Repository navigation
Noether Release Notes
This release moves Noether to calendar-based versioning (#189) and ships a major round of new recipes, a higher-level training API, broader AB-UPT capabilities, and a measurable quality improvement on the DrivAerML baseline.
Highlights
Improved AB-UPT baseline on DrivAerML
RoPE scaling (#184) combined with the new Muon optimizer (#158) lifts AB-UPT performance on DrivAerML over the previous baseline. See the full comparison in the W&B report.
New recipes
- AB-UPT showcase with scalable query-based inference (#153) — an end-to-end DrivAerML walkthrough covering data fetching, training, and evaluation. Designed to be the recommended starting point for AB-UPT users.
- Heat transfer recipe (#146) — Neural surrogate for the SIMSHIFT Heatsink benchmark (819 simulations) predicting velocity, temperature, and pressure on 3D volume fields conditioned on simulation parameters. Supports both AB-UPT and Transolver++.
- Emmi-Wing HF subset recipe (#159) — small, fast-to-iterate aerodynamics recipe backed by the public EmmiAI/Emmi-Wing HuggingFace dataset, with train/val/eval splits.
- Aero CFD recipe (#143) — the previous tutorial promoted to a full recipe.
High-level training API
Training presets (#128) — DomainPreset encapsulates dataset stats, normalizers, pipeline defaults, and forward properties. Per-dataset training scripts (examples/train_*.py) now expose only experiment-level knobs (model, hidden dim, epochs, device, accelerator, paths).
AB-UPT capabilities
- Untied physics blocks (#177) —
self_untied,cross_untied,perceiver_untiedvariants with per-branch weights viaUntiedLinear(batched or grouped matmul). Removes the need to configure decoder-block counts per domain and enables cross-attention between branches with untied weights. - Arbitrary domains (#139) (breaking) — replaces the hardcoded surface or volume split with a
ModelDataSpecsdict, so AB-UPT can be applied to any number of named domains (gas, liquid, solid, multi-phase, …). - Optional geometry encoder (#150) and Muon optimizer support (#158) (breaking) — Muon is paired with a secondary optimizer for non-2D tensors. QKV is split into separate Q, K, V matrices (breaks old checkpoints).
Workflow and infrastructure
- submitit-based multirun job submission (#164) (breaking) — replaces the custom
sbatch --wrappath withsubmitit.AutoExecutor, giving Hydra multirun sweeps as SLURM array jobs with login-node validation.SlurmConfigfield names now matchAutoExecutor.update_parameters(name,slurm_partition,mem_gb,timeout_min, …). - Development CLI (#142) —
noether-developmentruns individual modules (datasets, models, trainers) in isolation with verbose logging for fast iteration without the full pipeline. - EMA evaluation (#183, #192) —
EmaCallbacknow accepts nestedeval_callbacksthat run on swapped-in EMA weights and emit metrics under anema=<factor>/prefix, removing the need for a separate eval run. - Profiling callback (#161) — wraps the PyTorch profiler as a standard callback.
- Reproducibility (#179, #180) — DataLoader workers are seeded and
use_deterministic_algorithmsis enabled. Non-deterministic dataset ordering fixed. - Dataset hooks (#154) —
pre_getitemandpost_getitemhooks on the baseDatasetfor lightweight per-sample customization.
Breaking changes
- #138 — shared attention renamed to
self. Auto-converted with a deprecation warning during the transition. - #139 — fixed surface or volume domains generalized to arbitrary domains. Replace
AeroDataSpecswith theModelDataSpecsdict. - #142 — development CLI introduces new entry points (additive; review CLI docs).
- #158 — Muon support splits QKV into separate Q, K, V matrices. Old AB-UPT checkpoints will not load.
- #164 — submitit replaces the custom sbatch wrapper. Rename
SlurmConfigfields. Remove--outputand--error. Sweeps may not varyslurm:fields. - #189 — versioning switched to CalVer. Manual release process. Release-please config removed.
Detailed changes
Features
- Rename shared → self attention by @Ndles in #138
- Expose training presets and high-level API by @Ndles in #128
- Convert tutorial to
aero_cfdrecipe by @HennerM in #143 - Generalize fixed surface/volume to arbitrary domains by @richardk53 in #139
- Make geometry encoder optional in AB-UPT by @HennerM in #150
pre_getitemandpost_getitemhooks onDatasetby @HennerM in #154- Emmi-Wing HF subset recipe by @Ndles in #159
- Profiling callback by @HennerM in #161
- Heat transfer recipe by @HennerM in #146
- AB-UPT showcase with scalable query-based inference by @Ndles in #153
- Module-wise development CLI by @MauritsBleeker in #142
- submitit replaces custom sbatch wrap, adds multirun by @HennerM in #164
- Muon optimizer support by @kinggongzilla in #158
- Seed DataLoader workers and enable deterministic algorithms by @HennerM in #179
- Evaluate on EMA weights by @HennerM in #183
- Route
DomainPreset.build_optimizerthrough optimizer discriminator by @Ndles in #187 - Basic timing and precision option in showcase preset by @Ndles in #188
- Reuse callback configs in EMA eval by @HennerM in #192
- Untied physics blocks by @HennerM in #177
Fixes
- Distributed training hanging with
submit_jobby @HennerM in #141 calculate_statisticscompatibility with any dataset subclass by @HennerM in #147- Attempt HF download without
HF_TOKENby @HennerM in #152 - Support configs without custom top-level schema in submit script by @HennerM in #151
move_item_to_deviceon MPS by @Ndles in #157- Log total parameter count for non-composite models by @HennerM in #155
- Support normalization and denormalization on CUDA by @HennerM in #156
- StopIteration error when training on fractional epoch by @HennerM in #162
- Transolver uses Transolver attention, not regular attention by @MauritsBleeker in #166
- Missed import rename by @HennerM in #168
- Aero callback uses correct denormalization key by @MauritsBleeker in #169
aero_cfdShapeNet recipe by @HennerM in #173- Default to unlimited job time by @HennerM in #176
- Non-deterministic dataset order by @HennerM in #180
- Avoid error when loading model with
noether-evaldue to stored computed fields by @kinggongzilla in #170 - Catch OOM in slurm submission by @HennerM in #190
- Flush tracker on eval and exception by @HennerM in #182
resume_from_checkpointfor eval callbacks by @HennerM in #193
Docs
- Add "Understanding the Data Pipeline" page by @tcapelle in #140
- Minor documentation fixes by @MauritsBleeker in #160
- SEO enhancements by @HennerM in #175
- Increase visibility of recipes in docs and README by @Ndles in #181
Chore
- Fix leftover tutorial kind strings by @kinggongzilla in #144
- Use
_get_int_envinstead ofos.environ.getby @ghtyrant in #145 - Trainer config validation and transformer input validation by @HennerM in #148
- Add description to periodic callback progress bar by @HennerM in #149
CLAUDE.mdand conciseAGENTS.mdby @HennerM in #163- Upgrade torch to 2.11 by @kinggongzilla in #165
- Type guard to avoid mypy error in
OptimizerWrapperby @kinggongzilla in #171 - Instructions on SIGTERM and CheckpointCallback by @Ndles in #172
- Tests for trainer eval, failing callbacks, grad scaler loading by @HennerM in #167
- Add ABUPT forward/backward benchmarks by @HennerM in #174
- Change RoPE params for DrivAerML by @HennerM in #184
CI
- Publish target release to PyPI by @ghtyrant in #136
- Fix mypy pre-commit hook by @HennerM in #191
- Convert versioning to calendar-based system by @hfurkanvural in #189