Equimo 0.4.6a4__tar.gz → 0.4.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. {equimo-0.4.6a4/src/Equimo.egg-info → equimo-0.4.7}/PKG-INFO +1 -1
  2. {equimo-0.4.6a4 → equimo-0.4.7}/pyproject.toml +1 -1
  3. {equimo-0.4.6a4 → equimo-0.4.7/src/Equimo.egg-info}/PKG-INFO +1 -1
  4. equimo-0.4.7/src/equimo/__init__.py +1 -0
  5. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/experimental/text.py +4 -4
  6. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/attention.py +3 -3
  7. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/convolution.py +17 -26
  8. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/sharing.py +6 -6
  9. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/fastervit.py +8 -7
  10. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/lowformer.py +5 -5
  11. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/mlla.py +6 -6
  12. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/partialformer.py +2 -2
  13. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/reduceformer.py +5 -5
  14. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/shvit.py +4 -4
  15. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/vit.py +8 -8
  16. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/vssd.py +7 -7
  17. equimo-0.4.6a4/src/equimo/__init__.py +0 -1
  18. {equimo-0.4.6a4 → equimo-0.4.7}/LICENSE.md +0 -0
  19. {equimo-0.4.6a4 → equimo-0.4.7}/README.md +0 -0
  20. {equimo-0.4.6a4 → equimo-0.4.7}/setup.cfg +0 -0
  21. {equimo-0.4.6a4 → equimo-0.4.7}/src/Equimo.egg-info/SOURCES.txt +0 -0
  22. {equimo-0.4.6a4 → equimo-0.4.7}/src/Equimo.egg-info/dependency_links.txt +0 -0
  23. {equimo-0.4.6a4 → equimo-0.4.7}/src/Equimo.egg-info/requires.txt +0 -0
  24. {equimo-0.4.6a4 → equimo-0.4.7}/src/Equimo.egg-info/top_level.txt +0 -0
  25. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/conversion/__init__.py +0 -0
  26. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/conversion/utils.py +0 -0
  27. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/experimental/__init__.py +0 -0
  28. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/io.py +0 -0
  29. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/__init__.py +0 -0
  30. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/activation.py +0 -0
  31. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/downsample.py +0 -0
  32. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/dropout.py +0 -0
  33. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/ffn.py +0 -0
  34. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/generic.py +0 -0
  35. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/mamba.py +0 -0
  36. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/norm.py +0 -0
  37. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/patch.py +0 -0
  38. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/posemb.py +0 -0
  39. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/squeeze_excite.py +0 -0
  40. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/layers/wavelet.py +0 -0
  41. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/__init__.py +0 -0
  42. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/models/emamodel.py +0 -0
  43. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/ops/scan.py +0 -0
  44. {equimo-0.4.6a4 → equimo-0.4.7}/src/equimo/utils.py +0 -0
  45. {equimo-0.4.6a4 → equimo-0.4.7}/tests/test_models.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Equimo
3
- Version: 0.4.6a4
3
+ Version: 0.4.7
4
4
  Summary: Implementation of popular vision models in Jax
5
5
  Classifier: Development Status :: 4 - Beta
6
6
  Classifier: Intended Audience :: Developers
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "Equimo"
3
- version = "0.4.6a4"
3
+ version = "0.4.7"
4
4
  description = "Implementation of popular vision models in Jax"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Equimo
3
- Version: 0.4.6a4
3
+ Version: 0.4.7
4
4
  Summary: Implementation of popular vision models in Jax
5
5
  Classifier: Development Status :: 4 - Beta
6
6
  Classifier: Intended Audience :: Developers
@@ -0,0 +1 @@
1
+ __version__ = "0.4.7"
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from typing import Callable, Optional, Sequence
2
+ from typing import Callable, Optional, Sequence, Tuple
3
3
  from urllib.parse import urlparse
4
4
 
5
5
  import equinox as eqx
