Flash-Aurora is an inference and serving engine for the Microsoft Aurora Earth-system foundation model, with the same stack intended to host further geospatial foundation models. It provides shape-specialized Triton and CuTe DSL kernels, named mixed-precision routing (inference_precision), data ingress, checkpoint loading, autoregressive rollout, NetCDF/GeoTIFF export, and a ZeroMQ scheduler to deploy asynchronized service on a GPU cluster.
Companion documents:
- docs/tutorial.md: install steps, Engine and scheduler API examples, notebook index.
- docs/benchmarks.md: full latency, numerical-error, window-attention, and multi-GPU rollout tables.
- Examples: linked walkthrough notebooks for each preset, ROI export, and the ZMQ scheduler.
New model families plug into the same Engine without rewriting the performance-critical path. In the same sense as Day-1 model support in systems such as vLLM, a modular preset / registry / adapter surface lets a new family land with shared kernels and serving, rather than a fork of the hot path. Aurora 1.5 (Microsoft Aurora release tag v2.0.0) is the first proof point: a side-path package beside the archived legacy family (upstream v1.8.0). Walkthrough: docs/example_aurora_v1p5.ipynb.
The same pattern (model package, preset, adapter; reuse Engine and kernels) is how later Aurora generations or other geospatial foundation models can get Day-1 support under a compatible code adaption.
PyTorch Swin3D materializes many short-lived tensors at window-layout and AdaLN boundaries. Flash-Aurora fuses those steps on the backbone hot path:
- Fused window layout (
triton_swin3d_layout.py,use_triton_layout): cyclic shift, pad, 3D window partition, and inverse merge in fused Triton kernels instead of a chain of eager views and copies. For fixed inference shapes,InferenceWorkspacePoolcan reuse a scratch buffer for the backbone--decoder concat and related temporaries. - Fused AdaLN and residual (
triton_adaln.py,use_triton_adaln): LayerNorm, FiLM modulation, and residual add without writing a full-width AdaLN intermediate.
On bf16_mixed@* and tf32@* tiers, AdaLN can emit FP32 activations between Swin3D blocks (output_fp32), so the next block reads higher-precision residuals while GEMM and attention still use Tensor Cores. That reduces global-memory traffic relative to the decomposed PyTorch path without collapsing inter-block precision to BF16. Details: Precision tiers.
Aurora Swin windows are short (
Why short windows matter. When _smem_utils.py selects the single-stage path (single_kv_tile=True, num_stages=1): one shared-memory tile holds the entire window num_stages=2); production
Two precision modes (WinAttnPrecision) cover the production path:
BF16_MIXED: BF16 activations and Tensor Core MMA; FP32 online softmax.TF32_ACC_FP32: FP32 inputs and outputs with TF32-accumulated MMA, for closer FP32 fidelity at lower throughput than BF16.
Shifted-window masks are packed once as compact uint8 and applied inside the kernel as the additive bias equivalent of PyTorch's scaled_dot_product_attention (SDPA).
Attention sm_120) unmasked speedups are about sm_89) absolute latency is higher, with about
Measured on RTX PRO 6000 Blackwell (sm_120a). X-axis labels are
Tiers use the label backbone@encoder_decoder (default production tier bf16_mixed@fp32). The left token selects Swin3D GEMM and window-attention dtype; the right token selects Perceiver encoder/decoder GEMM dtype.
bf16_mixedbackbone: BF16 CuTe attention (QKV/proj) and BF16 MLP; TF32 Tensor Core GEMM elsewhere; FP32 inter-block activations via Triton AdaLN (output_fp32).tf32backbone: TF32 GEMM throughout Swin plus CuTeTF32_ACC_FP32attention (FP32 I/O).fp32backbone: Strict FP32 GEMM and PyTorch SDPA; accuracy baseline with Triton fusion still enabled.bf16backbone: Full backbone BF16 GEMM with fused CuTe attention (faster path exists, but larger drift; not recommended for production).
Encoder and Perceiver decoder default to @fp32 because their errors map directly into output fields, while the Swin backbone dominates runtime (about era5_pretrained). Across production presets, bf16_mixed@fp32 brings a single rollout step (model.forward, one lead) to about pytorch_backbone_fp32_encoder_decoder_fp32). These end-to-end bars are not multi-step autoregressive rollouts. Each tier is timed in a fresh subprocess (--isolate-tiers) so cuDNN autotune from an earlier tier cannot deflate a later baseline. Full tables: docs/benchmarks.md.
Precision tier details: Precision tiers.
RTX PRO 6000 Blackwell; one model.forward (single rollout step) per bar; each tier in a separate process (--isolate-tiers). Finetuned presets merge LoRA into base weights before timing (lora_merged). aurora_v1p5 is within a few percent of era5_pretrained; see docs/benchmarks.md.
One long-lived ZeroMQ worker owns one GPU and one model preset. A coordinator routes jobs to idle workers and streams step events to clients. This is job-level scheduling across heterogeneous presets, not tensor or pipeline parallelism inside one forward. Commands and client sketches: docs/tutorial.md.
| Single 1-step task distribution | Refill while hres_0.1 is pending |
|---|---|
![]() |
![]() |
Left: one job per worker and preset. Right: faster workers take follow-up jobs while hres_0.1 remains pending. Traces from docs/example_scheduler_distributed_workers.ipynb on
DistributedConfig places encoder, Swin backbone, and spatial decoder on two devices inside one process (not a multi-process torchrun job). The VRAM planner in engine/distributed/plan.py chooses the split from ModelVariantSpec and per-card limits; decoder_spatial.py can bisect the decoder west/east so peak decoder activation memory falls from about rollout_and_export run reaches about era5_pretrained and about hres_0.1, where GPU-to-CPU offload and NetCDF write dominate (export-bound). Aurora 1.5 does not yet enable this path. Placement and timing tables: docs/benchmarks.md.
era5_pretrained (5090) |
hres_0.1 (5090) |
|---|---|
![]() |
![]() |
In practice, application users rarely need a full global field after inference (the same pattern as clipping and exporting AOIs in Google Earth Engine). Shipping every grid cell through egress is wasteful: the dominant costs are GPU-to-CPU transfer and CPU-to-disk write for large NetCDF/GeoTIFF volumes. Flash-Aurora therefore clips on the egress path. RoiBatch exports several named masks from one rollout step with a *ingle GPU-to-CPU copy, then applies each mask and writes only the regional product (GeoTIFF recommended; NetCDF also supported) without re-running inference. That cuts both host memory traffic and on-disk footprint relative to a global dump. Masks come from axis-aligned bounds, GeoJSON, shapefile, or georeferenced raster; GeoTIFF defaults to Web Mercator (EPSG:3857) and handles the
git clone <repository-url>
cd flash-aurora
uv syncDependencies are listed in pyproject.toml and pinned in uv.lock. If CuTe kernels need an explicit GPU architecture, set CUTE_DSL_ARCH (for example sm_89 on RTX 4090, sm_120a on Blackwell). API sketches: docs/tutorial.md.
| Path | Role |
|---|---|
flash_aurora/models/aurora/ |
Legacy optimized Aurora (upstream freeze v1.8.0). |
flash_aurora/models/aurora_v1p5/ |
Aurora 1.5 package (v2.0.0 release); shares kernels and precision modes. |
flash_aurora/models/ops/ |
Shared Triton and CuTe kernels. |
flash_aurora/models/inference_precision.py |
Named precision presets. |
flash_aurora/engine/ |
Preset Engine: core, ingress, egress, runtime, distributed. |
flash_aurora/scheduler/ |
ZeroMQ worker, coordinator, client, supervisor. |
docs/ |
Notebooks, tutorial.md, benchmarks.md. |
benchmark/ |
Latency, numerical-error, kernel, and multi-GPU timing scripts. |
tests/ |
Model, kernel, engine, and scheduler tests (./scripts/run_tests.sh). |
- Run forecasts in one process: Engine, then docs/tutorial.md or the Examples notebooks.
- Fit a preset that needs two GPUs: Distributed pipeline and docs/benchmarks.md.
- Serve outside the notebook: Forecast scheduler and docs/tutorial.md.
- Compare precision or latency: Precision tiers and docs/benchmarks.md.
| Example | Topic |
|---|---|
| example_era5.ipynb | Baseline in-process era5_pretrained; populate cache and checkpoints. |
| example_aurora_v1p5.ipynb | Aurora 1.5: extended ERA5 IC, 6 h / hourly leads, optional ensemble. |
| example_hres_t0.ipynb | WeatherBench2 HRES T0 finetuned preset. |
| example_hres_0.1.ipynb |
hres_0.1). |
| example_cams.ipynb | CAMS air-pollution preset. |
| example_wave.ipynb | Wave preset; manual MARS GRIB cache placement when needed. |
| example_tc_tracking.ipynb | Tropical-cyclone tracking LoRA preset. |
| example_roi_export.ipynb | Batched ROI mask export (NetCDF / GeoTIFF) via RoiBatch. |
| example_scheduler_single_worker.ipynb | Single-GPU ZeroMQ queue; preflight cleanup; graceful shutdown. |
| example_scheduler_distributed_workers.ipynb | Heterogeneous multi-GPU dispatch and refill while a slow job is pending. |
| example_scheduler.py | Command-line version of the single-worker scheduler tutorial. |
API sketches that accompany these notebooks: docs/tutorial.md.
flash_aurora.engine is the preset-driven inference layer: choose a model and data source, load weights, validate the input batch, run multi-step forecasts, write NetCDF, and optionally place stages on two GPUs in one process.
| Layer | Path | Role |
|---|---|---|
| Core | engine/core/ |
Config, presets, AuroraEngine, checkpoints, forecast session, lifecycle. |
| Ingress | engine/ingress/ |
Downloaders, format adapters, initial-condition builder, validator, optional disk cache. |
| Egress | engine/egress/ |
Move results off GPU, name step NetCDF files, optional background export. |
| Runtime | engine/runtime/ |
Warmup, optional CUDA graph pool, GPU reservation, memory estimates. |
| Distributed | engine/distributed/ |
Two-GPU placement plan and pipelined forward. |
A preset pairs a model variant with a data profile. The downloader fills the local cache when files are missing; the initial-condition builder builds a validated batch; load() applies the chosen precision mode and optional two-GPU layout; rollout_stream advances
| Preset | Model | Grid |
Source | Backend |
|---|---|---|---|---|
era5_pretrained |
AuroraPretrained | CDS ERA5 | CDS | |
aurora_v1p5 |
AuroraV1p5 | CDS ERA5 (extended) | CDS | |
aurora_v1p5_ensemble |
AuroraV1p5Ensemble | CDS ERA5 (extended) | CDS | |
hres_t0_finetuned |
Aurora (LoRA) | WeatherBench2 HRES | WB2 + ERA5 static | |
small_pretrained |
AuroraSmallPretrained | CDS ERA5 | CDS | |
hres_0.1 |
AuroraHighRes | IFS analysis | ECMWF Open Data / GRIB | |
cams |
AuroraAirPollution | CAMS | ADS | |
wave |
AuroraWave | WB2 meteorology + MARS wave | WB2 + MARS | |
tc_tracking |
Aurora (LoRA) | WeatherBench2 HRES | WB2 + ERA5 static |
Personal ECMWF accounts typically lack MARS access; see example_wave.ipynb for placing wave GRIB files in the cache by hand.
Checkpoints load from disk, with optional Hugging Face Hub download. Precision modes route Triton, CuTe, BF16, and TF32 on the legacy family and the Aurora 1.5 backbone. Two-GPU pipeline placement is available for the legacy family (not for Aurora 1.5). Data sources include CDS (including Aurora 1.5 extended surface fields), ADS, WeatherBench2, Open Data GRIB, and MARS when the account allows it. Aurora 1.5 can use hourly lead times. Optional features include background NetCDF export, overlapping initial-condition load with compute, a disk cache of prepared initial conditions, and a GPU reservation guard. CUDA graph capture is still experimental and is turned off for Aurora 1.5.
API sketches and lifecycle notes: docs/tutorial.md.
Single-process pipeline parallelism for presets that exceed one GPU. Pass distributed=DistributedConfig(devices=("cuda:0", "cuda:1"), ...) to from_preset, or set engine.config.distributed before load(). Benchmarks: docs/benchmarks.md.
Long-lived workers each own one GPU and one preset. Clients send JSON commands and receive per-step events (exported file paths, metadata only, or the last step as an array). Deployment commands and client sketches: docs/tutorial.md.
Tiers are labeled backbone@encoder_decoder (for example bf16_mixed@fp32).
| Backbone token | Meaning |
|---|---|
fp32 |
Strict FP32 GEMM; PyTorch SDPA unless a higher tier replaces window attention. |
tf32 |
TF32 Tensor Core GEMM; CuTe TF32_ACC_FP32 window attention (FP32 I/O). |
bf16_mixed |
BF16 attention QKV/proj and MLP; TF32 GEMM elsewhere; CuTe BF16_MIXED attention; FP32 inter-block activations via Triton AdaLN when enabled. |
bf16 |
Full backbone BF16 GEMM with fused CuTe attention (not recommended for production). |
Encoder/decoder tokens are fp32 or tf32 and control Perceiver GEMM dtype. Set with inference_precision= on from_preset or EngineConfig.
All custom tiers enable the same Triton fusion base (use_triton_layout, use_triton_adaln). CuTe attention and GEMM precision layer on top. The reference tier pytorch_backbone_fp32_encoder_decoder_fp32 disables Triton and CuTe so drift is measured against an unfused baseline.
Official per-variable tolerances
Flash-Aurora replaces PyTorch SDPA on Swin windows with CuTe DSL kernels under flash_aurora/models/ops/cute/. Inputs use layout _choose_tile_n keeps single_kv_tile=True). Softmax accumulates in FP32; the full BF16_MIXED and TF32_ACC_FP32 trade Tensor Core throughput against FP32 fidelity; masks are uint8-packed equivalents of the PyTorch
End-to-end figures mean a single model.forward (one rollout step), measured on NVIDIA RTX PRO 6000 Blackwell, PyTorch CUTE_DSL_ARCH=sm_120a. Each timing run warms up twice, then averages five measured forwards. Each precision tier runs in its own process (--isolate-tiers) so cuDNN autotune from an earlier tier cannot deflate a later baseline. The wave preset is omitted (needs MARS). Full BF16 backbone tiers (bf16@*) are left out of the latency charts: they are no faster than bf16_mixed@* and show larger numerical drift. Multi-step rollout timings live under the distributed section of docs/benchmarks.md. Regenerate the figures with uv run python benchmark/plot_readme_perf_charts.py.
aurora_v1p5 numerical check (seed pytorch_backbone_fp32_encoder_decoder_fp32): recommended tiers (bf16_mixed@*, tf32@*, fp32@fp32) pass all bf16@fp32 and plain PyTorch autocast fail on some extended surface fields.
Full latency grids, drift tables, reproduce commands, and multi-GPU numbers: docs/benchmarks.md.
test_aurora_small compares FP64 forwards to Microsoft Hugging Face reference tensors. On recent PyTorch builds, a small drift on a few surface variables can appear even with the official microsoft-aurora wheel; the test still passes and emits a warning when drift exceeds upstream tolerances.
This repository is licensed under the MIT License.
flash_aurora.models.aurorais derived from Microsoft Aurora (MIT), frozen at upstream v1.8.0. Seeflash_aurora/models/aurora/LICENSE.txtandNOTICE.md.flash_aurora.models.aurora_v1p5is the Aurora 1.5 side path from tagv2.0.0(MIT). Presets:aurora_v1p5/aurora_v1p5_ensemble. Seeflash_aurora/models/aurora_v1p5/LICENSE.txtandNOTICE.md.- Shared kernels live under
flash_aurora.models.ops(see per-file headers, including NVIDIA BSD-3-Clause where noted).
Aurora model. Bodnar et al., A Foundation Model for the Earth System, Nature (2025). doi:10.1038/s41586-025-09005-y. Upstream: microsoft.github.io/aurora.
CUTLASS / CuTe DSL. Window-attention and dense GEMM kernels under flash_aurora/models/ops/cute/ adapt patterns from NVIDIA CUTLASS (BSD-3-Clause). Runtime package: nvidia-cutlass-dsl.
Flash Attention. FMHA mainloop and online softmax structure follow flash-attn (Tri Dao).



