diff --git a/tests/unit/utilities/test_typed_module_list.py b/tests/unit/utilities/test_typed_module_list.py new file mode 100644 index 000000000..64a95f4f6 --- /dev/null +++ b/tests/unit/utilities/test_typed_module_list.py @@ -0,0 +1,105 @@ +"""Unit tests for TypedModuleList. + +TypedModuleList is a generic, type-preserving wrapper around nn.ModuleList. These +tests pin down its runtime behaviour: it must stay a drop-in nn.ModuleList (same +iteration, indexing, slicing, and submodule registration). The static typing +guarantee (iteration/indexing yield the element type) is exercised separately by +mypy over the rest of the package. +""" + +import pytest +import torch.nn as nn + +from transformer_lens.utilities import TypedModuleList +from transformer_lens.utilities.typed_module_list import ( + TypedModuleList as TypedModuleListDirect, +) + + +def _linears(n: int) -> list[nn.Linear]: + return [nn.Linear(3, 3) for _ in range(n)] + + +class TestTypedModuleList: + """Runtime behaviour of TypedModuleList.""" + + def test_exported_from_utilities_package(self): + """It is re-exported from transformer_lens.utilities.""" + assert TypedModuleList is TypedModuleListDirect + + def test_is_an_nn_module_list(self): + """It must remain a genuine nn.ModuleList subclass.""" + assert isinstance(TypedModuleList(_linears(2)), nn.ModuleList) + + @pytest.mark.parametrize("n", [0, 1, 3]) + def test_construction_and_len(self, n: int): + """len() matches the number of modules passed in (including empty).""" + assert len(TypedModuleList(_linears(n))) == n + + def test_construction_with_no_arguments(self): + """It can be constructed empty, like nn.ModuleList().""" + empty = TypedModuleList() + assert len(empty) == 0 + assert list(empty) == [] + + def test_iteration_preserves_order_and_identity(self): + """Iterating yields the exact module objects, in order.""" + layers = _linears(3) + assert [block for block in TypedModuleList(layers)] == layers + + def test_integer_indexing_returns_the_element(self): + """Integer indexing (including negative) returns the stored module.""" + layers = _linears(3) + tml = TypedModuleList(layers) + assert tml[0] is layers[0] + assert tml[-1] is layers[-1] + + def test_slicing_returns_a_typed_module_list(self): + """Slicing returns a TypedModuleList (not a bare nn.ModuleList) with the right modules.""" + layers = _linears(4) + sliced = TypedModuleList(layers)[1:3] + assert isinstance(sliced, TypedModuleList) + assert list(sliced) == layers[1:3] + + def test_modules_are_registered_as_submodules(self): + """Child modules are registered, so parameters() / named_children() work.""" + tml = TypedModuleList(_linears(2)) + # Two Linear(3, 3) layers => 2 * (weight + bias) == 4 parameter tensors. + assert len(list(tml.parameters())) == 4 + assert [name for name, _ in tml.named_children()] == ["0", "1"] + + def test_registers_correctly_when_nested_in_a_module(self): + """Used as a submodule, its parameters surface on the parent under the attribute name.""" + + class Net(nn.Module): + def __init__(self) -> None: + super().__init__() + self.blocks = TypedModuleList(_linears(2)) + + net = Net() + param_names = [name for name, _ in net.named_parameters()] + assert len(param_names) == 4 + assert all(name.startswith("blocks.") for name in param_names) + + def test_append_mutates_and_returns_self(self): + """append adds the module and returns the same list (for chaining), like nn.ModuleList.""" + tml: TypedModuleList[nn.Linear] = TypedModuleList() + layer = nn.Linear(3, 3) + returned = tml.append(layer) + assert returned is tml + assert isinstance(returned, TypedModuleList) + assert len(tml) == 1 + assert tml[0] is layer + + def test_setitem_replaces_element(self): + """__setitem__ replaces the module at an existing index and re-registers it.""" + layers = _linears(2) + tml = TypedModuleList(layers) + replacement = nn.Linear(3, 3) + tml[0] = replacement + assert tml[0] is replacement + assert tml[1] is layers[1] + assert len(tml) == 2 + # The replacement must be registered (old child gone, new child present). + assert replacement in tml.children() + assert layers[0] not in tml.children() diff --git a/transformer_lens/ActivationCache.py b/transformer_lens/ActivationCache.py index e820b64d3..7d392b6da 100644 --- a/transformer_lens/ActivationCache.py +++ b/transformer_lens/ActivationCache.py @@ -36,7 +36,6 @@ class first, including the examples, and then skimming the available methods. Yo from transformer_lens.utilities import Slice, SliceInput, warn_if_mps if TYPE_CHECKING: - from transformer_lens.components import TransformerBlock from transformer_lens.HookedTransformer import HookedTransformer @@ -748,8 +747,7 @@ def compute_head_results( ) # Element-wise multiplication of z and W_O (with shape [head_index, d_head, d_model]) - # nn.ModuleList[T][i] is typed Tensor|Module upstream; cast restores T. - block = cast("TransformerBlock", self.model.blocks[layer]) + block = self.model.blocks[layer] result = z * block.attn.W_O # Sum over d_head to get the contribution of each head to the residual stream @@ -906,8 +904,7 @@ def get_neuron_results( pos_slice = Slice(pos_slice) neuron_acts = self[("post", layer, "mlp")] - # ModuleList[T] indexing is typed `Tensor | Module` upstream; cast restores T. - block = cast("TransformerBlock", self.model.blocks[layer]) + block = self.model.blocks[layer] W_out = block.mlp.W_out if pos_slice is not None: # Note - order is important, as Slice.apply *may* collapse a dimension, so this ensures @@ -974,8 +971,7 @@ def _stack_neuron_results_apply_ln_projected( components: list = [] for l in range(layer): - # nn.ModuleList[T][i] is typed Tensor|Module upstream; cast restores T. - block = cast("TransformerBlock", self.model.blocks[l]) + block = self.model.blocks[l] W_out_l = block.mlp.W_out # [d_mlp, d_model] W_out_l_sliced = neuron_slice.apply(W_out_l, dim=0) W_proj_l = W_out_l_sliced @ project_2d # [d_mlp, n_outs] diff --git a/transformer_lens/HookedAudioEncoder.py b/transformer_lens/HookedAudioEncoder.py index 472425ec5..a1cbd47eb 100644 --- a/transformer_lens/HookedAudioEncoder.py +++ b/transformer_lens/HookedAudioEncoder.py @@ -7,11 +7,10 @@ from __future__ import annotations import logging -from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union, overload +from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union, cast, overload import numpy as np import torch -import torch.nn as nn from einops import repeat from jaxtyping import Float, Int from transformers import AutoFeatureExtractor, HubertModel, Wav2Vec2Model @@ -19,11 +18,11 @@ from transformer_lens import loading_from_pretrained as loading from transformer_lens.ActivationCache import ActivationCache -from transformer_lens.components import MLP, Attention, BertBlock +from transformer_lens.components import MLP, BertBlock from transformer_lens.config.hooked_transformer_config import HookedTransformerConfig from transformer_lens.FactoredMatrix import FactoredMatrix from transformer_lens.HookedRootModule import HookedRootModule -from transformer_lens.utilities import devices +from transformer_lens.utilities import TypedModuleList, devices T = TypeVar("T", bound="HookedAudioEncoder") @@ -41,6 +40,7 @@ class HookedAudioEncoder(HookedRootModule): processor: Any # AutoFeatureExtractor — HF auto class, not typed as callable in stubs hubert_model: Union[HubertModel, Wav2Vec2Model] + blocks: TypedModuleList[BertBlock] def __init__( self, @@ -60,7 +60,7 @@ def __init__( assert self.cfg.n_devices == 1, "Multiple devices not supported for HookedEncoder" - self.blocks = nn.ModuleList([BertBlock(self.cfg) for _ in range(self.cfg.n_layers)]) + self.blocks = TypedModuleList([BertBlock(self.cfg) for _ in range(self.cfg.n_layers)]) if move_to_device: if self.cfg.device is None: @@ -426,86 +426,62 @@ def from_pretrained( @property def W_K(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the key weights across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.W_K for block in self.blocks], dim=0) @property def W_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the query weights across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.W_Q for block in self.blocks], dim=0) @property def W_V(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the value weights across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.W_V for block in self.blocks], dim=0) @property def W_O(self) -> Float[torch.Tensor, "n_layers n_heads d_head d_model"]: """Stacks the attn output weights across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.W_O for block in self.blocks], dim=0) @property def W_in(self) -> Float[torch.Tensor, "n_layers d_model d_mlp"]: """Stacks the MLP input weights across all layers""" - for block in self.blocks: - assert isinstance(block.mlp, MLP) return torch.stack([block.mlp.W_in for block in self.blocks], dim=0) @property def W_out(self) -> Float[torch.Tensor, "n_layers d_mlp d_model"]: """Stacks the MLP output weights across all layers""" - for block in self.blocks: - assert isinstance(block.mlp, MLP) return torch.stack([block.mlp.W_out for block in self.blocks], dim=0) @property def b_K(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the key biases across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.b_K for block in self.blocks], dim=0) @property def b_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the query biases across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.b_Q for block in self.blocks], dim=0) @property def b_V(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the value biases across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.b_V for block in self.blocks], dim=0) @property def b_O(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stacks the attn output biases across all layers""" - for block in self.blocks: - assert isinstance(block.attn, Attention) return torch.stack([block.attn.b_O for block in self.blocks], dim=0) @property def b_in(self) -> Float[torch.Tensor, "n_layers d_mlp"]: """Stacks the MLP input biases across all layers""" - for block in self.blocks: - assert isinstance(block.mlp, MLP) - return torch.stack([block.mlp.b_in for block in self.blocks], dim=0) + return torch.stack([cast(MLP, block.mlp).b_in for block in self.blocks], dim=0) @property def b_out(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stacks the MLP output biases across all layers""" - for block in self.blocks: - assert isinstance(block.mlp, MLP) - return torch.stack([block.mlp.b_out for block in self.blocks], dim=0) + return torch.stack([cast(MLP, block.mlp).b_out for block in self.blocks], dim=0) @property def QK(self) -> FactoredMatrix: # [n_layers, n_heads, d_model, d_model] diff --git a/transformer_lens/HookedEncoder.py b/transformer_lens/HookedEncoder.py index 9dffc07e4..f751fafbf 100644 --- a/transformer_lens/HookedEncoder.py +++ b/transformer_lens/HookedEncoder.py @@ -11,7 +11,6 @@ from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union, cast, overload import torch -import torch.nn as nn from einops import repeat from jaxtyping import Float, Int from transformers.models.auto.tokenization_auto import AutoTokenizer @@ -33,7 +32,7 @@ from transformer_lens.FactoredMatrix import FactoredMatrix from transformer_lens.hook_points import HookPoint from transformer_lens.HookedRootModule import HookedRootModule -from transformer_lens.utilities import devices +from transformer_lens.utilities import TypedModuleList, devices T = TypeVar("T", bound="HookedEncoder") @@ -49,11 +48,7 @@ class HookedEncoder(HookedRootModule): - There is no preprocessing (e.g. LayerNorm folding) when loading a pretrained model """ - blocks: nn.ModuleList[BertBlock] # type: ignore[type-arg] - - def _get_blocks(self) -> list[BertBlock]: - """Helper to get blocks with proper typing.""" - return [cast(BertBlock, block) for block in self.blocks] + blocks: TypedModuleList[BertBlock] def __init__( self, @@ -91,7 +86,7 @@ def __init__( self.cfg.d_vocab_out = self.cfg.d_vocab self.embed = BertEmbed(self.cfg) - self.blocks = nn.ModuleList([BertBlock(self.cfg) for _ in range(self.cfg.n_layers)]) + self.blocks = TypedModuleList([BertBlock(self.cfg) for _ in range(self.cfg.n_layers)]) self.mlm_head = BertMLMHead(self.cfg) self.unembed = Unembed(self.cfg) self.nsp_head = BertNSPHead(self.cfg) @@ -471,69 +466,69 @@ def W_E_pos(self) -> Float[torch.Tensor, "d_vocab+n_ctx d_model"]: @property def W_K(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the key weights across all layers""" - return torch.stack([block.attn.W_K for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_K for block in self.blocks], dim=0) @property def W_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the query weights across all layers""" - return torch.stack([block.attn.W_Q for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_Q for block in self.blocks], dim=0) @property def W_V(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the value weights across all layers""" - return torch.stack([block.attn.W_V for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_V for block in self.blocks], dim=0) @property def W_O(self) -> Float[torch.Tensor, "n_layers n_heads d_head d_model"]: """Stacks the attn output weights across all layers""" - return torch.stack([block.attn.W_O for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_O for block in self.blocks], dim=0) @property def W_in(self) -> Float[torch.Tensor, "n_layers d_model d_mlp"]: """Stacks the MLP input weights across all layers""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).W_in for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).W_in for block in self.blocks], dim=0 ) @property def W_out(self) -> Float[torch.Tensor, "n_layers d_mlp d_model"]: """Stacks the MLP output weights across all layers""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).W_out for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).W_out for block in self.blocks], dim=0 ) @property def b_K(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the key biases across all layers""" - return torch.stack([block.attn.b_K for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_K for block in self.blocks], dim=0) @property def b_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the query biases across all layers""" - return torch.stack([block.attn.b_Q for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_Q for block in self.blocks], dim=0) @property def b_V(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the value biases across all layers""" - return torch.stack([block.attn.b_V for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_V for block in self.blocks], dim=0) @property def b_O(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stacks the attn output biases across all layers""" - return torch.stack([block.attn.b_O for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_O for block in self.blocks], dim=0) @property def b_in(self) -> Float[torch.Tensor, "n_layers d_mlp"]: """Stacks the MLP input biases across all layers""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).b_in for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).b_in for block in self.blocks], dim=0 ) @property def b_out(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stacks the MLP output biases across all layers""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).b_out for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).b_out for block in self.blocks], dim=0 ) @property diff --git a/transformer_lens/HookedEncoderDecoder.py b/transformer_lens/HookedEncoderDecoder.py index 7bc56df9e..df466aaa0 100644 --- a/transformer_lens/HookedEncoderDecoder.py +++ b/transformer_lens/HookedEncoderDecoder.py @@ -27,7 +27,6 @@ import tqdm from einops import repeat from jaxtyping import Float, Int -from torch import nn from transformers import AutoTokenizer, PreTrainedTokenizerBase from typing_extensions import Literal @@ -38,7 +37,7 @@ from transformer_lens.FactoredMatrix import FactoredMatrix from transformer_lens.hook_points import HookPoint from transformer_lens.HookedRootModule import HookedRootModule -from transformer_lens.utilities import sample_logits, warn_if_mps +from transformer_lens.utilities import TypedModuleList, sample_logits, warn_if_mps from transformer_lens.utilities.multi_gpu import get_device_for_block_index T = TypeVar("T", bound="HookedEncoderDecoder") @@ -57,6 +56,8 @@ class HookedEncoderDecoder(HookedRootModule): """ tokenizer: Optional[PreTrainedTokenizerBase] + encoder: TypedModuleList[T5Block] + decoder: TypedModuleList[T5Block] def __init__( self, @@ -97,14 +98,14 @@ def __init__( self.cfg.d_vocab_out = self.cfg.d_vocab self.embed = Embed(self.cfg) - self.encoder = nn.ModuleList( + self.encoder = TypedModuleList( [ T5Block(self.cfg, num_layer, is_decoder=False) for num_layer in range(self.cfg.n_layers) ] ) self.encoder_final_ln = RMSNorm(self.cfg) - self.decoder = nn.ModuleList( + self.decoder = TypedModuleList( [ T5Block(self.cfg, num_layer, is_decoder=True) for num_layer in range(self.cfg.n_layers) @@ -258,9 +259,9 @@ def forward( query_len = key_len = tokens.shape[1] - encoder_positional_bias = cast( - T5Block, self.encoder[0] - ).attn.compute_relative_attention_bias(query_len, key_len, device=self.cfg.device) + encoder_positional_bias = self.encoder[0].attn.compute_relative_attention_bias( + query_len, key_len, device=self.cfg.device + ) for encoder_block in self.encoder: resid = encoder_block( @@ -275,9 +276,7 @@ def forward( raise ValueError("decoder_input cannot be None when input is not a string") decoder_resid = self.embed(decoder_input) decoder_query_len = decoder_key_len = decoder_input.shape[1] - decoder_positional_bias = cast( - T5Block, self.decoder[0] - ).attn.compute_relative_attention_bias( + decoder_positional_bias = self.decoder[0].attn.compute_relative_attention_bias( decoder_query_len, decoder_key_len, device=self.cfg.device ) @@ -638,7 +637,7 @@ def W_pos(self) -> None: def W_K(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the key weights across all layers""" return torch.stack( - [cast(T5Block, block).attn.W_K for block in chain(self.encoder, self.decoder)], + [block.attn.W_K for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -646,7 +645,7 @@ def W_K(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: def W_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the query weights across all layers""" return torch.stack( - [cast(T5Block, block).attn.W_Q for block in chain(self.encoder, self.decoder)], + [block.attn.W_Q for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -654,7 +653,7 @@ def W_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: def W_V(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stacks the value weights across all layers""" return torch.stack( - [cast(T5Block, block).attn.W_V for block in chain(self.encoder, self.decoder)], + [block.attn.W_V for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -662,7 +661,7 @@ def W_V(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: def W_O(self) -> Float[torch.Tensor, "n_layers n_heads d_head d_model"]: """Stacks the attn output weights across all layers""" return torch.stack( - [cast(T5Block, block).attn.W_O for block in chain(self.encoder, self.decoder)], + [block.attn.W_O for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -671,7 +670,7 @@ def W_in(self) -> Float[torch.Tensor, "n_layers d_model d_mlp"]: """Stacks the MLP input weights across all layers""" weights: List[torch.Tensor] = [] for block in chain(self.encoder, self.decoder): - mlp = cast(T5Block, block).mlp + mlp = block.mlp if isinstance(mlp, (MLP, GatedMLP)): weights.append(mlp.W_in) else: @@ -685,7 +684,7 @@ def W_out(self) -> Float[torch.Tensor, "n_layers d_mlp d_model"]: """Stacks the MLP output weights across all layers""" weights: List[torch.Tensor] = [] for block in chain(self.encoder, self.decoder): - mlp = cast(T5Block, block).mlp + mlp = block.mlp if isinstance(mlp, (MLP, GatedMLP)): weights.append(mlp.W_out) else: @@ -698,7 +697,7 @@ def W_out(self) -> Float[torch.Tensor, "n_layers d_mlp d_model"]: def b_K(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the key biases across all layers""" return torch.stack( - [cast(T5Block, block).attn.b_K for block in chain(self.encoder, self.decoder)], + [block.attn.b_K for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -706,7 +705,7 @@ def b_K(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: def b_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the query biases across all layers""" return torch.stack( - [cast(T5Block, block).attn.b_Q for block in chain(self.encoder, self.decoder)], + [block.attn.b_Q for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -714,7 +713,7 @@ def b_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: def b_V(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stacks the value biases across all layers""" return torch.stack( - [cast(T5Block, block).attn.b_V for block in chain(self.encoder, self.decoder)], + [block.attn.b_V for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -722,7 +721,7 @@ def b_V(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: def b_O(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stacks the attn output biases across all layers""" return torch.stack( - [cast(T5Block, block).attn.b_O for block in chain(self.encoder, self.decoder)], + [block.attn.b_O for block in chain(self.encoder, self.decoder)], dim=0, ) @@ -731,7 +730,7 @@ def b_in(self) -> Float[torch.Tensor, "n_layers d_mlp"]: """Stacks the MLP input biases across all layers""" biases: List[torch.Tensor] = [] for block in chain(self.encoder, self.decoder): - mlp = cast(T5Block, block).mlp + mlp = block.mlp if isinstance(mlp, (MLP, GatedMLP)): biases.append(mlp.b_in) else: @@ -745,7 +744,7 @@ def b_out(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stacks the MLP output biases across all layers""" biases: List[torch.Tensor] = [] for block in chain(self.encoder, self.decoder): - mlp = cast(T5Block, block).mlp + mlp = block.mlp if isinstance(mlp, (MLP, GatedMLP)): biases.append(mlp.b_out) else: diff --git a/transformer_lens/HookedTransformer.py b/transformer_lens/HookedTransformer.py index 8370bbf8a..7e9e780b1 100644 --- a/transformer_lens/HookedTransformer.py +++ b/transformer_lens/HookedTransformer.py @@ -66,6 +66,7 @@ from transformer_lens.loading_from_pretrained import NON_HF_HOSTED_MODEL_NAMES from transformer_lens.utilities import ( USE_DEFAULT_VALUE, + TypedModuleList, get_best_available_device, get_device_for_block_index, init_kaiming_normal_, @@ -138,7 +139,7 @@ class HookedTransformer(HookedRootModule): ln_final: nn.Module tokenizer: Optional[PreTrainedTokenizerBase] - blocks: nn.ModuleList[TransformerBlock] # type: ignore[type-arg] + blocks: TypedModuleList[TransformerBlock] def __init__( self, @@ -224,7 +225,7 @@ def __init__( if self.cfg.use_hook_tokens: self.hook_tokens = HookPoint() # [batch, pos] - self.blocks = nn.ModuleList( + self.blocks = TypedModuleList( [TransformerBlock(self.cfg, block_index) for block_index in range(self.cfg.n_layers)] ) @@ -640,7 +641,7 @@ def forward( # Eg: start_at_layer==None + stop_at_layer==0 means to only run the embed. # Eg: start_at_layer==3 + stop_at_layer==-1 means to run from layer 3 until the end of the PENULTIMATE layer blocks_and_idxs = list(zip(range(self.cfg.n_layers), self.blocks)) - for i, block in blocks_and_idxs[start_at_layer:stop_at_layer]: # type: ignore + for i, block in blocks_and_idxs[start_at_layer:stop_at_layer]: # Note that each block includes skip connections, so we don't need # residual + block(residual) # If we're using multiple GPUs, we need to send the residual and shortformer_pos_embed to the correct GPU @@ -2550,35 +2551,31 @@ def W_E_pos(self) -> Float[torch.Tensor, "d_vocab+n_ctx d_model"]: # we want to do analysis on weights across all layers. If GPU memory is a bottleneck, don't use # these properties! - def _get_blocks(self) -> list[TransformerBlock]: - """Helper to get blocks with proper typing.""" - return [cast(TransformerBlock, block) for block in self.blocks] - @property def W_K(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stack the key weights across all layers.""" - return torch.stack([block.attn.W_K for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_K for block in self.blocks], dim=0) @property def W_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stack the query weights across all layers.""" - return torch.stack([block.attn.W_Q for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_Q for block in self.blocks], dim=0) @property def W_V(self) -> Float[torch.Tensor, "n_layers n_heads d_model d_head"]: """Stack the value weights across all layers.""" - return torch.stack([block.attn.W_V for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_V for block in self.blocks], dim=0) @property def W_O(self) -> Float[torch.Tensor, "n_layers n_heads d_head d_model"]: """Stack the attn output weights across all layers.""" - return torch.stack([block.attn.W_O for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.W_O for block in self.blocks], dim=0) @property def W_in(self) -> Float[torch.Tensor, "n_layers d_model d_mlp"]: """Stack the MLP input weights across all layers.""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).W_in for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).W_in for block in self.blocks], dim=0 ) @property @@ -2588,9 +2585,7 @@ def W_gate(self) -> Union[Float[torch.Tensor, "n_layers d_model d_mlp"], None]: Only works for models with gated MLPs. """ if self.cfg.gated_mlp: - return torch.stack( - [cast(GatedMLP, block.mlp).W_gate for block in self._get_blocks()], dim=0 - ) + return torch.stack([cast(GatedMLP, block.mlp).W_gate for block in self.blocks], dim=0) else: return None @@ -2598,41 +2593,41 @@ def W_gate(self) -> Union[Float[torch.Tensor, "n_layers d_model d_mlp"], None]: def W_out(self) -> Float[torch.Tensor, "n_layers d_mlp d_model"]: """Stack the MLP output weights across all layers.""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).W_out for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).W_out for block in self.blocks], dim=0 ) @property def b_K(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stack the key biases across all layers.""" - return torch.stack([block.attn.b_K for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_K for block in self.blocks], dim=0) @property def b_Q(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stack the query biases across all layers.""" - return torch.stack([block.attn.b_Q for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_Q for block in self.blocks], dim=0) @property def b_V(self) -> Float[torch.Tensor, "n_layers n_heads d_head"]: """Stack the value biases across all layers.""" - return torch.stack([block.attn.b_V for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_V for block in self.blocks], dim=0) @property def b_O(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stack the attn output biases across all layers.""" - return torch.stack([block.attn.b_O for block in self._get_blocks()], dim=0) + return torch.stack([block.attn.b_O for block in self.blocks], dim=0) @property def b_in(self) -> Float[torch.Tensor, "n_layers d_mlp"]: """Stack the MLP input biases across all layers.""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).b_in for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).b_in for block in self.blocks], dim=0 ) @property def b_out(self) -> Float[torch.Tensor, "n_layers d_model"]: """Stack the MLP output biases across all layers.""" return torch.stack( - [cast(Union[MLP, GatedMLP], block.mlp).b_out for block in self._get_blocks()], dim=0 + [cast(Union[MLP, GatedMLP], block.mlp).b_out for block in self.blocks], dim=0 ) @property @@ -2668,13 +2663,13 @@ def accumulated_bias( accumulated_bias = torch.zeros(self.cfg.d_model, device=self.cfg.device) for i in range(layer): - block = cast(TransformerBlock, self.blocks[i]) + block = self.blocks[i] accumulated_bias += cast(torch.Tensor, block.attn.b_O) if include_mlp_biases: accumulated_bias += cast(torch.Tensor, block.mlp.b_out) if mlp_input: assert layer < self.cfg.n_layers, "Cannot include attn_bias from beyond the final layer" - block = cast(TransformerBlock, self.blocks[layer]) + block = self.blocks[layer] accumulated_bias += cast(torch.Tensor, block.attn.b_O) return accumulated_bias diff --git a/transformer_lens/benchmarks/weight_processing.py b/transformer_lens/benchmarks/weight_processing.py index 62e561b25..9ffe1c08f 100644 --- a/transformer_lens/benchmarks/weight_processing.py +++ b/transformer_lens/benchmarks/weight_processing.py @@ -77,11 +77,11 @@ def benchmark_weight_processing( ) _mlp_idx, mlp_block = mlp_blocks[0] bridge_w_out = mlp_block.mlp.W_out - reference_w_out = reference_model.blocks[_mlp_idx].mlp.W_out # type: ignore[union-attr] + reference_w_out = reference_model.blocks[_mlp_idx].mlp.W_out bridge_mean = torch.mean(torch.abs(torch.mean(bridge_w_out, dim=-1, keepdim=True))) reference_mean = torch.mean( - torch.abs(torch.mean(reference_w_out, dim=-1, keepdim=True)) # type: ignore[arg-type] + torch.abs(torch.mean(reference_w_out, dim=-1, keepdim=True)) ) if bridge_mean.item() > 1e-3: @@ -161,7 +161,7 @@ def benchmark_weight_sharing( # Verify weights are identical before modification bridge_W_V = torch.clone(cast(torch.Tensor, bridge_attn_block.attn.W_V)) reference_W_V = torch.clone( - cast(torch.Tensor, reference_model.blocks[bridge_attn_idx].attn.W_V) # type: ignore[union-attr] + cast(torch.Tensor, reference_model.blocks[bridge_attn_idx].attn.W_V) ) # Check if models have GQA (different head counts for K/V vs Q) @@ -206,7 +206,7 @@ def benchmark_weight_sharing( # Modify weights in both models with torch.no_grad(): bridge_attn_block.attn.W_V[0, :, :] = 0 # type: ignore[union-attr,operator] - reference_model.blocks[bridge_attn_idx].attn.W_V[0, :, :] = 0 # type: ignore[union-attr,operator] + reference_model.blocks[bridge_attn_idx].attn.W_V[0, :, :] = 0 # Test modified losses bridge_modified = bridge(test_text, return_type="loss") @@ -218,7 +218,7 @@ def benchmark_weight_sharing( # Restore weights with torch.no_grad(): bridge_attn_block.attn.W_V.copy_(bridge_W_V) # type: ignore[union-attr,operator,arg-type] - reference_model.blocks[bridge_attn_idx].attn.W_V.copy_(reference_W_V) # type: ignore[union-attr,operator,arg-type] + reference_model.blocks[bridge_attn_idx].attn.W_V.copy_(reference_W_V) diff = abs(bridge_change - reference_change) if diff < atol: diff --git a/transformer_lens/model_bridge/sources/native/model.py b/transformer_lens/model_bridge/sources/native/model.py index 2035ade42..1a6fa2e8b 100644 --- a/transformer_lens/model_bridge/sources/native/model.py +++ b/transformer_lens/model_bridge/sources/native/model.py @@ -16,6 +16,7 @@ import torch.nn.functional as F from transformer_lens.config import TransformerBridgeConfig +from transformer_lens.utilities import TypedModuleList # gelu_new = the tanh-approximation HF GPT-2 / HT use; F.gelu(approximate="tanh") # is the exact same formula. @@ -404,7 +405,7 @@ def __init__(self, cfg: TransformerBridgeConfig): f"NativeModel supports 'standard' and 'rotary'." ) - self.layers = nn.ModuleList( + self.layers = TypedModuleList( [NativeBlock(cfg, rotary=self.rotary) for _ in range(cfg.n_layers)] ) # final_rms forces RMS on the final norm regardless of block-norm choice diff --git a/transformer_lens/utilities/__init__.py b/transformer_lens/utilities/__init__.py index 3da03052c..e242e951c 100644 --- a/transformer_lens/utilities/__init__.py +++ b/transformer_lens/utilities/__init__.py @@ -80,3 +80,4 @@ get_tokens_with_bos_removed, tokenize_and_concatenate, ) +from .typed_module_list import TypedModuleList diff --git a/transformer_lens/utilities/bridge_components.py b/transformer_lens/utilities/bridge_components.py index 317289b52..8c0418fb6 100644 --- a/transformer_lens/utilities/bridge_components.py +++ b/transformer_lens/utilities/bridge_components.py @@ -1,6 +1,6 @@ """Utilities for traversing and applying functions to every component in a TransformerBridge model.""" -from typing import Any, Callable +from typing import Any, Callable, cast import torch.nn as nn @@ -73,8 +73,13 @@ def collect_components_of_block_bridge( # Make sure the remote component is a ModuleList if isinstance(remote_module_list, nn.ModuleList): for block in remote_module_list: - components[block.name] = block - components = collect_all_submodules_of_component(model, block, components, block.name) + block_component = cast(GeneralizedComponent, block) + block_name = block_component.name + assert block_name is not None, "Block bridge component must have a name" + components[block_name] = block_component + components = collect_all_submodules_of_component( + model, block_component, components, block_name + ) return components diff --git a/transformer_lens/utilities/typed_module_list.py b/transformer_lens/utilities/typed_module_list.py new file mode 100644 index 000000000..f5e0d4b0c --- /dev/null +++ b/transformer_lens/utilities/typed_module_list.py @@ -0,0 +1,27 @@ +"""Typed Module List. + +A thin generic wrapper around :class:`torch.nn.ModuleList`, inspired by +https://github.com/pytorch/pytorch/issues/80821#issuecomment-3188314929. + +``nn.ModuleList`` is not generic, so iterating or indexing it yields a bare +``nn.Module`` (or ``Any`` on torch < 2.8). ``TypedModuleList[T]`` preserves the +element type ``T`` through ` iteration and other methods while remaining a drop-in +``nn.ModuleList`` at runtime (children are still registered as submodules). + +The element-type-preserving signatures live in a companion stub +``typed_module_list.pyi`` for technical reasons related to jaxtyping/beartype. +""" + +from typing import Generic, TypeVar + +from torch import nn + +T = TypeVar("T", bound=nn.Module) + + +class TypedModuleList(nn.ModuleList, Generic[T]): + """An ``nn.ModuleList`` that remembers the type ``T`` of the modules it holds. + + Runtime behaviour is exactly ``nn.ModuleList``'s; the typed API is declared in + ``typed_module_list.pyi``. + """ diff --git a/transformer_lens/utilities/typed_module_list.pyi b/transformer_lens/utilities/typed_module_list.pyi new file mode 100644 index 000000000..dc997041a --- /dev/null +++ b/transformer_lens/utilities/typed_module_list.pyi @@ -0,0 +1,21 @@ +"""Typed Module List type annotations + +The element-type-preserving signatures live here rather than in +``typed_module_list.py`` for technical reasons related to jaxtyping/beartype. +""" + +from typing import Generic, Iterable, Iterator, Optional, TypeVar, overload + +from torch import nn + +T = TypeVar("T", bound=nn.Module) + +class TypedModuleList(nn.ModuleList, Generic[T]): + def __init__(self, modules: Optional[Iterable[T]] = ...) -> None: ... + def __iter__(self) -> Iterator[T]: ... + @overload + def __getitem__(self, idx: slice) -> TypedModuleList[T]: ... + @overload + def __getitem__(self, idx: int) -> T: ... + def append(self, module: T) -> TypedModuleList[T]: ... # type: ignore[override] + def __setitem__(self, idx: int, module: T) -> None: ... # type: ignore[override] diff --git a/uv.lock b/uv.lock index 3f03b3e29..f4b1b0809 100644 --- a/uv.lock +++ b/uv.lock @@ -1047,6 +1047,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/2a/1b016902351a523aa2bd446b50a5bc1175d7a7d1cf90fe2ef904f9b84ebc/cryptography-46.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:258514877e15963bd43b558917bc9f54cf7cf866c38aa576ebf47a77ddbc43a4", size = 3412829, upload-time = "2026-04-08T01:57:48.874Z" }, ] +[[package]] +name = "cuda-bindings" +version = "12.9.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-pathfinder", marker = "sys_platform == 'linux'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/d8/b546104b8da3f562c1ff8ab36d130c8fe1dd6a045ced80b4f6ad74f7d4e1/cuda_bindings-12.9.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d3c842c2a4303b2a580fe955018e31aea30278be19795ae05226235268032e5", size = 12148218, upload-time = "2025-10-21T14:51:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/45/e7/b47792cc2d01c7e1d37c32402182524774dadd2d26339bd224e0e913832e/cuda_bindings-12.9.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c912a3d9e6b6651853eed8eed96d6800d69c08e94052c292fec3f282c5a817c9", size = 12210593, upload-time = "2025-10-21T14:51:36.574Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c1/dabe88f52c3e3760d861401bb994df08f672ec893b8f7592dc91626adcf3/cuda_bindings-12.9.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fda147a344e8eaeca0c6ff113d2851ffca8f7dfc0a6c932374ee5c47caa649c8", size = 12151019, upload-time = "2025-10-21T14:51:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/63/56/e465c31dc9111be3441a9ba7df1941fe98f4aa6e71e8788a3fb4534ce24d/cuda_bindings-12.9.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:32bdc5a76906be4c61eb98f546a6786c5773a881f3b166486449b5d141e4a39f", size = 11906628, upload-time = "2025-10-21T14:51:49.905Z" }, + { url = "https://files.pythonhosted.org/packages/a3/84/1e6be415e37478070aeeee5884c2022713c1ecc735e6d82d744de0252eee/cuda_bindings-12.9.4-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56e0043c457a99ac473ddc926fe0dc4046694d99caef633e92601ab52cbe17eb", size = 11925991, upload-time = "2025-10-21T14:51:56.535Z" }, + { url = "https://files.pythonhosted.org/packages/d1/af/6dfd8f2ed90b1d4719bc053ff8940e494640fe4212dc3dd72f383e4992da/cuda_bindings-12.9.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8b72ee72a9cc1b531db31eebaaee5c69a8ec3500e32c6933f2d3b15297b53686", size = 11922703, upload-time = "2025-10-21T14:52:03.585Z" }, + { url = "https://files.pythonhosted.org/packages/6c/19/90ac264acc00f6df8a49378eedec9fd2db3061bf9263bf9f39fd3d8377c3/cuda_bindings-12.9.4-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d80bffc357df9988dca279734bc9674c3934a654cab10cadeed27ce17d8635ee", size = 11924658, upload-time = "2025-10-21T14:52:10.411Z" }, +] + +[[package]] +name = "cuda-pathfinder" +version = "1.5.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/c8/26f2e4aae92f11522a96043892ba39a90eac610d5242523aa863212bc1c7/cuda_pathfinder-1.5.5-py3-none-any.whl", hash = "sha256:0228c023f95d1480f143ef5c8922d27a2ab052087a942e81dc289c9eb8f91689", size = 51671, upload-time = "2026-05-27T01:21:25.413Z" }, +] + [[package]] name = "cycler" version = "0.12.1" @@ -3661,81 +3686,77 @@ wheels = [ [[package]] name = "nvidia-cublas-cu12" -version = "12.6.4.1" +version = "12.8.4.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/af/eb/ff4b8c503fa1f1796679dce648854d58751982426e4e4b37d6fce49d259c/nvidia_cublas_cu12-12.6.4.1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08ed2686e9875d01b58e3cb379c6896df8e76c75e0d4a7f7dace3d7b6d9ef8eb", size = 393138322, upload-time = "2024-11-20T17:40:25.65Z" }, + { url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921, upload-time = "2025-03-07T01:44:31.254Z" }, ] [[package]] name = "nvidia-cuda-cupti-cu12" -version = "12.6.80" +version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/49/60/7b6497946d74bcf1de852a21824d63baad12cd417db4195fc1bfe59db953/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6768bad6cab4f19e8292125e5f1ac8aa7d1718704012a0e3272a6f61c4bce132", size = 8917980, upload-time = "2024-11-20T17:36:04.019Z" }, - { url = "https://files.pythonhosted.org/packages/a5/24/120ee57b218d9952c379d1e026c4479c9ece9997a4fb46303611ee48f038/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a3eff6cdfcc6a4c35db968a06fcadb061cbc7d6dde548609a941ff8701b98b73", size = 8917972, upload-time = "2024-10-01T16:58:06.036Z" }, + { url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621, upload-time = "2025-03-07T01:40:21.213Z" }, ] [[package]] name = "nvidia-cuda-nvrtc-cu12" -version = "12.6.77" +version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/2e/46030320b5a80661e88039f59060d1790298b4718944a65a7f2aeda3d9e9/nvidia_cuda_nvrtc_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:35b0cc6ee3a9636d5409133e79273ce1f3fd087abb0532d2d2e8fff1fe9efc53", size = 23650380, upload-time = "2024-10-01T17:00:14.643Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029, upload-time = "2025-03-07T01:42:13.562Z" }, ] [[package]] name = "nvidia-cuda-runtime-cu12" -version = "12.6.77" +version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/23/e717c5ac26d26cf39a27fbc076240fad2e3b817e5889d671b67f4f9f49c5/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ba3b56a4f896141e25e19ab287cd71e52a6a0f4b29d0d31609f60e3b4d5219b7", size = 897690, upload-time = "2024-11-20T17:35:30.697Z" }, - { url = "https://files.pythonhosted.org/packages/f0/62/65c05e161eeddbafeca24dc461f47de550d9fa8a7e04eb213e32b55cfd99/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a84d15d5e1da416dd4774cb42edf5e954a3e60cc945698dc1d5be02321c44dc8", size = 897678, upload-time = "2024-10-01T16:57:33.821Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765, upload-time = "2025-03-07T01:40:01.615Z" }, ] [[package]] name = "nvidia-cudnn-cu12" -version = "9.5.1.17" +version = "9.10.2.21" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/78/4535c9c7f859a64781e43c969a3a7e84c54634e319a996d43ef32ce46f83/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:30ac3869f6db17d170e0e556dd6cc5eee02647abc31ca856634d5a40f82c15b2", size = 570988386, upload-time = "2024-10-25T19:54:26.39Z" }, + { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467, upload-time = "2025-06-06T21:54:08.597Z" }, ] [[package]] name = "nvidia-cufft-cu12" -version = "11.3.0.4" +version = "11.3.3.83" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/16/73727675941ab8e6ffd86ca3a4b7b47065edcca7a997920b831f8147c99d/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ccba62eb9cef5559abd5e0d54ceed2d9934030f51163df018532142a8ec533e5", size = 200221632, upload-time = "2024-11-20T17:41:32.357Z" }, - { url = "https://files.pythonhosted.org/packages/60/de/99ec247a07ea40c969d904fc14f3a356b3e2a704121675b75c366b694ee1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:768160ac89f6f7b459bee747e8d175dbf53619cfe74b2a5636264163138013ca", size = 200221622, upload-time = "2024-10-01T17:03:58.79Z" }, + { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695, upload-time = "2025-03-07T01:45:27.821Z" }, ] [[package]] name = "nvidia-cufile-cu12" -version = "1.11.1.6" +version = "1.13.1.3" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/66/cc9876340ac68ae71b15c743ddb13f8b30d5244af344ec8322b449e35426/nvidia_cufile_cu12-1.11.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc23469d1c7e52ce6c1d55253273d32c565dd22068647f3aa59b3c6b005bf159", size = 1142103, upload-time = "2024-11-20T17:42:11.83Z" }, + { url = "https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834, upload-time = "2025-03-07T01:45:50.723Z" }, ] [[package]] name = "nvidia-curand-cu12" -version = "10.3.7.77" +version = "10.3.9.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/1b/44a01c4e70933637c93e6e1a8063d1e998b50213a6b65ac5a9169c47e98e/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a42cd1344297f70b9e39a1e4f467a4e1c10f1da54ff7a85c12197f6c652c8bdf", size = 56279010, upload-time = "2024-11-20T17:42:50.958Z" }, - { url = "https://files.pythonhosted.org/packages/4a/aa/2c7ff0b5ee02eaef890c0ce7d4f74bc30901871c5e45dee1ae6d0083cd80/nvidia_curand_cu12-10.3.7.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:99f1a32f1ac2bd134897fc7a203f779303261268a65762a623bf30cc9fe79117", size = 56279000, upload-time = "2024-10-01T17:04:45.274Z" }, + { url = "https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976, upload-time = "2025-03-07T01:46:23.323Z" }, ] [[package]] name = "nvidia-cusolver-cu12" -version = "11.7.1.2" +version = "11.7.3.90" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, @@ -3743,53 +3764,58 @@ dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/6e/c2cf12c9ff8b872e92b4a5740701e51ff17689c4d726fca91875b07f655d/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e9e49843a7707e42022babb9bcfa33c29857a93b88020c4e4434656a655b698c", size = 158229790, upload-time = "2024-11-20T17:43:43.211Z" }, - { url = "https://files.pythonhosted.org/packages/9f/81/baba53585da791d043c10084cf9553e074548408e04ae884cfe9193bd484/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf28f17f64107a0c4d7802be5ff5537b2130bfc112f25d5a30df227058ca0e6", size = 158229780, upload-time = "2024-10-01T17:05:39.875Z" }, + { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905, upload-time = "2025-03-07T01:47:16.273Z" }, ] [[package]] name = "nvidia-cusparse-cu12" -version = "12.5.4.2" +version = "12.5.8.93" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/06/1e/b8b7c2f4099a37b96af5c9bb158632ea9e5d9d27d7391d7eb8fc45236674/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7556d9eca156e18184b94947ade0fba5bb47d69cec46bf8660fd2c71a4b48b73", size = 216561367, upload-time = "2024-11-20T17:44:54.824Z" }, - { url = "https://files.pythonhosted.org/packages/43/ac/64c4316ba163e8217a99680c7605f779accffc6a4bcd0c778c12948d3707/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:23749a6571191a215cb74d1cdbff4a86e7b19f1200c071b3fcf844a5bea23a2f", size = 216561357, upload-time = "2024-10-01T17:06:29.861Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466, upload-time = "2025-03-07T01:48:13.779Z" }, ] [[package]] name = "nvidia-cusparselt-cu12" -version = "0.6.3" +version = "0.7.1" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/9a/72ef35b399b0e183bc2e8f6f558036922d453c4d8237dab26c666a04244b/nvidia_cusparselt_cu12-0.6.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e5c8a26c36445dd2e6812f1177978a24e2d37cacce7e090f297a688d1ec44f46", size = 156785796, upload-time = "2024-10-15T21:29:17.709Z" }, + { url = "https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691, upload-time = "2025-02-26T00:15:44.104Z" }, ] [[package]] name = "nvidia-nccl-cu12" -version = "2.26.2" +version = "2.27.5" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/67/ca/f42388aed0fddd64ade7493dbba36e1f534d4e6fdbdd355c6a90030ae028/nvidia_nccl_cu12-2.26.2-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:694cf3879a206553cc9d7dbda76b13efaf610fdb70a50cba303de1b0d1530ac6", size = 201319755, upload-time = "2025-03-13T00:29:55.296Z" }, + { url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229, upload-time = "2025-06-26T04:11:28.385Z" }, ] [[package]] name = "nvidia-nvjitlink-cu12" -version = "12.6.85" +version = "12.8.93" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/d7/c5383e47c7e9bf1c99d5bd2a8c935af2b6d705ad831a7ec5c97db4d82f4f/nvidia_nvjitlink_cu12-12.6.85-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:eedc36df9e88b682efe4309aa16b5b4e78c2407eac59e8c10a6a47535164369a", size = 19744971, upload-time = "2024-11-20T17:46:53.366Z" }, + { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836, upload-time = "2025-03-07T01:49:55.661Z" }, +] + +[[package]] +name = "nvidia-nvshmem-cu12" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/09/6ea3ea725f82e1e76684f0708bbedd871fc96da89945adeba65c3835a64c/nvidia_nvshmem_cu12-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:042f2500f24c021db8a06c5eec2539027d57460e1c1a762055a6554f72c369bd", size = 139103095, upload-time = "2025-09-06T00:32:31.266Z" }, ] [[package]] name = "nvidia-nvtx-cu12" -version = "12.6.77" +version = "12.8.90" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/9a/fff8376f8e3d084cd1530e1ef7b879bb7d6d265620c95c1b322725c694f4/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b90bed3df379fa79afbd21be8e04a0314336b8ae16768b58f2d34cb1d04cd7d2", size = 89276, upload-time = "2024-11-20T17:38:27.621Z" }, - { url = "https://files.pythonhosted.org/packages/9e/4e/0d0c945463719429b7bd21dece907ad0bde437a2ff12b9b12fee94722ab0/nvidia_nvtx_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6574241a3ec5fdc9334353ab8c479fe75841dbe8f4532a8fc97ce63503330ba1", size = 89265, upload-time = "2024-10-01T17:00:38.172Z" }, + { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954, upload-time = "2025-03-07T01:42:44.131Z" }, ] [[package]] @@ -6316,9 +6342,10 @@ wheels = [ [[package]] name = "torch" -version = "2.7.1" +version = "2.10.0" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "cuda-bindings", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "filelock" }, { name = "fsspec" }, { name = "jinja2" }, @@ -6337,6 +6364,7 @@ dependencies = [ { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, { name = "setuptools", marker = "python_full_version >= '3.12'" }, { name = "sympy" }, @@ -6344,31 +6372,50 @@ dependencies = [ { name = "typing-extensions" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/27/2e06cb52adf89fe6e020963529d17ed51532fc73c1e6d1b18420ef03338c/torch-2.7.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a103b5d782af5bd119b81dbcc7ffc6fa09904c423ff8db397a1e6ea8fd71508f", size = 99089441, upload-time = "2025-06-04T17:38:48.268Z" }, - { url = "https://files.pythonhosted.org/packages/0a/7c/0a5b3aee977596459ec45be2220370fde8e017f651fecc40522fd478cb1e/torch-2.7.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:fe955951bdf32d182ee8ead6c3186ad54781492bf03d547d31771a01b3d6fb7d", size = 821154516, upload-time = "2025-06-04T17:36:28.556Z" }, - { url = "https://files.pythonhosted.org/packages/f9/91/3d709cfc5e15995fb3fe7a6b564ce42280d3a55676dad672205e94f34ac9/torch-2.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:885453d6fba67d9991132143bf7fa06b79b24352f4506fd4d10b309f53454162", size = 216093147, upload-time = "2025-06-04T17:39:38.132Z" }, - { url = "https://files.pythonhosted.org/packages/92/f6/5da3918414e07da9866ecb9330fe6ffdebe15cb9a4c5ada7d4b6e0a6654d/torch-2.7.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:d72acfdb86cee2a32c0ce0101606f3758f0d8bb5f8f31e7920dc2809e963aa7c", size = 68630914, upload-time = "2025-06-04T17:39:31.162Z" }, - { url = "https://files.pythonhosted.org/packages/11/56/2eae3494e3d375533034a8e8cf0ba163363e996d85f0629441fa9d9843fe/torch-2.7.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:236f501f2e383f1cb861337bdf057712182f910f10aeaf509065d54d339e49b2", size = 99093039, upload-time = "2025-06-04T17:39:06.963Z" }, - { url = "https://files.pythonhosted.org/packages/e5/94/34b80bd172d0072c9979708ccd279c2da2f55c3ef318eceec276ab9544a4/torch-2.7.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:06eea61f859436622e78dd0cdd51dbc8f8c6d76917a9cf0555a333f9eac31ec1", size = 821174704, upload-time = "2025-06-04T17:37:03.799Z" }, - { url = "https://files.pythonhosted.org/packages/50/9e/acf04ff375b0b49a45511c55d188bcea5c942da2aaf293096676110086d1/torch-2.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:8273145a2e0a3c6f9fd2ac36762d6ee89c26d430e612b95a99885df083b04e52", size = 216095937, upload-time = "2025-06-04T17:39:24.83Z" }, - { url = "https://files.pythonhosted.org/packages/5b/2b/d36d57c66ff031f93b4fa432e86802f84991477e522adcdffd314454326b/torch-2.7.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:aea4fc1bf433d12843eb2c6b2204861f43d8364597697074c8d38ae2507f8730", size = 68640034, upload-time = "2025-06-04T17:39:17.989Z" }, - { url = "https://files.pythonhosted.org/packages/87/93/fb505a5022a2e908d81fe9a5e0aa84c86c0d5f408173be71c6018836f34e/torch-2.7.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:27ea1e518df4c9de73af7e8a720770f3628e7f667280bce2be7a16292697e3fa", size = 98948276, upload-time = "2025-06-04T17:39:12.852Z" }, - { url = "https://files.pythonhosted.org/packages/56/7e/67c3fe2b8c33f40af06326a3d6ae7776b3e3a01daa8f71d125d78594d874/torch-2.7.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:c33360cfc2edd976c2633b3b66c769bdcbbf0e0b6550606d188431c81e7dd1fc", size = 821025792, upload-time = "2025-06-04T17:34:58.747Z" }, - { url = "https://files.pythonhosted.org/packages/a1/37/a37495502bc7a23bf34f89584fa5a78e25bae7b8da513bc1b8f97afb7009/torch-2.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:d8bf6e1856ddd1807e79dc57e54d3335f2b62e6f316ed13ed3ecfe1fc1df3d8b", size = 216050349, upload-time = "2025-06-04T17:38:59.709Z" }, - { url = "https://files.pythonhosted.org/packages/3a/60/04b77281c730bb13460628e518c52721257814ac6c298acd25757f6a175c/torch-2.7.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:787687087412c4bd68d315e39bc1223f08aae1d16a9e9771d95eabbb04ae98fb", size = 68645146, upload-time = "2025-06-04T17:38:52.97Z" }, - { url = "https://files.pythonhosted.org/packages/66/81/e48c9edb655ee8eb8c2a6026abdb6f8d2146abd1f150979ede807bb75dcb/torch-2.7.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:03563603d931e70722dce0e11999d53aa80a375a3d78e6b39b9f6805ea0a8d28", size = 98946649, upload-time = "2025-06-04T17:38:43.031Z" }, - { url = "https://files.pythonhosted.org/packages/3a/24/efe2f520d75274fc06b695c616415a1e8a1021d87a13c68ff9dce733d088/torch-2.7.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:d632f5417b6980f61404a125b999ca6ebd0b8b4bbdbb5fbbba44374ab619a412", size = 821033192, upload-time = "2025-06-04T17:38:09.146Z" }, - { url = "https://files.pythonhosted.org/packages/dd/d9/9c24d230333ff4e9b6807274f6f8d52a864210b52ec794c5def7925f4495/torch-2.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:23660443e13995ee93e3d844786701ea4ca69f337027b05182f5ba053ce43b38", size = 216055668, upload-time = "2025-06-04T17:38:36.253Z" }, - { url = "https://files.pythonhosted.org/packages/95/bf/e086ee36ddcef9299f6e708d3b6c8487c1651787bb9ee2939eb2a7f74911/torch-2.7.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:0da4f4dba9f65d0d203794e619fe7ca3247a55ffdcbd17ae8fb83c8b2dc9b585", size = 68925988, upload-time = "2025-06-04T17:38:29.273Z" }, - { url = "https://files.pythonhosted.org/packages/69/6a/67090dcfe1cf9048448b31555af6efb149f7afa0a310a366adbdada32105/torch-2.7.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:e08d7e6f21a617fe38eeb46dd2213ded43f27c072e9165dc27300c9ef9570934", size = 99028857, upload-time = "2025-06-04T17:37:50.956Z" }, - { url = "https://files.pythonhosted.org/packages/90/1c/48b988870823d1cc381f15ec4e70ed3d65e043f43f919329b0045ae83529/torch-2.7.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:30207f672328a42df4f2174b8f426f354b2baa0b7cca3a0adb3d6ab5daf00dc8", size = 821098066, upload-time = "2025-06-04T17:37:33.939Z" }, - { url = "https://files.pythonhosted.org/packages/7b/eb/10050d61c9d5140c5dc04a89ed3257ef1a6b93e49dd91b95363d757071e0/torch-2.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:79042feca1c634aaf6603fe6feea8c6b30dfa140a6bbc0b973e2260c7e79a22e", size = 216336310, upload-time = "2025-06-04T17:36:09.862Z" }, - { url = "https://files.pythonhosted.org/packages/b1/29/beb45cdf5c4fc3ebe282bf5eafc8dfd925ead7299b3c97491900fe5ed844/torch-2.7.1-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:988b0cbc4333618a1056d2ebad9eb10089637b659eb645434d0809d8d937b946", size = 68645708, upload-time = "2025-06-04T17:34:39.852Z" }, + { url = "https://files.pythonhosted.org/packages/5b/30/bfebdd8ec77db9a79775121789992d6b3b75ee5494971294d7b4b7c999bc/torch-2.10.0-2-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:2b980edd8d7c0a68c4e951ee1856334a43193f98730d97408fbd148c1a933313", size = 79411457, upload-time = "2026-02-10T21:44:59.189Z" }, + { url = "https://files.pythonhosted.org/packages/0f/8b/4b61d6e13f7108f36910df9ab4b58fd389cc2520d54d81b88660804aad99/torch-2.10.0-2-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:418997cb02d0a0f1497cf6a09f63166f9f5df9f3e16c8a716ab76a72127c714f", size = 79423467, upload-time = "2026-02-10T21:44:48.711Z" }, + { url = "https://files.pythonhosted.org/packages/d3/54/a2ba279afcca44bbd320d4e73675b282fcee3d81400ea1b53934efca6462/torch-2.10.0-2-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:13ec4add8c3faaed8d13e0574f5cd4a323c11655546f91fbe6afa77b57423574", size = 79498202, upload-time = "2026-02-10T21:44:52.603Z" }, + { url = "https://files.pythonhosted.org/packages/ec/23/2c9fe0c9c27f7f6cb865abcea8a4568f29f00acaeadfc6a37f6801f84cb4/torch-2.10.0-2-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:e521c9f030a3774ed770a9c011751fb47c4d12029a3d6522116e48431f2ff89e", size = 79498254, upload-time = "2026-02-10T21:44:44.095Z" }, + { url = "https://files.pythonhosted.org/packages/16/ee/efbd56687be60ef9af0c9c0ebe106964c07400eade5b0af8902a1d8cd58c/torch-2.10.0-3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a1ff626b884f8c4e897c4c33782bdacdff842a165fee79817b1dd549fdda1321", size = 915510070, upload-time = "2026-03-11T14:16:39.386Z" }, + { url = "https://files.pythonhosted.org/packages/36/ab/7b562f1808d3f65414cd80a4f7d4bb00979d9355616c034c171249e1a303/torch-2.10.0-3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac5bdcbb074384c66fa160c15b1ead77839e3fe7ed117d667249afce0acabfac", size = 915518691, upload-time = "2026-03-11T14:15:43.147Z" }, + { url = "https://files.pythonhosted.org/packages/b3/7a/abada41517ce0011775f0f4eacc79659bc9bc6c361e6bfe6f7052a6b9363/torch-2.10.0-3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:98c01b8bb5e3240426dcde1446eed6f40c778091c8544767ef1168fc663a05a6", size = 915622781, upload-time = "2026-03-11T14:17:11.354Z" }, + { url = "https://files.pythonhosted.org/packages/ab/c6/4dfe238342ffdcec5aef1c96c457548762d33c40b45a1ab7033bb26d2ff2/torch-2.10.0-3-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:80b1b5bfe38eb0e9f5ff09f206dcac0a87aadd084230d4a36eea5ec5232c115b", size = 915627275, upload-time = "2026-03-11T14:16:11.325Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f0/72bf18847f58f877a6a8acf60614b14935e2f156d942483af1ffc081aea0/torch-2.10.0-3-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:46b3574d93a2a8134b3f5475cfb98e2eb46771794c57015f6ad1fb795ec25e49", size = 915523474, upload-time = "2026-03-11T14:17:44.422Z" }, + { url = "https://files.pythonhosted.org/packages/f4/39/590742415c3030551944edc2ddc273ea1fdfe8ffb2780992e824f1ebee98/torch-2.10.0-3-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:b1d5e2aba4eb7f8e87fbe04f86442887f9167a35f092afe4c237dfcaaef6e328", size = 915632474, upload-time = "2026-03-11T14:15:13.666Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8e/34949484f764dde5b222b7fe3fede43e4a6f0da9d7f8c370bb617d629ee2/torch-2.10.0-3-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:0228d20b06701c05a8f978357f657817a4a63984b0c90745def81c18aedfa591", size = 915523882, upload-time = "2026-03-11T14:14:46.311Z" }, + { url = "https://files.pythonhosted.org/packages/0c/1a/c61f36cfd446170ec27b3a4984f072fd06dab6b5d7ce27e11adb35d6c838/torch-2.10.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:5276fa790a666ee8becaffff8acb711922252521b28fbce5db7db5cf9cb2026d", size = 145992962, upload-time = "2026-01-21T16:24:14.04Z" }, + { url = "https://files.pythonhosted.org/packages/b5/60/6662535354191e2d1555296045b63e4279e5a9dbad49acf55a5d38655a39/torch-2.10.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:aaf663927bcd490ae971469a624c322202a2a1e68936eb952535ca4cd3b90444", size = 915599237, upload-time = "2026-01-21T16:23:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/40/b8/66bbe96f0d79be2b5c697b2e0b187ed792a15c6c4b8904613454651db848/torch-2.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:a4be6a2a190b32ff5c8002a0977a25ea60e64f7ba46b1be37093c141d9c49aeb", size = 113720931, upload-time = "2026-01-21T16:24:23.743Z" }, + { url = "https://files.pythonhosted.org/packages/76/bb/d820f90e69cda6c8169b32a0c6a3ab7b17bf7990b8f2c680077c24a3c14c/torch-2.10.0-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:35e407430795c8d3edb07a1d711c41cc1f9eaddc8b2f1cc0a165a6767a8fb73d", size = 79411450, upload-time = "2026-01-21T16:25:30.692Z" }, + { url = "https://files.pythonhosted.org/packages/78/89/f5554b13ebd71e05c0b002f95148033e730d3f7067f67423026cc9c69410/torch-2.10.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:3282d9febd1e4e476630a099692b44fdc214ee9bf8ee5377732d9d9dfe5712e4", size = 145992610, upload-time = "2026-01-21T16:25:26.327Z" }, + { url = "https://files.pythonhosted.org/packages/ae/30/a3a2120621bf9c17779b169fc17e3dc29b230c29d0f8222f499f5e159aa8/torch-2.10.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a2f9edd8dbc99f62bc4dfb78af7bf89499bca3d753423ac1b4e06592e467b763", size = 915607863, upload-time = "2026-01-21T16:25:06.696Z" }, + { url = "https://files.pythonhosted.org/packages/6f/3d/c87b33c5f260a2a8ad68da7147e105f05868c281c63d65ed85aa4da98c66/torch-2.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:29b7009dba4b7a1c960260fc8ac85022c784250af43af9fb0ebafc9883782ebd", size = 113723116, upload-time = "2026-01-21T16:25:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/61/d8/15b9d9d3a6b0c01b883787bd056acbe5cc321090d4b216d3ea89a8fcfdf3/torch-2.10.0-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:b7bd80f3477b830dd166c707c5b0b82a898e7b16f59a7d9d42778dd058272e8b", size = 79423461, upload-time = "2026-01-21T16:24:50.266Z" }, + { url = "https://files.pythonhosted.org/packages/cc/af/758e242e9102e9988969b5e621d41f36b8f258bb4a099109b7a4b4b50ea4/torch-2.10.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:5fd4117d89ffd47e3dcc71e71a22efac24828ad781c7e46aaaf56bf7f2796acf", size = 145996088, upload-time = "2026-01-21T16:24:44.171Z" }, + { url = "https://files.pythonhosted.org/packages/23/8e/3c74db5e53bff7ed9e34c8123e6a8bfef718b2450c35eefab85bb4a7e270/torch-2.10.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:787124e7db3b379d4f1ed54dd12ae7c741c16a4d29b49c0226a89bea50923ffb", size = 915711952, upload-time = "2026-01-21T16:23:53.503Z" }, + { url = "https://files.pythonhosted.org/packages/6e/01/624c4324ca01f66ae4c7cd1b74eb16fb52596dce66dbe51eff95ef9e7a4c/torch-2.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:2c66c61f44c5f903046cc696d088e21062644cbe541c7f1c4eaae88b2ad23547", size = 113757972, upload-time = "2026-01-21T16:24:39.516Z" }, + { url = "https://files.pythonhosted.org/packages/c9/5c/dee910b87c4d5c0fcb41b50839ae04df87c1cfc663cf1b5fca7ea565eeaa/torch-2.10.0-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:6d3707a61863d1c4d6ebba7be4ca320f42b869ee657e9b2c21c736bf17000294", size = 79498198, upload-time = "2026-01-21T16:24:34.704Z" }, + { url = "https://files.pythonhosted.org/packages/c9/6f/f2e91e34e3fcba2e3fc8d8f74e7d6c22e74e480bbd1db7bc8900fdf3e95c/torch-2.10.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5c4d217b14741e40776dd7074d9006fd28b8a97ef5654db959d8635b2fe5f29b", size = 146004247, upload-time = "2026-01-21T16:24:29.335Z" }, + { url = "https://files.pythonhosted.org/packages/98/fb/5160261aeb5e1ee12ee95fe599d0541f7c976c3701d607d8fc29e623229f/torch-2.10.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6b71486353fce0f9714ca0c9ef1c850a2ae766b409808acd58e9678a3edb7738", size = 915716445, upload-time = "2026-01-21T16:22:45.353Z" }, + { url = "https://files.pythonhosted.org/packages/6a/16/502fb1b41e6d868e8deb5b0e3ae926bbb36dab8ceb0d1b769b266ad7b0c3/torch-2.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:c2ee399c644dc92ef7bc0d4f7e74b5360c37cdbe7c5ba11318dda49ffac2bc57", size = 113757050, upload-time = "2026-01-21T16:24:19.204Z" }, + { url = "https://files.pythonhosted.org/packages/1a/0b/39929b148f4824bc3ad6f9f72a29d4ad865bcf7ebfc2fa67584773e083d2/torch-2.10.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:3202429f58309b9fa96a614885eace4b7995729f44beb54d3e4a47773649d382", size = 79851305, upload-time = "2026-01-21T16:24:09.209Z" }, + { url = "https://files.pythonhosted.org/packages/d8/14/21fbce63bc452381ba5f74a2c0a959fdf5ad5803ccc0c654e752e0dbe91a/torch-2.10.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:aae1b29cd68e50a9397f5ee897b9c24742e9e306f88a807a27d617f07adb3bd8", size = 146005472, upload-time = "2026-01-21T16:22:29.022Z" }, + { url = "https://files.pythonhosted.org/packages/54/fd/b207d1c525cb570ef47f3e9f836b154685011fce11a2f444ba8a4084d042/torch-2.10.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6021db85958db2f07ec94e1bc77212721ba4920c12a18dc552d2ae36a3eb163f", size = 915612644, upload-time = "2026-01-21T16:21:47.019Z" }, + { url = "https://files.pythonhosted.org/packages/36/53/0197f868c75f1050b199fe58f9bf3bf3aecac9b4e85cc9c964383d745403/torch-2.10.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff43db38af76fda183156153983c9a096fc4c78d0cd1e07b14a2314c7f01c2c8", size = 113997015, upload-time = "2026-01-21T16:23:00.767Z" }, + { url = "https://files.pythonhosted.org/packages/0e/13/e76b4d9c160e89fff48bf16b449ea324bda84745d2ab30294c37c2434c0d/torch-2.10.0-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:cdf2a523d699b70d613243211ecaac14fe9c5df8a0b0a9c02add60fb2a413e0f", size = 79498248, upload-time = "2026-01-21T16:23:09.315Z" }, + { url = "https://files.pythonhosted.org/packages/4f/93/716b5ac0155f1be70ed81bacc21269c3ece8dba0c249b9994094110bfc51/torch-2.10.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:bf0d9ff448b0218e0433aeb198805192346c4fd659c852370d5cc245f602a06a", size = 79464992, upload-time = "2026-01-21T16:23:05.162Z" }, + { url = "https://files.pythonhosted.org/packages/69/2b/51e663ff190c9d16d4a8271203b71bc73a16aa7619b9f271a69b9d4a936b/torch-2.10.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:233aed0659a2503b831d8a67e9da66a62c996204c0bba4f4c442ccc0c68a3f60", size = 146018567, upload-time = "2026-01-21T16:22:23.393Z" }, + { url = "https://files.pythonhosted.org/packages/5e/cd/4b95ef7f293b927c283db0b136c42be91c8ec6845c44de0238c8c23bdc80/torch-2.10.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:682497e16bdfa6efeec8cde66531bc8d1fbbbb4d8788ec6173c089ed3cc2bfe5", size = 915721646, upload-time = "2026-01-21T16:21:16.983Z" }, + { url = "https://files.pythonhosted.org/packages/56/97/078a007208f8056d88ae43198833469e61a0a355abc0b070edd2c085eb9a/torch-2.10.0-cp314-cp314-win_amd64.whl", hash = "sha256:6528f13d2a8593a1a412ea07a99812495bec07e9224c28b2a25c0a30c7da025c", size = 113752373, upload-time = "2026-01-21T16:22:13.471Z" }, + { url = "https://files.pythonhosted.org/packages/d8/94/71994e7d0d5238393df9732fdab607e37e2b56d26a746cb59fdb415f8966/torch-2.10.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:f5ab4ba32383061be0fb74bda772d470140a12c1c3b58a0cfbf3dae94d164c28", size = 79850324, upload-time = "2026-01-21T16:22:09.494Z" }, + { url = "https://files.pythonhosted.org/packages/e2/65/1a05346b418ea8ccd10360eef4b3e0ce688fba544e76edec26913a8d0ee0/torch-2.10.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:716b01a176c2a5659c98f6b01bf868244abdd896526f1c692712ab36dbaf9b63", size = 146006482, upload-time = "2026-01-21T16:22:18.42Z" }, + { url = "https://files.pythonhosted.org/packages/1d/b9/5f6f9d9e859fc3235f60578fa64f52c9c6e9b4327f0fe0defb6de5c0de31/torch-2.10.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:d8f5912ba938233f86361e891789595ff35ca4b4e2ac8fe3670895e5976731d6", size = 915613050, upload-time = "2026-01-21T16:20:49.035Z" }, + { url = "https://files.pythonhosted.org/packages/66/4d/35352043ee0eaffdeff154fad67cd4a31dbed7ff8e3be1cc4549717d6d51/torch-2.10.0-cp314-cp314t-win_amd64.whl", hash = "sha256:71283a373f0ee2c89e0f0d5f446039bdabe8dbc3c9ccf35f0f784908b0acd185", size = 113995816, upload-time = "2026-01-21T16:22:05.312Z" }, ] [[package]] name = "torchvision" -version = "0.22.1" +version = "0.25.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, @@ -6376,26 +6423,34 @@ dependencies = [ { name = "torch" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/15/2c/7b67117b14c6cc84ae3126ca6981abfa3af2ac54eb5252b80d9475fb40df/torchvision-0.22.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3b47d8369ee568c067795c0da0b4078f39a9dfea6f3bc1f3ac87530dfda1dd56", size = 1947825, upload-time = "2025-06-04T17:43:15.523Z" }, - { url = "https://files.pythonhosted.org/packages/6c/9f/c4dcf1d232b75e28bc37e21209ab2458d6d60235e16163544ed693de54cb/torchvision-0.22.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:990de4d657a41ed71680cd8be2e98ebcab55371f30993dc9bd2e676441f7180e", size = 2512611, upload-time = "2025-06-04T17:43:03.951Z" }, - { url = "https://files.pythonhosted.org/packages/e2/99/db71d62d12628111d59147095527a0ab492bdfecfba718d174c04ae6c505/torchvision-0.22.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:3347f690c2eed6d02aa0edfb9b01d321e7f7cf1051992d96d8d196c39b881d49", size = 7485668, upload-time = "2025-06-04T17:43:09.453Z" }, - { url = "https://files.pythonhosted.org/packages/32/ff/4a93a4623c3e5f97e8552af0f9f81d289dcf7f2ac71f1493f1c93a6b973d/torchvision-0.22.1-cp310-cp310-win_amd64.whl", hash = "sha256:86ad938f5a6ca645f0d5fb19484b1762492c2188c0ffb05c602e9e9945b7b371", size = 1707961, upload-time = "2025-06-04T17:43:13.038Z" }, - { url = "https://files.pythonhosted.org/packages/f6/00/bdab236ef19da050290abc2b5203ff9945c84a1f2c7aab73e8e9c8c85669/torchvision-0.22.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4addf626e2b57fc22fd6d329cf1346d474497672e6af8383b7b5b636fba94a53", size = 1947827, upload-time = "2025-06-04T17:43:10.84Z" }, - { url = "https://files.pythonhosted.org/packages/ac/d0/18f951b2be3cfe48c0027b349dcc6fde950e3dc95dd83e037e86f284f6fd/torchvision-0.22.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:8b4a53a6067d63adba0c52f2b8dd2290db649d642021674ee43c0c922f0c6a69", size = 2514021, upload-time = "2025-06-04T17:43:07.608Z" }, - { url = "https://files.pythonhosted.org/packages/c3/1a/63eb241598b36d37a0221e10af357da34bd33402ccf5c0765e389642218a/torchvision-0.22.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:b7866a3b326413e67724ac46f1ee594996735e10521ba9e6cdbe0fa3cd98c2f2", size = 7487300, upload-time = "2025-06-04T17:42:58.349Z" }, - { url = "https://files.pythonhosted.org/packages/e5/73/1b009b42fe4a7774ba19c23c26bb0f020d68525c417a348b166f1c56044f/torchvision-0.22.1-cp311-cp311-win_amd64.whl", hash = "sha256:bb3f6df6f8fd415ce38ec4fd338376ad40c62e86052d7fc706a0dd51efac1718", size = 1707989, upload-time = "2025-06-04T17:43:14.332Z" }, - { url = "https://files.pythonhosted.org/packages/02/90/f4e99a5112dc221cf68a485e853cc3d9f3f1787cb950b895f3ea26d1ea98/torchvision-0.22.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:153f1790e505bd6da123e21eee6e83e2e155df05c0fe7d56347303067d8543c5", size = 1947827, upload-time = "2025-06-04T17:43:11.945Z" }, - { url = "https://files.pythonhosted.org/packages/25/f6/53e65384cdbbe732cc2106bb04f7fb908487e4fb02ae4a1613ce6904a122/torchvision-0.22.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:964414eef19459d55a10e886e2fca50677550e243586d1678f65e3f6f6bac47a", size = 2514576, upload-time = "2025-06-04T17:43:02.707Z" }, - { url = "https://files.pythonhosted.org/packages/17/8b/155f99042f9319bd7759536779b2a5b67cbd4f89c380854670850f89a2f4/torchvision-0.22.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:699c2d70d33951187f6ed910ea05720b9b4aaac1dcc1135f53162ce7d42481d3", size = 7485962, upload-time = "2025-06-04T17:42:43.606Z" }, - { url = "https://files.pythonhosted.org/packages/05/17/e45d5cd3627efdb47587a0634179a3533593436219de3f20c743672d2a79/torchvision-0.22.1-cp312-cp312-win_amd64.whl", hash = "sha256:75e0897da7a8e43d78632f66f2bdc4f6e26da8d3f021a7c0fa83746073c2597b", size = 1707992, upload-time = "2025-06-04T17:42:53.207Z" }, - { url = "https://files.pythonhosted.org/packages/7a/30/fecdd09fb973e963da68207fe9f3d03ec6f39a935516dc2a98397bf495c6/torchvision-0.22.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c3ae3319624c43cc8127020f46c14aa878406781f0899bb6283ae474afeafbf", size = 1947818, upload-time = "2025-06-04T17:42:51.954Z" }, - { url = "https://files.pythonhosted.org/packages/55/f4/b45f6cd92fa0acfac5e31b8e9258232f25bcdb0709a604e8b8a39d76e411/torchvision-0.22.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:4a614a6a408d2ed74208d0ea6c28a2fbb68290e9a7df206c5fef3f0b6865d307", size = 2471597, upload-time = "2025-06-04T17:42:48.838Z" }, - { url = "https://files.pythonhosted.org/packages/8d/b0/3cffd6a285b5ffee3fe4a31caff49e350c98c5963854474d1c4f7a51dea5/torchvision-0.22.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:7ee682be589bb1a002b7704f06b8ec0b89e4b9068f48e79307d2c6e937a9fdf4", size = 7485894, upload-time = "2025-06-04T17:43:01.371Z" }, - { url = "https://files.pythonhosted.org/packages/fd/1d/0ede596fedc2080d18108149921278b59f220fbb398f29619495337b0f86/torchvision-0.22.1-cp313-cp313-win_amd64.whl", hash = "sha256:2566cafcfa47ecfdbeed04bab8cef1307c8d4ef75046f7624b9e55f384880dfe", size = 1708020, upload-time = "2025-06-04T17:43:06.085Z" }, - { url = "https://files.pythonhosted.org/packages/0f/ca/e9a06bd61ee8e04fb4962a3fb524fe6ee4051662db07840b702a9f339b24/torchvision-0.22.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:043d9e35ed69c2e586aff6eb9e2887382e7863707115668ac9d140da58f42cba", size = 2137623, upload-time = "2025-06-04T17:43:05.028Z" }, - { url = "https://files.pythonhosted.org/packages/ab/c8/2ebe90f18e7ffa2120f5c3eab62aa86923185f78d2d051a455ea91461608/torchvision-0.22.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:27142bcc8a984227a6dcf560985e83f52b82a7d3f5fe9051af586a2ccc46ef26", size = 2476561, upload-time = "2025-06-04T17:42:59.691Z" }, - { url = "https://files.pythonhosted.org/packages/94/8b/04c6b15f8c29b39f0679589753091cec8b192ab296d4fdaf9055544c4ec9/torchvision-0.22.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ef46e065502f7300ad6abc98554131c35dc4c837b978d91306658f1a65c00baa", size = 7658543, upload-time = "2025-06-04T17:42:46.064Z" }, - { url = "https://files.pythonhosted.org/packages/ab/c0/131628e6d42682b0502c63fd7f647b8b5ca4bd94088f6c85ca7225db8ac4/torchvision-0.22.1-cp313-cp313t-win_amd64.whl", hash = "sha256:7414eeacfb941fa21acddcd725f1617da5630ec822e498660a4b864d7d998075", size = 1629892, upload-time = "2025-06-04T17:42:57.156Z" }, + { url = "https://files.pythonhosted.org/packages/50/ae/cbf727421eb73f1cf907fbe5788326a08f111b3f6b6ddca15426b53fec9a/torchvision-0.25.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a95c47abb817d4e90ea1a8e57bd0d728e3e6b533b3495ae77d84d883c4d11f56", size = 1874919, upload-time = "2026-01-21T16:27:47.617Z" }, + { url = "https://files.pythonhosted.org/packages/64/68/dc7a224f606d53ea09f9a85196a3921ec3a801b0b1d17e84c73392f0c029/torchvision-0.25.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:acc339aba4a858192998c2b91f635827e40d9c469d9cf1455bafdda6e4c28ea4", size = 2343220, upload-time = "2026-01-21T16:27:44.26Z" }, + { url = "https://files.pythonhosted.org/packages/f9/fa/8cce5ca7ffd4da95193232493703d20aa06303f37b119fd23a65df4f239a/torchvision-0.25.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:0d9a3f925a081dd2ebb0b791249b687c2ef2c2717d027946654607494b9b64b6", size = 8068106, upload-time = "2026-01-21T16:27:37.805Z" }, + { url = "https://files.pythonhosted.org/packages/8b/b9/a53bcf8f78f2cd89215e9ded70041765d50ef13bf301f9884ec6041a9421/torchvision-0.25.0-cp310-cp310-win_amd64.whl", hash = "sha256:b57430fbe9e9b697418a395041bb615124d9c007710a2712fda6e35fb310f264", size = 3697295, upload-time = "2026-01-21T16:27:36.574Z" }, + { url = "https://files.pythonhosted.org/packages/3e/be/c704bceaf11c4f6b19d64337a34a877fcdfe3bd68160a8c9ae9bea4a35a3/torchvision-0.25.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db74a551946b75d19f9996c419a799ffdf6a223ecf17c656f90da011f1d75b20", size = 1874923, upload-time = "2026-01-21T16:27:46.574Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e9/f143cd71232430de1f547ceab840f68c55e127d72558b1061a71d0b193cd/torchvision-0.25.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:f49964f96644dbac2506dffe1a0a7ec0f2bf8cf7a588c3319fed26e6329ffdf3", size = 2344808, upload-time = "2026-01-21T16:27:43.191Z" }, + { url = "https://files.pythonhosted.org/packages/43/ae/ad5d6165797de234c9658752acb4fce65b78a6a18d82efdf8367c940d8da/torchvision-0.25.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:153c0d2cbc34b7cf2da19d73450f24ba36d2b75ec9211b9962b5022fb9e4ecee", size = 8070752, upload-time = "2026-01-21T16:27:33.748Z" }, + { url = "https://files.pythonhosted.org/packages/23/19/55b28aecdc7f38df57b8eb55eb0b14a62b470ed8efeb22cdc74224df1d6a/torchvision-0.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:ea580ffd6094cc01914ad32f8c8118174f18974629af905cea08cb6d5d48c7b7", size = 4038722, upload-time = "2026-01-21T16:27:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/56/3a/6ea0d73f49a9bef38a1b3a92e8dd455cea58470985d25635beab93841748/torchvision-0.25.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2abe430c90b1d5e552680037d68da4eb80a5852ebb1c811b2b89d299b10573b", size = 1874920, upload-time = "2026-01-21T16:27:45.348Z" }, + { url = "https://files.pythonhosted.org/packages/51/f8/c0e1ef27c66e15406fece94930e7d6feee4cb6374bbc02d945a630d6426e/torchvision-0.25.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:b75deafa2dfea3e2c2a525559b04783515e3463f6e830cb71de0fb7ea36fe233", size = 2344556, upload-time = "2026-01-21T16:27:40.125Z" }, + { url = "https://files.pythonhosted.org/packages/68/2f/f24b039169db474e8688f649377de082a965fbf85daf4e46c44412f1d15a/torchvision-0.25.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:f25aa9e380865b11ea6e9d99d84df86b9cc959f1a007cd966fc6f1ab2ed0e248", size = 8072351, upload-time = "2026-01-21T16:27:21.074Z" }, + { url = "https://files.pythonhosted.org/packages/ad/16/8f650c2e288977cf0f8f85184b90ee56ed170a4919347fc74ee99286ed6f/torchvision-0.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:f9c55ae8d673ab493325d1267cbd285bb94d56f99626c00ac4644de32a59ede3", size = 4303059, upload-time = "2026-01-21T16:27:11.08Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5b/1562a04a6a5a4cf8cf40016a0cdeda91ede75d6962cff7f809a85ae966a5/torchvision-0.25.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:24e11199e4d84ba9c5ee7825ebdf1cd37ce8deec225117f10243cae984ced3ec", size = 1874918, upload-time = "2026-01-21T16:27:39.02Z" }, + { url = "https://files.pythonhosted.org/packages/36/b1/3d6c42f62c272ce34fcce609bb8939bdf873dab5f1b798fd4e880255f129/torchvision-0.25.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5f271136d2d2c0b7a24c5671795c6e4fd8da4e0ea98aeb1041f62bc04c4370ef", size = 2309106, upload-time = "2026-01-21T16:27:30.624Z" }, + { url = "https://files.pythonhosted.org/packages/c7/60/59bb9c8b67cce356daeed4cb96a717caa4f69c9822f72e223a0eae7a9bd9/torchvision-0.25.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:855c0dc6d37f462482da7531c6788518baedca1e0847f3df42a911713acdfe52", size = 8071522, upload-time = "2026-01-21T16:27:29.392Z" }, + { url = "https://files.pythonhosted.org/packages/32/a5/9a9b1de0720f884ea50dbf9acb22cbe5312e51d7b8c4ac6ba9b51efd9bba/torchvision-0.25.0-cp313-cp313-win_amd64.whl", hash = "sha256:cef0196be31be421f6f462d1e9da1101be7332d91984caa6f8022e6c78a5877f", size = 4321911, upload-time = "2026-01-21T16:27:35.195Z" }, + { url = "https://files.pythonhosted.org/packages/52/99/dca81ed21ebaeff2b67cc9f815a20fdaa418b69f5f9ea4c6ed71721470db/torchvision-0.25.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a8f8061284395ce31bcd460f2169013382ccf411148ceb2ee38e718e9860f5a7", size = 1896209, upload-time = "2026-01-21T16:27:32.159Z" }, + { url = "https://files.pythonhosted.org/packages/28/cc/2103149761fdb4eaed58a53e8437b2d716d48f05174fab1d9fcf1e2a2244/torchvision-0.25.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:146d02c9876858420adf41f3189fe90e3d6a409cbfa65454c09f25fb33bf7266", size = 2310735, upload-time = "2026-01-21T16:27:22.327Z" }, + { url = "https://files.pythonhosted.org/packages/76/ad/f4c985ad52ddd3b22711c588501be1b330adaeaf6850317f66751711b78c/torchvision-0.25.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:c4d395cb2c4a2712f6eb93a34476cdf7aae74bb6ea2ea1917f858e96344b00aa", size = 8089557, upload-time = "2026-01-21T16:27:27.666Z" }, + { url = "https://files.pythonhosted.org/packages/63/cc/0ea68b5802e5e3c31f44b307e74947bad5a38cc655231d845534ed50ddb8/torchvision-0.25.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5e6b449e9fa7d642142c0e27c41e5a43b508d57ed8e79b7c0a0c28652da8678c", size = 4344260, upload-time = "2026-01-21T16:27:17.018Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1f/fa839532660e2602b7e704d65010787c5bb296258b44fa8b9c1cd6175e7d/torchvision-0.25.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:620a236288d594dcec7634c754484542dc0a5c1b0e0b83a34bda5e91e9b7c3a1", size = 1896193, upload-time = "2026-01-21T16:27:24.785Z" }, + { url = "https://files.pythonhosted.org/packages/80/ed/d51889da7ceaf5ff7a0574fb28f9b6b223df19667265395891f81b364ab3/torchvision-0.25.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:0b5e7f50002a8145a98c5694a018e738c50e2972608310c7e88e1bd4c058f6ce", size = 2309331, upload-time = "2026-01-21T16:27:19.97Z" }, + { url = "https://files.pythonhosted.org/packages/90/a5/f93fcffaddd8f12f9e812256830ec9c9ca65abbf1bc369379f9c364d1ff4/torchvision-0.25.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:632db02300e83793812eee4f61ae6a2686dab10b4cfd628b620dc47747aa9d03", size = 8088713, upload-time = "2026-01-21T16:27:15.281Z" }, + { url = "https://files.pythonhosted.org/packages/1f/eb/d0096eed5690d962853213f2ee00d91478dfcb586b62dbbb449fb8abc3a6/torchvision-0.25.0-cp314-cp314-win_amd64.whl", hash = "sha256:d1abd5ed030c708f5dbf4812ad5f6fbe9384b63c40d6bd79f8df41a4a759a917", size = 4325058, upload-time = "2026-01-21T16:27:26.165Z" }, + { url = "https://files.pythonhosted.org/packages/97/36/96374a4c7ab50dea9787ce987815614ccfe988a42e10ac1a2e3e5b60319a/torchvision-0.25.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ad9a8a5877782944d99186e4502a614770fe906626d76e9cd32446a0ac3075f2", size = 1896207, upload-time = "2026-01-21T16:27:23.383Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e2/7abb10a867db79b226b41da419b63b69c0bd5b82438c4a4ed50e084c552f/torchvision-0.25.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:40a122c3cf4d14b651f095e0f672b688dde78632783fc5cd3d4d5e4f6a828563", size = 2310741, upload-time = "2026-01-21T16:27:18.712Z" }, + { url = "https://files.pythonhosted.org/packages/08/e6/0927784e6ffc340b6676befde1c60260bd51641c9c574b9298d791a9cda4/torchvision-0.25.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:846890161b825b38aa85fc37fb3ba5eea74e7091ff28bab378287111483b6443", size = 8089772, upload-time = "2026-01-21T16:27:14.048Z" }, + { url = "https://files.pythonhosted.org/packages/b6/37/e7ca4ec820d434c0f23f824eb29f0676a0c3e7a118f1514f5b949c3356da/torchvision-0.25.0-cp314-cp314t-win_amd64.whl", hash = "sha256:f07f01d27375ad89d72aa2b3f2180f07da95dd9d2e4c758e015c0acb2da72977", size = 4425879, upload-time = "2026-01-21T16:27:12.579Z" }, ] [[package]] @@ -6631,17 +6686,16 @@ sdist = { url = "https://files.pythonhosted.org/packages/42/c2/65f13aec253100e19 [[package]] name = "triton" -version = "3.3.1" +version = "3.6.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "setuptools", marker = "sys_platform == 'linux'" }, -] wheels = [ - { url = "https://files.pythonhosted.org/packages/8d/a9/549e51e9b1b2c9b854fd761a1d23df0ba2fbc60bd0c13b489ffa518cfcb7/triton-3.3.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b74db445b1c562844d3cfad6e9679c72e93fdfb1a90a24052b03bb5c49d1242e", size = 155600257, upload-time = "2025-05-29T23:39:36.085Z" }, - { url = "https://files.pythonhosted.org/packages/21/2f/3e56ea7b58f80ff68899b1dbe810ff257c9d177d288c6b0f55bf2fe4eb50/triton-3.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b31e3aa26f8cb3cc5bf4e187bf737cbacf17311e1112b781d4a059353dfd731b", size = 155689937, upload-time = "2025-05-29T23:39:44.182Z" }, - { url = "https://files.pythonhosted.org/packages/24/5f/950fb373bf9c01ad4eb5a8cd5eaf32cdf9e238c02f9293557a2129b9c4ac/triton-3.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9999e83aba21e1a78c1f36f21bce621b77bcaa530277a50484a7cb4a822f6e43", size = 155669138, upload-time = "2025-05-29T23:39:51.771Z" }, - { url = "https://files.pythonhosted.org/packages/74/1f/dfb531f90a2d367d914adfee771babbd3f1a5b26c3f5fbc458dee21daa78/triton-3.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b89d846b5a4198317fec27a5d3a609ea96b6d557ff44b56c23176546023c4240", size = 155673035, upload-time = "2025-05-29T23:40:02.468Z" }, - { url = "https://files.pythonhosted.org/packages/28/71/bd20ffcb7a64c753dc2463489a61bf69d531f308e390ad06390268c4ea04/triton-3.3.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3198adb9d78b77818a5388bff89fa72ff36f9da0bc689db2f0a651a67ce6a42", size = 155735832, upload-time = "2025-05-29T23:40:10.522Z" }, + { url = "https://files.pythonhosted.org/packages/8c/f7/f1c9d3424ab199ac53c2da567b859bcddbb9c9e7154805119f8bd95ec36f/triton-3.6.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6550fae429e0667e397e5de64b332d1e5695b73650ee75a6146e2e902770bea", size = 188105201, upload-time = "2026-01-20T16:00:29.272Z" }, + { url = "https://files.pythonhosted.org/packages/e0/12/b05ba554d2c623bffa59922b94b0775673de251f468a9609bc9e45de95e9/triton-3.6.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e8e323d608e3a9bfcc2d9efcc90ceefb764a82b99dea12a86d643c72539ad5d3", size = 188214640, upload-time = "2026-01-20T16:00:35.869Z" }, + { url = "https://files.pythonhosted.org/packages/ab/a8/cdf8b3e4c98132f965f88c2313a4b493266832ad47fb52f23d14d4f86bb5/triton-3.6.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74caf5e34b66d9f3a429af689c1c7128daba1d8208df60e81106b115c00d6fca", size = 188266850, upload-time = "2026-01-20T16:00:43.041Z" }, + { url = "https://files.pythonhosted.org/packages/f9/0b/37d991d8c130ce81a8728ae3c25b6e60935838e9be1b58791f5997b24a54/triton-3.6.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10c7f76c6e72d2ef08df639e3d0d30729112f47a56b0c81672edc05ee5116ac9", size = 188289450, upload-time = "2026-01-20T16:00:49.136Z" }, + { url = "https://files.pythonhosted.org/packages/35/f8/9c66bfc55361ec6d0e4040a0337fb5924ceb23de4648b8a81ae9d33b2b38/triton-3.6.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d002e07d7180fd65e622134fbd980c9a3d4211fb85224b56a0a0efbd422ab72f", size = 188400296, upload-time = "2026-01-20T16:00:56.042Z" }, + { url = "https://files.pythonhosted.org/packages/df/3d/9e7eee57b37c80cec63322c0231bb6da3cfe535a91d7a4d64896fcb89357/triton-3.6.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a17a5d5985f0ac494ed8a8e54568f092f7057ef60e1b0fa09d3fd1512064e803", size = 188273063, upload-time = "2026-01-20T16:01:07.278Z" }, + { url = "https://files.pythonhosted.org/packages/f6/56/6113c23ff46c00aae423333eb58b3e60bdfe9179d542781955a5e1514cb3/triton-3.6.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:46bd1c1af4b6704e554cad2eeb3b0a6513a980d470ccfa63189737340c7746a7", size = 188397994, upload-time = "2026-01-20T16:01:14.236Z" }, ] [[package]]