@@ -136,7 +136,7 @@ class Transformer(eqx.Module):
136
136
  blocks: A list of `AttentionBlock` instances forming the transformer stack.
137
137
  """
138
138
 
139
- blocks: list[AttentionBlock]
139
+ blocks: Tuple[AttentionBlock, ...]
140
140
 
141
141
  def __init__(
142
142
  self,
@@ -164,7 +164,7 @@ class Transformer(eqx.Module):
164
164
 
165
165
  act_layer = get_act(act_layer)
166
166
 
167
- self.blocks = [
167
+ self.blocks = tuple(
168
168
  AttentionBlock(
169
169
  dim=dim,
170
170
  num_heads=num_heads,
@@ -173,7 +173,7 @@ class Transformer(eqx.Module):
173
173
  key=keys[i],
174
174
  )
175
175
  for i in range(depth)
176
- ]
176
+ )
177
177
 
178
178
  def __call__(
179
179
  self,
@@ -1671,7 +1671,7 @@ class RFAttention(eqx.Module):
1671
1671
  eps: float = eqx.field(static=True)
1672
1672
 
1673
1673
  qkv: eqx.nn.Conv2d
1674
- aggreg: list[eqx.nn.Conv2d]
1674
+ aggreg: Tuple[eqx.nn.Conv2d, ...]
1675
1675
  proj: SingleConvBlock
1676
1676
 
1677
1677
  def __init__(
@@ -1709,7 +1709,7 @@ class RFAttention(eqx.Module):
1709
1709
  use_bias=use_bias,
1710
1710
  key=key_qkv,
1711
1711
  )
1712
- self.aggreg = [
1712
+ self.aggreg = tuple(
1713
1713
  eqx.nn.Conv2d(
1714
1714
  in_channels=3 * total_dim,
1715
1715
  out_channels=3 * total_dim,
@@ -1720,7 +1720,7 @@ class RFAttention(eqx.Module):
1720
1720
  use_bias=use_bias,
1721
1721
  )
1722
1722
  for scale in scales
1723
- ]
1723
+ )
1724
1724
  # TODO: test different normalizations
1725
1725
  self.proj = SingleConvBlock(
1726
1726
  in_channels=self.total_dim,
@@ -409,7 +409,7 @@ class C2f(eqx.Module):
409
409
 
410
410
  conv1: SingleConvBlock
411
411
  conv2: SingleConvBlock
412
- blocks: list[ConvBottleneck]
412
+ blocks: Tuple[ConvBottleneck, ...]
413
413
 
414
414
  def __init__(
415
415
  self,
@@ -445,7 +445,7 @@ class C2f(eqx.Module):
445
445
  key=key_conv2,
446
446
  )
447
447
 
448
- self.blocks = [
448
+ self.blocks = tuple(
449
449
  ConvBottleneck(
450
450
  in_channels=self.hidden_channels,
451
451
  out_channels=self.hidden_channels,
@@ -456,7 +456,7 @@ class C2f(eqx.Module):
456
456
  key=key_blocks[i],
457
457
  )
458
458
  for i in range(n)
459
- ]
459
+ )
460
460
 
461
461
  def __call__(
462
462
  self,
@@ -589,7 +589,7 @@ class C3k2(eqx.Module):
589
589
 
590
590
  conv1: SingleConvBlock
591
591
  conv2: SingleConvBlock
592
- blocks: list[ConvBottleneck] | list[C3k]
592
+ blocks: Tuple[ConvBottleneck, ...] | Tuple[C3k, ...]
593
593
 
594
594
  def __init__(
595
595
  self,
@@ -627,7 +627,7 @@ class C3k2(eqx.Module):
627
627
  )
628
628
 
629
629
  if c3k:
630
- self.blocks = [
630
+ self.blocks = tuple(
631
631
  C3k(
632
632
  in_channels=self.hidden_channels,
633
633
  out_channels=self.hidden_channels,
@@ -637,9 +637,9 @@ class C3k2(eqx.Module):
637
637
  key=key_blocks[i],
638
638
  )
639
639
  for i in range(n)
640
- ]
640
+ )
641
641
  else:
642
- self.blocks = [
642
+ self.blocks = tuple(
643
643
  ConvBottleneck(
644
644
  in_channels=self.hidden_channels,
645
645
  out_channels=self.hidden_channels,
@@ -648,7 +648,7 @@ class C3k2(eqx.Module):
648
648
  key=key_blocks[i],
649
649
  )
650
650
  for i in range(n)
651
- ]
651
+ )
652
652
 
653
653
  def __call__(
654
654
  self,
@@ -1078,12 +1078,12 @@ class GenericGhostModule(eqx.Module):
1078
1078
  cheap_operation: eqx.nn.Conv2d
1079
1079
 
1080
1080
  # Training
1081
- primary_rpr_conv: list[eqx.nn.Conv2d]
1081
+ primary_rpr_conv: Tuple[eqx.nn.Conv2d, ...]
1082
1082
  primary_rpr_scale: eqx.nn.Conv2d | eqx.nn.Identity
1083
1083
  primary_shared_norm: eqx.nn.GroupNorm
1084
1084
  primary_activation: Callable
1085
1085
 
1086
- cheap_rpr_conv: list[eqx.nn.Conv2d]
1086
+ cheap_rpr_conv: Tuple[eqx.nn.Conv2d, ...]
1087
1087
  cheap_rpr_scale: eqx.nn.Conv2d | eqx.nn.Identity
1088
1088
  cheap_shared_norm: eqx.nn.GroupNorm
1089
1089
  cheap_activation: Callable
@@ -1156,7 +1156,7 @@ class GenericGhostModule(eqx.Module):
1156
1156
 
1157
1157
  # Primary training branches
1158
1158
  init_num_groups = nearest_power_of_2_divisor(init_channels, 32)
1159
- self.primary_rpr_conv = [
1159
+ self.primary_rpr_conv = tuple(
1160
1160
  eqx.nn.Conv2d(
1161
1161
  in_channels=in_channels,
1162
1162
  out_channels=init_channels,
@@ -1167,7 +1167,7 @@ class GenericGhostModule(eqx.Module):
1167
1167
  key=key_ps[i],
1168
1168
  )
1169
1169
  for i in range(num_conv_branches)
1170
- ]
1170
+ )
1171
1171
  self.primary_rpr_scale = (
1172
1172
  eqx.nn.Conv2d(
1173
1173
  in_channels=in_channels,
@@ -1186,7 +1186,7 @@ class GenericGhostModule(eqx.Module):
1186
1186
 
1187
1187
  # Cheap training branches (depthwise)
1188
1188
  newchannels_num_groups = nearest_power_of_2_divisor(new_channels, 32)
1189
- self.cheap_rpr_conv = [
1189
+ self.cheap_rpr_conv = tuple(
1190
1190
  eqx.nn.Conv2d(
1191
1191
  in_channels=init_channels,
1192
1192
  out_channels=new_channels,
@@ -1198,7 +1198,7 @@ class GenericGhostModule(eqx.Module):
1198
1198
  key=key_cs[i],
1199
1199
  )
1200
1200
  for i in range(self.num_conv_branches)
1201
- ]
1201
+ )
1202
1202
  self.cheap_rpr_scale = (
1203
1203
  eqx.nn.Conv2d(
1204
1204
  in_channels=init_channels,
@@ -1344,7 +1344,7 @@ class GhostBottleneck(eqx.Module):
1344
1344
  ghost2: "GenericGhostModule"
1345
1345
 
1346
1346
  dw_conv: eqx.nn.Conv2d | eqx.nn.Identity
1347
- dw_rpr_conv: list[eqx.nn.Conv2d] # depthwise conv branches (no bias)
1347
+ dw_rpr_conv: Tuple[eqx.nn.Conv2d, ...] # depthwise conv branches (no bias)
1348
1348
  dw_rpr_scale: eqx.nn.Conv2d | eqx.nn.Identity # optional 1x1 depthwise (no bias)
1349
1349
  dw_shared_norm: eqx.nn.GroupNorm | eqx.nn.Identity
1350
1350
 
@@ -1393,7 +1393,7 @@ class GhostBottleneck(eqx.Module):
1393
1393
  # Depthwise stage (only if stride > 1)
1394
1394
  if stride > 1:
1395
1395
  # Training-time branches (depthwise, no bias); no activation; shared GN after sum
1396
- self.dw_rpr_conv = [
1396
+ self.dw_rpr_conv = tuple(
1397
1397
  eqx.nn.Conv2d(
1398
1398
  in_channels=mid_channels,
1399
1399
  out_channels=mid_channels,
@@ -1405,7 +1405,7 @@ class GhostBottleneck(eqx.Module):
1405
1405
  key=k_dw_list[i],
1406
1406
  )
1407
1407
  for i in range(3)
1408
- ]
1408
+ )
1409
1409
  # Optional scale branch (1x1, depthwise, stride=stride)
1410
1410
  self.dw_rpr_scale = (
1411
1411
  eqx.nn.Conv2d(
@@ -1543,15 +1543,6 @@ class GhostBottleneck(eqx.Module):
1543
1543
  return x
1544
1544
 
1545
1545
 
1546
- key = jr.PRNGKey(42)
1547
- x = jr.normal(key, (64, 16, 16))
1548
- f = GhostBottleneck(64, 128, 64, se_ratio=0.25, key=key)
1549
- x1 = f.ghost1(x, key=key)
1550
- x2 = f.se(x1)
1551
- x3 = f.ghost2(x2, key=key)
1552
- print(x2.shape)
1553
-
1554
-
1555
1546
  def _pad_kernel_to_target(kernel: Array, target_size: tuple[int, int]) -> Array:
1556
1547
  kh, kw = kernel.shape[-2], kernel.shape[-1]
1557
1548
  th, tw = target_size
@@ -1,5 +1,5 @@
1
1
  import math
2
- from typing import List, Optional
2
+ from typing import List, Optional, Tuple
3
3
 
4
4
  import equinox as eqx
5
5
  import jax
@@ -72,8 +72,8 @@ class LayerSharing(eqx.Module):
72
72
 
73
73
  repeat: int = eqx.field(static=True)
74
74
 
75
- loras: List[LoRA]
76
- dropouts: List[eqx.nn.Dropout]
75
+ loras: Tuple[LoRA, ...]
76
+ dropouts: Tuple[eqx.nn.Dropout, ...]
77
77
  f: eqx.Module
78
78
 
79
79
  def __init__(
@@ -93,8 +93,8 @@ class LayerSharing(eqx.Module):
93
93
  keys = jr.split(key, repeat)
94
94
  self.repeat = repeat
95
95
 
96
- self.dropouts = [eqx.nn.Dropout(drop_rate) for i in range(self.repeat)]
97
- self.loras = [
96
+ self.dropouts = tuple(eqx.nn.Dropout(drop_rate) for i in range(self.repeat))
97
+ self.loras = tuple(
98
98
  LoRA(
99
99
  in_features=dim,
100
100
  out_features=dim,
@@ -103,7 +103,7 @@ class LayerSharing(eqx.Module):
103
103
  key=keys[i],
104
104
  )
105
105
  for i in range(self.repeat)
106
- ]
106
+ )
107
107
 
108
108
  self.f = f
109
109
 
@@ -1,4 +1,4 @@
1
- from typing import Callable, List, Literal, Optional
1
+ from typing import Callable, List, Literal, Optional, Tuple
2
2
 
3
3
  import equinox as eqx
4
4
  import jax
@@ -157,7 +157,7 @@ class BlockChunk(eqx.Module):
157
157
  window_size: bool = eqx.field(static=True)
158
158
  do_gt: bool = eqx.field(static=True)
159
159
 
160
- blocks: List[eqx.Module]
160
+ blocks: Tuple[eqx.Module, ...]
161
161
  downsample: eqx.Module
162
162
  global_tokenizer: Optional[TokenInitializer]
163
163
 
@@ -195,7 +195,7 @@ class BlockChunk(eqx.Module):
195
195
  k for k, v in kwargs.items() if isinstance(v, list) and len(v) == depth
196
196
  ]
197
197
 
198
- self.blocks = []
198
+ blocks = []
199
199
  for i in range(depth):
200
200
  config = kwargs | {k: kwargs[k][i] for k in keys_to_spread}
201
201
 
@@ -210,7 +210,7 @@ class BlockChunk(eqx.Module):
210
210
  }
211
211
 
212
212
  wrapper = LayerSharingWithCT if self.is_hat else LayerSharing
213
- self.blocks.append(
213
+ blocks.append(
214
214
  wrapper(
215
215
  dim=kwargs.get("dim"),
216
216
  f=block(**config, key=block_subkeys[i]),
@@ -218,6 +218,7 @@ class BlockChunk(eqx.Module):
218
218
  key=block_subkeys[i],
219
219
  ),
220
220
  )
221
+ self.blocks = tuple(blocks)
221
222
 
222
223
  self.downsample = downsampler(dim=kwargs.get("dim"), key=key_ds)
223
224
 
@@ -331,7 +332,7 @@ class FasterViT(eqx.Module):
331
332
  """
