From 3e225804904ee2fe0cefdbcfae938ab1676d9818 Mon Sep 17 00:00:00 2001 From: bputzeys Date: Mon, 18 Aug 2025 09:19:20 +0200 Subject: [PATCH] Remove dependency on torchvision by having only the requried class directly in the helical package --- README.md | 2 + .../models/hyena_dna/standalone_hyenadna.py | 2 +- helical/models/hyena_dna/stochastic_depth.py | 128 ++++++++++++++++++ pyproject.toml | 6 +- 4 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 helical/models/hyena_dna/stochastic_depth.py diff --git a/README.md b/README.md index 228e01b8..e2589a12 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,8 @@ A lot of our models have been published by talend authors developing these excit - [GenePT](https://github.com/yiqunchen/GenePT) - [Caduceus](https://github.com/kuleshov-group/caduceus) - [Evo2](https://github.com/ArcInstitute/evo2) +- [torch](https://github.com/pytorch/pytorch/blob/main/LICENSE) +- [torchvision](https://github.com/pytorch/vision/blob/release/0.21/LICENSE) ### Licenses diff --git a/helical/models/hyena_dna/standalone_hyenadna.py b/helical/models/hyena_dna/standalone_hyenadna.py index 85cce9d1..a20615ea 100644 --- a/helical/models/hyena_dna/standalone_hyenadna.py +++ b/helical/models/hyena_dna/standalone_hyenadna.py @@ -23,7 +23,7 @@ from typing import Optional from functools import partial from torch import Tensor -from torchvision.ops import StochasticDepth +from helical.models.hyena_dna.stochastic_depth import StochasticDepth from collections import namedtuple import numpy as np import os diff --git a/helical/models/hyena_dna/stochastic_depth.py b/helical/models/hyena_dna/stochastic_depth.py new file mode 100644 index 00000000..a811c1a5 --- /dev/null +++ b/helical/models/hyena_dna/stochastic_depth.py @@ -0,0 +1,128 @@ +""" + +BSD 3-Clause License + +Copyright (c) Soumith Chintala 2016, +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copied from torchvision to remove that dependency +https://github.com/pytorch/vision/blob/release/0.21/torchvision/utils.py +https://github.com/pytorch/vision/blob/release/0.21/torchvision/ops/stochastic_depth.py +""" + +import torch +import torch.fx +from torch import nn, Tensor +from typing import Any +from types import FunctionType + +def _log_api_usage_once(obj: Any) -> None: + + """ + Logs API usage(module and name) within an organization. + In a large ecosystem, it's often useful to track the PyTorch and + TorchVision APIs usage. This API provides the similar functionality to the + logging module in the Python stdlib. It can be used for debugging purpose + to log which methods are used and by default it is inactive, unless the user + manually subscribes a logger via the `SetAPIUsageLogger method `_. + Please note it is triggered only once for the same API call within a process. + It does not collect any data from open-source users since it is no-op by default. + For more information, please refer to + * PyTorch note: https://pytorch.org/docs/stable/notes/large_scale_deployments.html#api-usage-logging; + * Logging policy: https://github.com/pytorch/vision/issues/5052; + + Args: + obj (class instance or method): an object to extract info from. + """ + module = obj.__module__ + if not module.startswith("torchvision"): + module = f"torchvision.internal.{module}" + name = obj.__class__.__name__ + if isinstance(obj, FunctionType): + name = obj.__name__ + torch._C._log_api_usage_once(f"{module}.{name}") + +def stochastic_depth(input: Tensor, p: float, mode: str, training: bool = True) -> Tensor: + """ + Implements the Stochastic Depth from `"Deep Networks with Stochastic Depth" + `_ used for randomly dropping residual + branches of residual architectures. + + Args: + input (Tensor[N, ...]): The input tensor or arbitrary dimensions with the first one + being its batch i.e. a batch with ``N`` rows. + p (float): probability of the input to be zeroed. + mode (str): ``"batch"`` or ``"row"``. + ``"batch"`` randomly zeroes the entire input, ``"row"`` zeroes + randomly selected rows from the batch. + training: apply stochastic depth if is ``True``. Default: ``True`` + + Returns: + Tensor[N, ...]: The randomly zeroed tensor. + """ + if not torch.jit.is_scripting() and not torch.jit.is_tracing(): + _log_api_usage_once(stochastic_depth) + if p < 0.0 or p > 1.0: + raise ValueError(f"drop probability has to be between 0 and 1, but got {p}") + if mode not in ["batch", "row"]: + raise ValueError(f"mode has to be either 'batch' or 'row', but got {mode}") + if not training or p == 0.0: + return input + + survival_rate = 1.0 - p + if mode == "row": + size = [input.shape[0]] + [1] * (input.ndim - 1) + else: + size = [1] * input.ndim + noise = torch.empty(size, dtype=input.dtype, device=input.device) + noise = noise.bernoulli_(survival_rate) + if survival_rate > 0.0: + noise.div_(survival_rate) + return input * noise + + +torch.fx.wrap("stochastic_depth") + + +class StochasticDepth(nn.Module): + """ + See :func:`stochastic_depth`. + """ + + def __init__(self, p: float, mode: str) -> None: + super().__init__() + _log_api_usage_once(self) + self.p = p + self.mode = mode + + def forward(self, input: Tensor) -> Tensor: + return stochastic_depth(input, self.p, self.mode, self.training) + + def __repr__(self) -> str: + s = f"{self.__class__.__name__}(p={self.p}, mode={self.mode})" + return s \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 6b62095e..2fceb703 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "helical" -version = "1.4.1" +version = "1.4.2" authors = [ { name="Helical Team", email="support@helical-ai.com" }, ] @@ -28,15 +28,11 @@ dependencies = [ 'scipy==1.13.1', 'gitpython==3.1.43', 'torch==2.6.0', - 'torchvision==0.21.0', 'accelerate==1.4.0', 'transformers==4.49.0', 'loompy==3.0.7', 'scib==1.1.5', 'scikit-misc==0.3.1', - 'azure-identity==1.16.1', - 'azure-storage-blob==12.19.1', - 'azure-core==1.30.1', 'einops==0.8.0', 'omegaconf==2.3.0', 'hydra-core==1.3.2',