Equimo 2.4.0__tar.gz → 2.5.1__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.
- {equimo-2.4.0 → equimo-2.5.1}/CHANGELOG.md +32 -0
- {equimo-2.4.0 → equimo-2.5.1}/PKG-INFO +1 -1
- {equimo-2.4.0 → equimo-2.5.1}/pyproject.toml +1 -1
- equimo-2.5.1/src/equimo/__init__.py +1 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/audio/models/ast.py +5 -5
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/_prng.py +5 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/language/models.py +5 -5
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/models/tabpfn.py +4 -4
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/models/t0.py +2 -2
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/_features.py +6 -7
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/attnet.py +3 -3
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/deq.py +5 -5
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/eomt.py +13 -1
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/fastervit.py +3 -3
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/lowformer.py +3 -3
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/mobilenet.py +3 -3
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/parcae.py +35 -26
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/partialformer.py +5 -5
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/reduceformer.py +4 -4
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/shvit.py +3 -3
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/vit.py +5 -5
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/query_training/_assignment.py +10 -8
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/query_training/_loss.py +4 -2
- equimo-2.4.0/src/equimo/__init__.py +0 -1
- {equimo-2.4.0 → equimo-2.5.1}/LICENSE.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/Apache-2.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/README.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/ast-BSD-3-Clause.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/convnext-Apache-2.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/convnextv2-CC-BY-NC-4.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/dinov2-Apache-2.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/dinov3-License.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/eupe-FAIR-Noncommercial-Research-License.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/lingbot-vision-Apache-2.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/siglip2-Apache-2.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/t0-alpha-Apache-2.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/tabpfn-3-License-v1.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/pretrained/tips-CC-BY-4.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/LICENSES/tfc-t0-APACHE-2.0.txt +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/NOTICE +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/README.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/docs/licensing/t0-source-provenance.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/docs/migration-v2.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/docs/stability.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/docs/timeseries.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/models/huggingface/NOTICE +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/models/huggingface/README.md +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/models/huggingface/convnext-conversion.json +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/_checkpoint_limits.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/_io.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/_pretrained.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/audio/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/audio/io.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/audio/layers/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/audio/layers/patch.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/audio/models/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/catalog.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/conversion/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/conversion/utils.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/emamodel.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/factory.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/implicit/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/implicit/_base.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/implicit/deq.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/implicit/injectors.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/implicit/stabilizers.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/implicit/strategies.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/intermediates.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/_registry.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/activation.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/attention.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/dropout.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/ffn.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/generic.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/mamba.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/norm.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/layers/rotary.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/ops/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/core/ops/scan.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/_blocks.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/_serialization_codecs.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/_typing.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/audio/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/audio/recipes.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/audio/selectors.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/calibration.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/config.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/continued_ssl.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/feature_extraction.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/heads.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/inspection.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/labels.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/language/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/language/recipes.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/language/selectors.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/masks.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/merging.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/paths.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/_common.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/_compat.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/adapters.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/base.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/bitfit.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/dora.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/ia3.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/lora.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/prefix.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/prompts.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/scale_shift.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/peft/vera.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/pooling.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/recipes.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/regularization.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/selectors.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/serialization.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/surgery.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/tags.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/vision/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/vision/dense.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/vision/eomt.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/finetune/vision/pmt.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/language/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/language/tokenizers.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/registry.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/serialization.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/layers/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/layers/attention.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/layers/blocks.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/layers/decoder.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/layers/mlp.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/layers/preprocessing.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/layers/registry.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/tabular/models/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/layers/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/layers/axis_attn.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/layers/blocks.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/layers/patch_encoder.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/layers/registry.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/layers/residual_mlp.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/timeseries/models/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/utils.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/_encoder_identity.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/io.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/attention.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/convolution.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/downsample.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/patch.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/posemb.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/registry.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/squeeze_excite.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/layers/wavelet.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/_embedding.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/convnext.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/iformer.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/mlla.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/pmd.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/pmt.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/models/vssd.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/pmt_checkpoint.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/query_training/__init__.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/query_training/_sampling.py +0 -0
- {equimo-2.4.0 → equimo-2.5.1}/src/equimo/vision/segmentation.py +0 -0
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to Equimo are documented here. Equimo follows Semantic Versioning from version 2.0.0 onward.
|
|
4
4
|
|
|
5
|
+
## [2.5.1] - 2026-10-16
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- The EoMT and PMT mask-head `ScaleBlock` computes its 2 × 2, stride-2 transposed convolution as a matmul followed by
|
|
10
|
+
depth-to-space. This avoids an untuned cuDNN fallback for the bfloat16 weight gradient that made GPU training steps
|
|
11
|
+
several times slower at batch sizes of 12 and above. Parameters and checkpoints are unchanged; outputs match the
|
|
12
|
+
previous implementation within floating-point rounding.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- `match_queries` and the query-segmentation losses no longer rely on dropping out-of-range scatter updates. Under
|
|
17
|
+
`vmap` with `--xla_gpu_deterministic_ops` or `--xla_gpu_exclude_nondeterministic_ops`, jaxlib 0.11.2 and earlier write
|
|
18
|
+
such updates into the next batch row (openxla/xla#49380), which silently produced non-optimal query assignments and
|
|
19
|
+
wrong classification targets.
|
|
20
|
+
|
|
21
|
+
## [2.5.0] - 2026-10-15
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
|
|
25
|
+
- Model forward and feature endpoints default `key` to `None` instead of a fixed `jax.random.PRNGKey(42)`. Deterministic
|
|
26
|
+
inference (`inference=True`) needs no key; a stochastic forward pass without a key raises a `ValueError` instead of
|
|
27
|
+
silently reusing the same randomness on every call.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- `extract_features`, `DenseProbe`, and the other fine-tuning wrappers no longer fail with their default `key=None` on
|
|
32
|
+
ViT-family models (including DINOv2, DINOv3, SigLIP2, EUPE, and LingBot-Vision), VisionParcae, MobileNetV3, AST, the
|
|
33
|
+
text encoder, TabPFN, and T0, whose feature endpoints required a PRNG key even in inference mode.
|
|
34
|
+
- VisionParcae with `state_init="zero"` runs deterministic inference without a key. Key-dependent configurations,
|
|
35
|
+
including the default `state_init="like-init"`, raise an actionable error when the key is missing.
|
|
36
|
+
|
|
5
37
|
## [2.4.0] - 2026-09-24
|
|
6
38
|
|
|
7
39
|
### Added
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.5.1"
|
|
@@ -190,7 +190,7 @@ class AudioSpectrogramTransformer(eqx.Module):
|
|
|
190
190
|
def features(
|
|
191
191
|
self,
|
|
192
192
|
x: Float[Array, "time frequency"],
|
|
193
|
-
key: PRNGKeyArray,
|
|
193
|
+
key: PRNGKeyArray | None = None,
|
|
194
194
|
inference: Optional[bool] = None,
|
|
195
195
|
**kwargs,
|
|
196
196
|
) -> Float[Array, "seqlen dim"]:
|
|
@@ -207,7 +207,7 @@ class AudioSpectrogramTransformer(eqx.Module):
|
|
|
207
207
|
def intermediate_features(
|
|
208
208
|
self,
|
|
209
209
|
x: Float[Array, "time frequency"],
|
|
210
|
-
key: PRNGKeyArray,
|
|
210
|
+
key: PRNGKeyArray | None = None,
|
|
211
211
|
inference: Optional[bool] = None,
|
|
212
212
|
indices: Sequence[int] | None = None,
|
|
213
213
|
n_last_blocks: int | None = None,
|
|
@@ -251,7 +251,7 @@ class AudioSpectrogramTransformer(eqx.Module):
|
|
|
251
251
|
self,
|
|
252
252
|
x: Float[Array, "time frequency"],
|
|
253
253
|
*,
|
|
254
|
-
key: PRNGKeyArray,
|
|
254
|
+
key: PRNGKeyArray | None,
|
|
255
255
|
inference: Optional[bool],
|
|
256
256
|
) -> Float[Array, "seqlen dim"]:
|
|
257
257
|
x = self.patch_embed(x)
|
|
@@ -266,7 +266,7 @@ class AudioSpectrogramTransformer(eqx.Module):
|
|
|
266
266
|
def forward_features(
|
|
267
267
|
self,
|
|
268
268
|
x: Float[Array, "time frequency"],
|
|
269
|
-
key: PRNGKeyArray,
|
|
269
|
+
key: PRNGKeyArray | None = None,
|
|
270
270
|
inference: Optional[bool] = None,
|
|
271
271
|
**kwargs,
|
|
272
272
|
) -> dict:
|
|
@@ -283,7 +283,7 @@ class AudioSpectrogramTransformer(eqx.Module):
|
|
|
283
283
|
def __call__(
|
|
284
284
|
self,
|
|
285
285
|
x: Float[Array, "time frequency"],
|
|
286
|
-
key: PRNGKeyArray =
|
|
286
|
+
key: PRNGKeyArray | None = None,
|
|
287
287
|
inference: Optional[bool] = None,
|
|
288
288
|
**kwargs,
|
|
289
289
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
@@ -10,6 +10,11 @@ def split_for_mode(key: Any, num: int = 2, *, inference: bool | None) -> tuple:
|
|
|
10
10
|
|
|
11
11
|
if inference is True:
|
|
12
12
|
return (key,) * num
|
|
13
|
+
if key is None:
|
|
14
|
+
raise ValueError(
|
|
15
|
+
"A PRNG key is required for stochastic forward passes; pass key=... "
|
|
16
|
+
"or run with inference=True."
|
|
17
|
+
)
|
|
13
18
|
return tuple(jr.split(key, num))
|
|
14
19
|
|
|
15
20
|
|
|
@@ -68,7 +68,7 @@ class TransformerEncoderStack(eqx.Module):
|
|
|
68
68
|
def __call__(
|
|
69
69
|
self,
|
|
70
70
|
x: Float[Array, "seqlen dim"],
|
|
71
|
-
key: PRNGKeyArray,
|
|
71
|
+
key: PRNGKeyArray | None = None,
|
|
72
72
|
inference: Optional[bool] = None,
|
|
73
73
|
mask: Optional[Float[Array, ""]] = None,
|
|
74
74
|
*,
|
|
@@ -90,7 +90,7 @@ class TransformerEncoderStack(eqx.Module):
|
|
|
90
90
|
def intermediate_features(
|
|
91
91
|
self,
|
|
92
92
|
x: Float[Array, "seqlen dim"],
|
|
93
|
-
key: PRNGKeyArray,
|
|
93
|
+
key: PRNGKeyArray | None = None,
|
|
94
94
|
inference: Optional[bool] = None,
|
|
95
95
|
mask: Optional[Float[Array, ""]] = None,
|
|
96
96
|
indices: Sequence[int] | None = None,
|
|
@@ -209,7 +209,7 @@ class TextTransformerEncoder(eqx.Module):
|
|
|
209
209
|
self,
|
|
210
210
|
ids: Int[Array, "seqlen"], # noqa: F821
|
|
211
211
|
padding_mask: Float[Array, "seqlen"], # noqa: F821
|
|
212
|
-
key: PRNGKeyArray,
|
|
212
|
+
key: PRNGKeyArray | None = None,
|
|
213
213
|
inference: Optional[bool] = None,
|
|
214
214
|
) -> Float[Array, "seqlen dim"]:
|
|
215
215
|
x, valid_mask = self._prepare_tokens(ids, padding_mask)
|
|
@@ -226,7 +226,7 @@ class TextTransformerEncoder(eqx.Module):
|
|
|
226
226
|
self,
|
|
227
227
|
ids: Int[Array, "seqlen"], # noqa: F821
|
|
228
228
|
padding_mask: Float[Array, "seqlen"], # noqa: F821
|
|
229
|
-
key: PRNGKeyArray,
|
|
229
|
+
key: PRNGKeyArray | None = None,
|
|
230
230
|
inference: Optional[bool] = None,
|
|
231
231
|
indices: Sequence[int] | None = None,
|
|
232
232
|
n_last_blocks: int | None = None,
|
|
@@ -248,7 +248,7 @@ class TextTransformerEncoder(eqx.Module):
|
|
|
248
248
|
self,
|
|
249
249
|
ids: Int[Array, "seqlen"], # noqa: F821
|
|
250
250
|
padding_mask: Float[Array, "seqlen"], # noqa: F821
|
|
251
|
-
key: PRNGKeyArray,
|
|
251
|
+
key: PRNGKeyArray | None = None,
|
|
252
252
|
inference: Optional[bool] = None,
|
|
253
253
|
) -> Float[Array, "dim"]:
|
|
254
254
|
x = self.features(ids, padding_mask, key=key, inference=inference)
|
|
@@ -217,7 +217,7 @@ class TabPFN(eqx.Module):
|
|
|
217
217
|
x: Float[Array, "rows columns"],
|
|
218
218
|
y: Array,
|
|
219
219
|
n_train: int,
|
|
220
|
-
key: PRNGKeyArray,
|
|
220
|
+
key: PRNGKeyArray | None = None,
|
|
221
221
|
inference: Optional[bool] = None,
|
|
222
222
|
**kwargs,
|
|
223
223
|
) -> Float[Array, "rows dim"]:
|
|
@@ -256,7 +256,7 @@ class TabPFN(eqx.Module):
|
|
|
256
256
|
x: Float[Array, "rows columns"],
|
|
257
257
|
y: Array,
|
|
258
258
|
n_train: int,
|
|
259
|
-
key: PRNGKeyArray,
|
|
259
|
+
key: PRNGKeyArray | None = None,
|
|
260
260
|
inference: Optional[bool] = None,
|
|
261
261
|
indices: Sequence[int] | None = None,
|
|
262
262
|
n_last_blocks: int | None = None,
|
|
@@ -322,7 +322,7 @@ class TabPFN(eqx.Module):
|
|
|
322
322
|
x: Float[Array, "rows columns"],
|
|
323
323
|
y: Array,
|
|
324
324
|
n_train: int,
|
|
325
|
-
key: PRNGKeyArray,
|
|
325
|
+
key: PRNGKeyArray | None = None,
|
|
326
326
|
inference: Optional[bool] = None,
|
|
327
327
|
**kwargs,
|
|
328
328
|
) -> dict:
|
|
@@ -339,7 +339,7 @@ class TabPFN(eqx.Module):
|
|
|
339
339
|
x: Float[Array, "rows columns"],
|
|
340
340
|
y: Array,
|
|
341
341
|
n_train: int,
|
|
342
|
-
key: PRNGKeyArray =
|
|
342
|
+
key: PRNGKeyArray | None = None,
|
|
343
343
|
inference: Optional[bool] = None,
|
|
344
344
|
**kwargs,
|
|
345
345
|
) -> Float[Array, "test classes"]:
|
|
@@ -474,7 +474,7 @@ class T0(eqx.Module):
|
|
|
474
474
|
group_ids: Int[Array, "variates time"],
|
|
475
475
|
variate_type: Int[Array, "variates time"],
|
|
476
476
|
*,
|
|
477
|
-
key: PRNGKeyArray,
|
|
477
|
+
key: PRNGKeyArray | None = None,
|
|
478
478
|
inference: Optional[bool] = None,
|
|
479
479
|
) -> Float[Array, "tokens embed_dim"]:
|
|
480
480
|
"""Return post-normalization latent tokens before quantile decoding.
|
|
@@ -503,7 +503,7 @@ class T0(eqx.Module):
|
|
|
503
503
|
group_ids: Int[Array, "variates time"],
|
|
504
504
|
variate_type: Int[Array, "variates time"],
|
|
505
505
|
*,
|
|
506
|
-
key: PRNGKeyArray =
|
|
506
|
+
key: PRNGKeyArray | None = None,
|
|
507
507
|
inference: Optional[bool] = None,
|
|
508
508
|
) -> Float[Array, "variates patches patch_size quantiles"]:
|
|
509
509
|
key_encoder, key_blocks, key_decoder = split_for_mode(
|
|
@@ -8,7 +8,6 @@ its saved-checkpoint signature, unchanged.
|
|
|
8
8
|
from typing import TYPE_CHECKING, Any, Collection, Optional, Sequence
|
|
9
9
|
|
|
10
10
|
import jax
|
|
11
|
-
import jax.random as jr
|
|
12
11
|
from einops import reduce
|
|
13
12
|
from jaxtyping import Array, Float, PRNGKeyArray
|
|
14
13
|
|
|
@@ -50,7 +49,7 @@ class DenseStageFeatures:
|
|
|
50
49
|
def features(
|
|
51
50
|
self,
|
|
52
51
|
x: Float[Array, "channels height width"],
|
|
53
|
-
key: PRNGKeyArray =
|
|
52
|
+
key: PRNGKeyArray | None = None,
|
|
54
53
|
inference: Optional[bool] = None,
|
|
55
54
|
**kwargs,
|
|
56
55
|
) -> Float[Array, "dim height width"]:
|
|
@@ -66,7 +65,7 @@ class DenseStageFeatures:
|
|
|
66
65
|
def intermediate_features(
|
|
67
66
|
self,
|
|
68
67
|
x: Float[Array, "channels height width"],
|
|
69
|
-
key: PRNGKeyArray =
|
|
68
|
+
key: PRNGKeyArray | None = None,
|
|
70
69
|
inference: Optional[bool] = None,
|
|
71
70
|
indices: Sequence[int] | None = None,
|
|
72
71
|
n_last_blocks: int | None = None,
|
|
@@ -88,7 +87,7 @@ class DenseStageFeatures:
|
|
|
88
87
|
def __call__(
|
|
89
88
|
self,
|
|
90
89
|
x: Float[Array, "channels height width"],
|
|
91
|
-
key: PRNGKeyArray =
|
|
90
|
+
key: PRNGKeyArray | None = None,
|
|
92
91
|
inference: Optional[bool] = None,
|
|
93
92
|
**kwargs,
|
|
94
93
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
@@ -116,7 +115,7 @@ class TokenStemFeatures:
|
|
|
116
115
|
def features(
|
|
117
116
|
self,
|
|
118
117
|
x: Float[Array, "..."],
|
|
119
|
-
key: PRNGKeyArray =
|
|
118
|
+
key: PRNGKeyArray | None = None,
|
|
120
119
|
inference: Optional[bool] = None,
|
|
121
120
|
) -> Float[Array, "..."]:
|
|
122
121
|
key_pd, *keys = split_for_mode(key, 1 + len(self.blocks), inference=inference)
|
|
@@ -130,7 +129,7 @@ class TokenStemFeatures:
|
|
|
130
129
|
def intermediate_features(
|
|
131
130
|
self,
|
|
132
131
|
x: Float[Array, "..."],
|
|
133
|
-
key: PRNGKeyArray =
|
|
132
|
+
key: PRNGKeyArray | None = None,
|
|
134
133
|
inference: Optional[bool] = None,
|
|
135
134
|
indices: Sequence[int] | None = None,
|
|
136
135
|
n_last_blocks: int | None = None,
|
|
@@ -153,7 +152,7 @@ class TokenStemFeatures:
|
|
|
153
152
|
def __call__(
|
|
154
153
|
self,
|
|
155
154
|
x: Float[Array, "..."],
|
|
156
|
-
key: PRNGKeyArray =
|
|
155
|
+
key: PRNGKeyArray | None = None,
|
|
157
156
|
inference: Optional[bool] = None,
|
|
158
157
|
) -> Float[Array, "..."]:
|
|
159
158
|
"""Features, token-mean pooling, and classification head."""
|
|
@@ -108,7 +108,7 @@ class AttNet(eqx.Module):
|
|
|
108
108
|
def features(
|
|
109
109
|
self,
|
|
110
110
|
x: Float[Array, "channels height width"],
|
|
111
|
-
key: PRNGKeyArray =
|
|
111
|
+
key: PRNGKeyArray | None = None,
|
|
112
112
|
inference: Optional[bool] = None,
|
|
113
113
|
**kwargs,
|
|
114
114
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
@@ -119,7 +119,7 @@ class AttNet(eqx.Module):
|
|
|
119
119
|
def intermediate_features(
|
|
120
120
|
self,
|
|
121
121
|
x: Float[Array, "channels height width"],
|
|
122
|
-
key: PRNGKeyArray =
|
|
122
|
+
key: PRNGKeyArray | None = None,
|
|
123
123
|
inference: Optional[bool] = None,
|
|
124
124
|
indices: Sequence[int] | None = None,
|
|
125
125
|
n_last_blocks: int | None = None,
|
|
@@ -141,7 +141,7 @@ class AttNet(eqx.Module):
|
|
|
141
141
|
def __call__(
|
|
142
142
|
self,
|
|
143
143
|
x: Float[Array, "channels height width"],
|
|
144
|
-
key: PRNGKeyArray =
|
|
144
|
+
key: PRNGKeyArray | None = None,
|
|
145
145
|
inference: Optional[bool] = None,
|
|
146
146
|
**kwargs,
|
|
147
147
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
@@ -227,7 +227,7 @@ class BlockChunk(eqx.Module):
|
|
|
227
227
|
x: Float[Array, "..."],
|
|
228
228
|
*,
|
|
229
229
|
z0: Float[Array, "..."] | None = None,
|
|
230
|
-
key: PRNGKeyArray,
|
|
230
|
+
key: PRNGKeyArray | None,
|
|
231
231
|
inference: Optional[bool] = False,
|
|
232
232
|
**kwargs,
|
|
233
233
|
) -> Tuple[Float[Array, "..."], list]:
|
|
@@ -362,7 +362,7 @@ class DEQ(eqx.Module):
|
|
|
362
362
|
def features(
|
|
363
363
|
self,
|
|
364
364
|
x: Float[Array, "channels height width"],
|
|
365
|
-
key: PRNGKeyArray =
|
|
365
|
+
key: PRNGKeyArray | None = None,
|
|
366
366
|
inference: Optional[bool] = None,
|
|
367
367
|
**kwargs,
|
|
368
368
|
) -> Tuple[Float[Array, "num_classes"], list]: # noqa: F821
|
|
@@ -380,7 +380,7 @@ class DEQ(eqx.Module):
|
|
|
380
380
|
def intermediate_features(
|
|
381
381
|
self,
|
|
382
382
|
x: Float[Array, "channels height width"],
|
|
383
|
-
key: PRNGKeyArray =
|
|
383
|
+
key: PRNGKeyArray | None = None,
|
|
384
384
|
inference: Optional[bool] = None,
|
|
385
385
|
indices: Sequence[int] | None = None,
|
|
386
386
|
n_last_blocks: int | None = None,
|
|
@@ -404,7 +404,7 @@ class DEQ(eqx.Module):
|
|
|
404
404
|
def readout(
|
|
405
405
|
self,
|
|
406
406
|
z_star: Float[Array, "channels height width"],
|
|
407
|
-
key: PRNGKeyArray =
|
|
407
|
+
key: PRNGKeyArray | None = None,
|
|
408
408
|
inference: Optional[bool] = None,
|
|
409
409
|
):
|
|
410
410
|
if len(self.fpi_index) == 0:
|
|
@@ -434,7 +434,7 @@ class DEQ(eqx.Module):
|
|
|
434
434
|
def __call__(
|
|
435
435
|
self,
|
|
436
436
|
x: Float[Array, "channels height width"],
|
|
437
|
-
key: PRNGKeyArray =
|
|
437
|
+
key: PRNGKeyArray | None = None,
|
|
438
438
|
inference: Optional[bool] = None,
|
|
439
439
|
**kwargs,
|
|
440
440
|
) -> Tuple[Float[Array, "num_classes"], list]: # noqa: F821
|
|
@@ -76,7 +76,19 @@ class ScaleBlock(eqx.Module):
|
|
|
76
76
|
self.norm = LayerNorm2d(channels, eps=1e-6)
|
|
77
77
|
|
|
78
78
|
def __call__(self, x: jax.Array) -> jax.Array:
|
|
79
|
-
|
|
79
|
+
# The 2x2 stride-2 transposed convolution has no overlapping windows, so
|
|
80
|
+
# it is a per-pixel matmul followed by depth-to-space. Lowering it as a
|
|
81
|
+
# convolution sends its bfloat16 weight gradient to an untuned cuDNN
|
|
82
|
+
# kernel that dominates training steps at larger batch sizes.
|
|
83
|
+
_, height, width = x.shape
|
|
84
|
+
# Equinox correlates the stored kernel with the dilated input.
|
|
85
|
+
weight = self.conv1.weight[:, :, ::-1, ::-1]
|
|
86
|
+
upscaled = jnp.einsum(
|
|
87
|
+
"oiab,ihw->ohawb", weight, x, preferred_element_type=jnp.float32
|
|
88
|
+
)
|
|
89
|
+
upscaled = upscaled.reshape(-1, 2 * height, 2 * width) + self.conv1.bias
|
|
90
|
+
upscaled = upscaled.astype(x.dtype)
|
|
91
|
+
return self.norm(self.conv2(jax.nn.gelu(upscaled, approximate=False)))
|
|
80
92
|
|
|
81
93
|
|
|
82
94
|
class MaskEmbedding(eqx.Module):
|
|
@@ -393,7 +393,7 @@ class FasterViT(eqx.Module):
|
|
|
393
393
|
def features(
|
|
394
394
|
self,
|
|
395
395
|
x: Float[Array, "channels height width"],
|
|
396
|
-
key: PRNGKeyArray =
|
|
396
|
+
key: PRNGKeyArray | None = None,
|
|
397
397
|
inference: Optional[bool] = None,
|
|
398
398
|
) -> Float[Array, "seqlen dim"]:
|
|
399
399
|
"""Extract features from input image.
|
|
@@ -422,7 +422,7 @@ class FasterViT(eqx.Module):
|
|
|
422
422
|
def intermediate_features(
|
|
423
423
|
self,
|
|
424
424
|
x: Float[Array, "channels height width"],
|
|
425
|
-
key: PRNGKeyArray =
|
|
425
|
+
key: PRNGKeyArray | None = None,
|
|
426
426
|
inference: Optional[bool] = None,
|
|
427
427
|
indices: Sequence[int] | None = None,
|
|
428
428
|
n_last_blocks: int | None = None,
|
|
@@ -451,7 +451,7 @@ class FasterViT(eqx.Module):
|
|
|
451
451
|
def __call__(
|
|
452
452
|
self,
|
|
453
453
|
x: Float[Array, "channels height width"],
|
|
454
|
-
key: PRNGKeyArray =
|
|
454
|
+
key: PRNGKeyArray | None = None,
|
|
455
455
|
inference: Optional[bool] = None,
|
|
456
456
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
457
457
|
"""Process input image through the full network.
|
|
@@ -223,7 +223,7 @@ class LowFormer(eqx.Module):
|
|
|
223
223
|
def features(
|
|
224
224
|
self,
|
|
225
225
|
x: Float[Array, "channels height width"],
|
|
226
|
-
key: PRNGKeyArray =
|
|
226
|
+
key: PRNGKeyArray | None = None,
|
|
227
227
|
inference: Optional[bool] = None,
|
|
228
228
|
**kwargs,
|
|
229
229
|
) -> Float[Array, "seqlen dim"]:
|
|
@@ -251,7 +251,7 @@ class LowFormer(eqx.Module):
|
|
|
251
251
|
def intermediate_features(
|
|
252
252
|
self,
|
|
253
253
|
x: Float[Array, "channels height width"],
|
|
254
|
-
key: PRNGKeyArray =
|
|
254
|
+
key: PRNGKeyArray | None = None,
|
|
255
255
|
inference: Optional[bool] = None,
|
|
256
256
|
indices: Sequence[int] | None = None,
|
|
257
257
|
n_last_blocks: int | None = None,
|
|
@@ -280,7 +280,7 @@ class LowFormer(eqx.Module):
|
|
|
280
280
|
def __call__(
|
|
281
281
|
self,
|
|
282
282
|
x: Float[Array, "channels height width"],
|
|
283
|
-
key: PRNGKeyArray =
|
|
283
|
+
key: PRNGKeyArray | None = None,
|
|
284
284
|
inference: Optional[bool] = None,
|
|
285
285
|
**kwargs,
|
|
286
286
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
@@ -75,7 +75,7 @@ class MobileNetv3(eqx.Module):
|
|
|
75
75
|
def features(
|
|
76
76
|
self,
|
|
77
77
|
x: Float[Array, "..."],
|
|
78
|
-
key: PRNGKeyArray,
|
|
78
|
+
key: PRNGKeyArray | None = None,
|
|
79
79
|
inference: Optional[bool] = None,
|
|
80
80
|
) -> Float[Array, "..."]:
|
|
81
81
|
key_conv1, key_layers = split_for_mode(key, 2, inference=inference)
|
|
@@ -93,7 +93,7 @@ class MobileNetv3(eqx.Module):
|
|
|
93
93
|
def intermediate_features(
|
|
94
94
|
self,
|
|
95
95
|
x: Float[Array, "..."],
|
|
96
|
-
key: PRNGKeyArray,
|
|
96
|
+
key: PRNGKeyArray | None = None,
|
|
97
97
|
inference: Optional[bool] = None,
|
|
98
98
|
indices: Sequence[int] | None = None,
|
|
99
99
|
n_last_blocks: int | None = None,
|
|
@@ -124,7 +124,7 @@ class MobileNetv3(eqx.Module):
|
|
|
124
124
|
def __call__(
|
|
125
125
|
self,
|
|
126
126
|
x: Float[Array, "..."],
|
|
127
|
-
key: PRNGKeyArray,
|
|
127
|
+
key: PRNGKeyArray | None = None,
|
|
128
128
|
inference: Optional[bool] = None,
|
|
129
129
|
) -> Float[Array, "..."]:
|
|
130
130
|
key_f, key_d = split_for_mode(key, 2, inference=inference)
|
|
@@ -1067,7 +1067,7 @@ class VisionParcae(eqx.Module):
|
|
|
1067
1067
|
H: int,
|
|
1068
1068
|
W: int,
|
|
1069
1069
|
inference: Optional[bool],
|
|
1070
|
-
key: PRNGKeyArray,
|
|
1070
|
+
key: PRNGKeyArray | None,
|
|
1071
1071
|
rotary=None,
|
|
1072
1072
|
checkpoint: bool = False,
|
|
1073
1073
|
**kwargs,
|
|
@@ -1288,7 +1288,7 @@ class VisionParcae(eqx.Module):
|
|
|
1288
1288
|
H: int,
|
|
1289
1289
|
W: int,
|
|
1290
1290
|
inference: Optional[bool],
|
|
1291
|
-
key: PRNGKeyArray,
|
|
1291
|
+
key: PRNGKeyArray | None,
|
|
1292
1292
|
rotary=None,
|
|
1293
1293
|
checkpoint: bool = False,
|
|
1294
1294
|
**kwargs,
|
|
@@ -1315,7 +1315,7 @@ class VisionParcae(eqx.Module):
|
|
|
1315
1315
|
H: int,
|
|
1316
1316
|
W: int,
|
|
1317
1317
|
inference: Optional[bool],
|
|
1318
|
-
key: PRNGKeyArray,
|
|
1318
|
+
key: PRNGKeyArray | None,
|
|
1319
1319
|
num_steps: int | Array | None = None,
|
|
1320
1320
|
num_steps_pair: tuple[int | Array, int | Array]
|
|
1321
1321
|
| list[int | Array]
|
|
@@ -1344,11 +1344,17 @@ class VisionParcae(eqx.Module):
|
|
|
1344
1344
|
key=key_rope,
|
|
1345
1345
|
)
|
|
1346
1346
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1347
|
+
# A missing key is only accepted for deterministic inference, where no
|
|
1348
|
+
# recurrent step consumes randomness.
|
|
1349
|
+
keys = (
|
|
1350
|
+
None
|
|
1351
|
+
if key_loop is None
|
|
1352
|
+
else jnp.stack(
|
|
1353
|
+
split_for_mode(
|
|
1354
|
+
key_loop,
|
|
1355
|
+
self.max_recurrence,
|
|
1356
|
+
inference=deterministic_inference,
|
|
1357
|
+
)
|
|
1352
1358
|
)
|
|
1353
1359
|
)
|
|
1354
1360
|
|
|
@@ -1372,9 +1378,13 @@ class VisionParcae(eqx.Module):
|
|
|
1372
1378
|
grad_scan_bound = min(self.max_recurrence, self.mean_backprop_depth)
|
|
1373
1379
|
no_grad_scan_bound = self.max_recurrence - grad_scan_bound
|
|
1374
1380
|
|
|
1375
|
-
def
|
|
1381
|
+
def step_key(index):
|
|
1382
|
+
if keys is None:
|
|
1383
|
+
return None
|
|
1384
|
+
return jax.lax.dynamic_index_in_dim(keys, index, axis=0, keepdims=False)
|
|
1385
|
+
|
|
1386
|
+
def no_grad_body(carry, t):
|
|
1376
1387
|
h_cur, last_cur = carry
|
|
1377
|
-
t, key_step = xs
|
|
1378
1388
|
active = t < no_grad_steps
|
|
1379
1389
|
|
|
1380
1390
|
def inactive(c):
|
|
@@ -1388,7 +1398,7 @@ class VisionParcae(eqx.Module):
|
|
|
1388
1398
|
H=H,
|
|
1389
1399
|
W=W,
|
|
1390
1400
|
inference=inference,
|
|
1391
|
-
key=
|
|
1401
|
+
key=step_key(t),
|
|
1392
1402
|
rotary=rotary,
|
|
1393
1403
|
checkpoint=False,
|
|
1394
1404
|
**kwargs,
|
|
@@ -1401,11 +1411,7 @@ class VisionParcae(eqx.Module):
|
|
|
1401
1411
|
|
|
1402
1412
|
if no_grad_scan_bound:
|
|
1403
1413
|
no_grad_ts = jnp.arange(no_grad_scan_bound, dtype=jnp.int32)
|
|
1404
|
-
(h, last_h), _ = jax.lax.scan(
|
|
1405
|
-
no_grad_body,
|
|
1406
|
-
(h, h),
|
|
1407
|
-
(no_grad_ts, keys[:no_grad_scan_bound]),
|
|
1408
|
-
)
|
|
1414
|
+
(h, last_h), _ = jax.lax.scan(no_grad_body, (h, h), no_grad_ts)
|
|
1409
1415
|
h = jax.lax.stop_gradient(h)
|
|
1410
1416
|
last_h = jax.lax.stop_gradient(last_h)
|
|
1411
1417
|
else:
|
|
@@ -1424,16 +1430,13 @@ class VisionParcae(eqx.Module):
|
|
|
1424
1430
|
no_grad_steps + t,
|
|
1425
1431
|
jnp.asarray(self.max_recurrence - 1, jnp.int32),
|
|
1426
1432
|
)
|
|
1427
|
-
key_step = jax.lax.dynamic_index_in_dim(
|
|
1428
|
-
keys, key_index, axis=0, keepdims=False
|
|
1429
|
-
)
|
|
1430
1433
|
h_next = self._recurrent_step(
|
|
1431
1434
|
h_active,
|
|
1432
1435
|
e,
|
|
1433
1436
|
H=H,
|
|
1434
1437
|
W=W,
|
|
1435
1438
|
inference=inference,
|
|
1436
|
-
key=
|
|
1439
|
+
key=step_key(key_index),
|
|
1437
1440
|
rotary=rotary,
|
|
1438
1441
|
checkpoint=self.recurrent_checkpoint,
|
|
1439
1442
|
**kwargs,
|
|
@@ -1463,7 +1466,7 @@ class VisionParcae(eqx.Module):
|
|
|
1463
1466
|
self,
|
|
1464
1467
|
x: Float[Array, "channels height width"],
|
|
1465
1468
|
*,
|
|
1466
|
-
key: PRNGKeyArray,
|
|
1469
|
+
key: PRNGKeyArray | None,
|
|
1467
1470
|
mask: Optional[Int[Array, "embed_h embed_w"]] = None,
|
|
1468
1471
|
inference: Optional[bool] = None,
|
|
1469
1472
|
num_steps: int | Array | None = None,
|
|
@@ -1474,6 +1477,12 @@ class VisionParcae(eqx.Module):
|
|
|
1474
1477
|
**kwargs,
|
|
1475
1478
|
) -> tuple[Float[Array, "seq dim"], dict]:
|
|
1476
1479
|
deterministic_inference = inference is True and self.state_init == "zero"
|
|
1480
|
+
if key is None and not deterministic_inference:
|
|
1481
|
+
raise ValueError(
|
|
1482
|
+
"VisionParcae requires a PRNG key unless inference=True and "
|
|
1483
|
+
f"state_init='zero' (got inference={inference!r}, "
|
|
1484
|
+
f"state_init={self.state_init!r})."
|
|
1485
|
+
)
|
|
1477
1486
|
key_embed, key_prelude, key_loop, key_coda = split_for_mode(
|
|
1478
1487
|
key, 4, inference=deterministic_inference
|
|
1479
1488
|
)
|
|
@@ -1525,7 +1534,7 @@ class VisionParcae(eqx.Module):
|
|
|
1525
1534
|
def features(
|
|
1526
1535
|
self,
|
|
1527
1536
|
x: Float[Array, "channels height width"],
|
|
1528
|
-
key: PRNGKeyArray,
|
|
1537
|
+
key: PRNGKeyArray | None = None,
|
|
1529
1538
|
mask: Optional[Int[Array, "embed_h embed_w"]] = None,
|
|
1530
1539
|
inference: Optional[bool] = None,
|
|
1531
1540
|
num_steps: int | Array | None = None,
|
|
@@ -1556,7 +1565,7 @@ class VisionParcae(eqx.Module):
|
|
|
1556
1565
|
def forward_features(
|
|
1557
1566
|
self,
|
|
1558
1567
|
x: Float[Array, "channels height width"],
|
|
1559
|
-
key: PRNGKeyArray,
|
|
1568
|
+
key: PRNGKeyArray | None = None,
|
|
1560
1569
|
inference: Optional[bool] = None,
|
|
1561
1570
|
**kwargs,
|
|
1562
1571
|
) -> dict:
|
|
@@ -1590,7 +1599,7 @@ class VisionParcae(eqx.Module):
|
|
|
1590
1599
|
def intermediate_features(
|
|
1591
1600
|
self,
|
|
1592
1601
|
x: Float[Array, "channels height width"],
|
|
1593
|
-
key: PRNGKeyArray,
|
|
1602
|
+
key: PRNGKeyArray | None = None,
|
|
1594
1603
|
inference: Optional[bool] = None,
|
|
1595
1604
|
indices: Sequence[int] | None = None,
|
|
1596
1605
|
n_last_blocks: int | None = None,
|
|
@@ -1686,7 +1695,7 @@ class VisionParcae(eqx.Module):
|
|
|
1686
1695
|
*,
|
|
1687
1696
|
H: int | None = None,
|
|
1688
1697
|
W: int | None = None,
|
|
1689
|
-
key: PRNGKeyArray =
|
|
1698
|
+
key: PRNGKeyArray | None = None,
|
|
1690
1699
|
inference: Optional[bool] = True,
|
|
1691
1700
|
**kwargs,
|
|
1692
1701
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
@@ -1723,7 +1732,7 @@ class VisionParcae(eqx.Module):
|
|
|
1723
1732
|
def __call__(
|
|
1724
1733
|
self,
|
|
1725
1734
|
x: Float[Array, "channels height width"],
|
|
1726
|
-
key: PRNGKeyArray =
|
|
1735
|
+
key: PRNGKeyArray | None = None,
|
|
1727
1736
|
inference: Optional[bool] = None,
|
|
1728
1737
|
num_steps: int | Array | None = None,
|
|
1729
1738
|
num_steps_pair: tuple[int | Array, int | Array]
|
|
@@ -305,7 +305,7 @@ class PartialFormer(eqx.Module):
|
|
|
305
305
|
def features(
|
|
306
306
|
self,
|
|
307
307
|
x: Float[Array, "channels height width"],
|
|
308
|
-
key: PRNGKeyArray = ...,
|
|
308
|
+
key: PRNGKeyArray | None = ...,
|
|
309
309
|
inference: Optional[bool] = ...,
|
|
310
310
|
return_qa: Literal[False] = ...,
|
|
311
311
|
) -> Float[Array, "seqlen dim"]: ...
|
|
@@ -314,7 +314,7 @@ class PartialFormer(eqx.Module):
|
|
|
314
314
|
def features(
|
|
315
315
|
self,
|
|
316
316
|
x: Float[Array, "channels height width"],
|
|
317
|
-
key: PRNGKeyArray = ...,
|
|
317
|
+
key: PRNGKeyArray | None = ...,
|
|
318
318
|
inference: Optional[bool] = ...,
|
|
319
319
|
*,
|
|
320
320
|
return_qa: Literal[True],
|
|
@@ -323,7 +323,7 @@ class PartialFormer(eqx.Module):
|
|
|
323
323
|
def features(
|
|
324
324
|
self,
|
|
325
325
|
x: Float[Array, "channels height width"],
|
|
326
|
-
key: PRNGKeyArray =
|
|
326
|
+
key: PRNGKeyArray | None = None,
|
|
327
327
|
inference: Optional[bool] = None,
|
|
328
328
|
return_qa: bool = False,
|
|
329
329
|
) -> (
|
|
@@ -364,7 +364,7 @@ class PartialFormer(eqx.Module):
|
|
|
364
364
|
def intermediate_features(
|
|
365
365
|
self,
|
|
366
366
|
x: Float[Array, "channels height width"],
|
|
367
|
-
key: PRNGKeyArray =
|
|
367
|
+
key: PRNGKeyArray | None = None,
|
|
368
368
|
inference: Optional[bool] = None,
|
|
369
369
|
indices: Sequence[int] | None = None,
|
|
370
370
|
n_last_blocks: int | None = None,
|
|
@@ -401,7 +401,7 @@ class PartialFormer(eqx.Module):
|
|
|
401
401
|
def __call__(
|
|
402
402
|
self,
|
|
403
403
|
x: Float[Array, "channels height width"],
|
|
404
|
-
key: PRNGKeyArray =
|
|
404
|
+
key: PRNGKeyArray | None = None,
|
|
405
405
|
inference: Optional[bool] = None,
|
|
406
406
|
) -> Float[Array, "num_classes"]: # noqa: F821
|
|
407
407
|
"""Process input image through the full network.
|