332
333
 
333
334
  patch_embed: ConvPatchEmbed
334
- blocks: List[eqx.Module]
335
+ blocks: Tuple[eqx.Module, ...]
335
336
  norm: eqx.Module
336
337
  head: eqx.Module
337
338
 
@@ -398,7 +399,7 @@ class FasterViT(eqx.Module):
398
399
  hat = to_list(hat, n_chunks)
399
400
  attn_layer = to_list(attn_layer, n_chunks)
400
401
  window_size = to_list(window_size, n_chunks)
401
- self.blocks = [
402
+ self.blocks = tuple(
402
403
  BlockChunk(
403
404
  block=ConvBlock if i < 2 else HATBlock,
404
405
  repeat=repeat,
@@ -427,7 +428,7 @@ class FasterViT(eqx.Module):
427
428
  key=block_subkeys[i],
428
429
  )
429
430
  for i, depth in enumerate(depths)
430
- ]
431
+ )
431
432
 
432
433
  num_features = int(dim * 2 ** (len(depths) - 1))
433
434
  self.norm = norm_layer(num_features)
@@ -15,7 +15,7 @@ from equimo.layers.norm import get_norm
15
15
 
16
16
  class BlockChunk(eqx.Module):
17
17
  residuals: list[bool] = eqx.field(static=True)
18
- blocks: list[DSConv | MBConv | LowFormerBlock]
18
+ blocks: Tuple[DSConv | MBConv | LowFormerBlock, ...]
19
19
 
20
20
  def __init__(
21
21
  self,
@@ -123,7 +123,7 @@ class BlockChunk(eqx.Module):
123
123
  )
124
124
  residuals.append(False)
125
125
 
126
- self.blocks = blocks
126
+ self.blocks = tuple(blocks)
127
127
  self.residuals = residuals
128
128
 
129
129
  def __call__(
@@ -146,7 +146,7 @@ class BlockChunk(eqx.Module):
146
146
 
147
147
  class LowFormer(eqx.Module):
148
148
  input_stem: eqx.nn.Sequential
149
- blocks: list[BlockChunk]
149
+ blocks: Tuple[BlockChunk, ...]
150
150
  head: eqx.nn.Linear | eqx.nn.Identity
151
151
 
152
152
  def __init__(
@@ -220,7 +220,7 @@ class LowFormer(eqx.Module):
220
220
  ]
221
221
  )
222
222
 
223
- self.blocks = [
223
+ self.blocks = tuple(
224
224
  BlockChunk(
225
225
  in_channels=widths[i - 1] if i > 0 else width_stem,
226
226
  out_channels=widths[i],
@@ -241,7 +241,7 @@ class LowFormer(eqx.Module):
241
241
  for i, (depth, att_stride, block_type, key_block) in enumerate(
242
242
  zip(depths, att_strides, block_types, key_blocks)
243
243
  )
244
- ]
244
+ )
245
245
 
246
246
  self.head = (
247
247
  eqx.nn.Linear(
@@ -1,4 +1,4 @@
1
- from typing import List, Optional
1
+ from typing import List, Optional, Tuple
2
2
 
3
3
  import equinox as eqx
4
4
  import jax
@@ -38,7 +38,7 @@ class Mlla(eqx.Module):
38
38
 
39
39
  patch_embed: eqx.Module
40
40
  pos_drop: eqx.Module
41
- blocks: List[eqx.Module]
41
+ blocks: Tuple[eqx.Module, ...]
42
42
  head: eqx.Module
43
43
 
44
44
  def __init__(
@@ -52,7 +52,7 @@ class Mlla(eqx.Module):
52
52
  patch_size: int = 4,
53
53
  depths: List[int] = [2, 2, 6, 2],
54
54
  num_heads: List[int] = [3, 6, 12, 24],
55
- attentions_layers: List[eqx.Module] | eqx.Module = LinearAttention,
55
+ attentions_layers: Tuple[eqx.Module, ...] | eqx.Module = LinearAttention,
56
56
  drop_rate: float = 0.0,
57
57
  drop_path_rate: float = 0.0,
58
58
  drop_path_uniform: bool = False,
@@ -101,8 +101,8 @@ class Mlla(eqx.Module):
101
101
  )
102
102
 
103
103
  num_heads = to_list(num_heads, n_chunks)
104
- attentions_layers = to_list(attentions_layers, n_chunks)
105
- self.blocks = [
104
+ attentions_layers = tuple(to_list(attentions_layers, n_chunks))
105
+ self.blocks = tuple(
106
106
  BlockChunk(
107
107
  block=MllaBlock,
108
108
  repeat=repeat,
@@ -124,7 +124,7 @@ class Mlla(eqx.Module):
124
124
  key=block_subkeys[i],
125
125
  )
126
126
  for i, depth in enumerate(depths)
127
- ]
127
+ )
128
128
 
129
129
  self.norm = eqx.nn.LayerNorm(self.num_features)
130
130
  self.head = (
@@ -98,7 +98,7 @@ class BlockChunk(eqx.Module):
98
98
  downsampler_contains_dropout: bool = eqx.field(static=True)
99
99
 
100
100
  posemb: eqx.Module
101
- blocks: List[eqx.Module]
101
+ blocks: Tuple[eqx.Module, ...]
102
102
  downsample: eqx.Module
103
103
  qa_proj: eqx.Module
104
104
  qa_drop: eqx.Module
@@ -247,7 +247,7 @@ class PartialFormer(eqx.Module):
247
247
  qa_token: jnp.ndarray
248
248
  patch_embed: Stem
249
249
  pos_drop: eqx.nn.Dropout
250
- blocks: List[eqx.Module]
250
+ blocks: Tuple[eqx.Module, ...]
251
251
  norm: eqx.Module
252
252
  head: eqx.Module
253
253
 
@@ -14,7 +14,7 @@ from equimo.layers.norm import get_norm
14
14
 
15
15
 
16
16
  class BlockChunk(eqx.Module):
17
- blocks: list[DSConv | MBConv | RFAttentionBlock]
17
+ blocks: Tuple[DSConv | MBConv | RFAttentionBlock, ...]
18
18
 
19
19
  def __init__(
20
20
  self,
@@ -126,7 +126,7 @@ class BlockChunk(eqx.Module):
126
126
  )
127
127
  )
128
128
 
129
- self.blocks = blocks
129
+ self.blocks = tuple(blocks)
130
130
 
131
131
  def __call__(
132
132
  self,
@@ -148,7 +148,7 @@ class BlockChunk(eqx.Module):
148
148
  class ReduceFormer(eqx.Module):
149
149
  conv_stem: SingleConvBlock
150
150
  block_stem: BlockChunk
151
- blocks: list[BlockChunk]
151
+ blocks: Tuple[BlockChunk, ...]
152
152
  head: eqx.nn.Linear | eqx.nn.Identity
153
153
 
154
154
  def __init__(
@@ -220,7 +220,7 @@ class ReduceFormer(eqx.Module):
220
220
  key=key_block_stem,
221
221
  )
222
222
 
223
- self.blocks = [
223
+ self.blocks = tuple(
224
224
  BlockChunk(
225
225
  in_channels=widths[i - 1] if i > 0 else width_stem,
226
226
  out_channels=widths[i],
@@ -240,7 +240,7 @@ class ReduceFormer(eqx.Module):
240
240
  for i, (depth, block_type, key_block) in enumerate(
241
241
  zip(depths, block_types, key_blocks)
242
242
  )
243
- ]
243
+ )
244
244
 
245
245
  self.head = (
246
246
  eqx.nn.Linear(
@@ -1,4 +1,4 @@
1
- from typing import List, Optional
1
+ from typing import List, Optional, Tuple
2
2
 
3
3
  import equinox as eqx
4
4
  import jax
@@ -240,7 +240,7 @@ class SHViT(eqx.Module):
240
240
  """
241
241
 
242
242
  patch_embed: eqx.nn.Sequential
243
- blocks: List[eqx.Module]
243
+ blocks: Tuple[eqx.Module, ...]
244
244
  head: eqx.Module
245
245
 
246
246
  def __init__(
@@ -316,7 +316,7 @@ class SHViT(eqx.Module):
316
316
  qk_dims = to_list(qk_dim, n_chunks)
317
317
  pdims = to_list(pdim, n_chunks)
318
318
  block_types = to_list(block_type, n_chunks)
319
- self.blocks = [
319
+ self.blocks = tuple(
320
320
  BlockChunk(
321
321
  block=BasicBlock,
322
322
  repeat=repeat,
@@ -334,7 +334,7 @@ class SHViT(eqx.Module):
334
334
  key=block_subkeys[i],
335
335
  )
336
336
  for i, depth in enumerate(depths)
337
- ]
337
+ )
338
338
 
339
339
  self.norm = eqx.nn.LayerNorm(dims[-1])
340
340
  self.head = (
@@ -1,4 +1,4 @@
1
- from typing import Callable, List, Literal, Optional
1
+ from typing import Callable, Literal, Optional, Tuple
2
2
 
3
3
  import equinox as eqx
4
4
  import jax
@@ -39,7 +39,7 @@ class BlockChunk(eqx.Module):
39
39
  downsampler_contains_dropout: bool = eqx.field(static=True)
40
40
 
41
41
  posemb: eqx.Module
42
- blocks: List[eqx.Module]
42
+ blocks: Tuple[eqx.Module]
43
43
  downsample: eqx.Module
44
44
 
45
45
  def __init__(
@@ -84,7 +84,7 @@ class BlockChunk(eqx.Module):
84
84
  for i in range(depth):
85
85
  config = kwargs | {k: kwargs[k][i] for k in keys_to_spread}
86
86
  blocks.append(block(**config, key=block_subkeys[i]))
87
- self.blocks = blocks
87
+ self.blocks = tuple(blocks)
88
88
 
89
89
  self.downsample = downsampler(dim=dim, **downsampler_kwargs, key=key_ds)
90
90
 
@@ -145,7 +145,7 @@ class VisionTransformer(eqx.Module):
145
145
  cls_token: jax.Array | None
146
146
  reg_tokens: jax.Array | None
147
147
  mask_token: jax.Array | None
148
- blocks: List[eqx.Module]
148
+ blocks: Tuple[eqx.Module, ...]
149
149
  pos_drop: eqx.nn.Dropout
150
150
  norm: eqx.Module
151
151
  local_cls_norm: eqx.Module | None
@@ -171,8 +171,8 @@ class VisionTransformer(eqx.Module):
171
171
  in_channels: int,
172
172
  dim: int,
173
173
  patch_size: int,
174
- num_heads: int | List[int],
175
- depths: List[int],
174
+ num_heads: int | list[int],
175
+ depths: list[int],
176
176
  *,
177
177
  key: PRNGKeyArray,
178
178
  use_mask_token: bool = False,
@@ -304,7 +304,7 @@ class VisionTransformer(eqx.Module):
304
304
  dims = to_list(dim, n_chunks)
305
305
  num_heads = to_list(num_heads, n_chunks)
306
306
  attn_layer = to_list(attn_layer, n_chunks)
307
- self.blocks = [
307
+ self.blocks = tuple(
308
308
  BlockChunk(
309
309
  block=block,
310
310
  dim=dims[i],
@@ -328,7 +328,7 @@ class VisionTransformer(eqx.Module):
328
328
  key=block_subkeys[i],
329
329
  )
330
330
  for i, depth in enumerate(depths)
331
- ]
331
+ )
332
332
 
333
333
  self.norm = norm_layer(dim, eps=eps)
334
334
 
@@ -1,4 +1,4 @@
1
- from typing import List, Optional
1
+ from typing import List, Optional, Tuple
2
2
 
3
3
  import equinox as eqx
4
4
  import jax
@@ -43,7 +43,7 @@ class Vssd(eqx.Module):
43
43
 
44
44
  patch_embed: eqx.Module
45
45
  pos_drop: eqx.Module
46
- blocks: List[eqx.Module]
46
+ blocks: Tuple[eqx.Module, ...]
47
47
  head: eqx.Module
48
48
 
49
49
  def __init__(
@@ -60,12 +60,12 @@ class Vssd(eqx.Module):
60
60
  patch_size: int = 4,
61
61
  depths: List[int] = [2, 4, 12, 4],
62
62
  num_heads: List[int] = [2, 4, 8, 16],
63
- attentions_layers: List[eqx.Module] | eqx.Module = [
63
+ attentions_layers: Tuple[eqx.Module, ...] | eqx.Module = (
64
64
  Mamba2Mixer,
65
65
  Mamba2Mixer,
66
66
  Mamba2Mixer,
67
67
  Attention,
68
- ],
68
+ ),
69
69
  drop_rate: float = 0.0,
70
70
  drop_path_rate: float = 0.0,
71
71
  drop_path_uniform: bool = False,
@@ -118,8 +118,8 @@ class Vssd(eqx.Module):
118
118
  )
119
119
 
120
120
  num_heads = to_list(num_heads, n_chunks)
121
- attentions_layers = to_list(attentions_layers, n_chunks)
122
- self.blocks = [
121
+ attentions_layers = tuple(to_list(attentions_layers, n_chunks))
122
+ self.blocks = tuple(
123
123
  BlockChunk(
124
124
  block=MllaBlock,
125
125
  repeat=repeat,
@@ -142,7 +142,7 @@ class Vssd(eqx.Module):
142
142
  key=block_subkeys[i],
143
143
  )
144
144
  for i, depth in enumerate(depths)
145
- ]
145
+ )
146
146
 
147
147
  self.norm = eqx.nn.LayerNorm(self.num_features)
148
148
  self.head = (
@@ -1 +0,0 @@
1
- __version__ = "0.4.6a4"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes