shafezi commited on
Commit
36a52e2
·
verified ·
1 Parent(s): 650421f

Add files using upload-large-folder tool

Browse files
README.md ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - ocean-modeling
5
+ - diffusion-models
6
+ - ensemble-forecasting
7
+ - data-assimilation
8
+ - robotics
9
+ library_name: pytorch
10
+ ---
11
+
12
+ # Closed-Loop Adaptive Sampling on a Generative Ocean Model — weights
13
+
14
+ Regional latent-diffusion ocean forecasters for two ROMS reanalysis domains:
15
+ the Mid-Atlantic Bight (MAB, from the Doppio reanalysis) and the California
16
+ Current System (CCS, from CCSRA31). Each region has a deep compressive
17
+ autoencoder (256,388,460 parameters) and an EDM-trained latent denoiser
18
+ (374,938,452 parameters). These are the exact weights behind every number in
19
+ the paper "Closed-Loop Adaptive Sampling on a Generative Ocean Model"
20
+ (Hafezi and Papalia): the closed loop forecasts an analysis ensemble in latent
21
+ space, decodes it, plans sampling locations from ensemble statistics, and
22
+ assimilates observations by observation-conditioned diffusion sampling.
23
+
24
+ This is a research model, not an operational forecast. It is trained on
25
+ reanalysis fields of two specific regional domains and evaluated against the
26
+ same reanalyses; it has no skill guarantee on real-time data and must not be
27
+ used for navigation or safety decisions.
28
+
29
+ ## Files
30
+
31
+ ```
32
+ mab/dcae/ ema.safetensors, meta.json, training_config.yaml
33
+ mab/denoiser/seed0/ same triple
34
+ mab/region.yaml the complete region configuration (grid, crop, channels)
35
+ mab/wet_mask.npy the binary wet mask on the model crop (19,150 wet cells;
36
+ CCS: 21,240)
37
+ ccs/ same layout
38
+ extras/denoiser_seed1_{mab,ccs}/ trained identically with seed 1;
39
+ not used in any paper result
40
+ ```
41
+
42
+ Every checkpoint is the exponential-moving-average (EMA) weights of the
43
+ best-on-validation checkpoint, re-keyed by parameter name and converted to
44
+ safetensors; `meta.json` records the epoch, validation loss, parameter count
45
+ and source training run. The as-run training configuration sits beside each
46
+ checkpoint.
47
+
48
+ ## Training, in brief
49
+
50
+ Per region: the autoencoder compresses 84 input channels (20 sigma-levels each
51
+ of u, v, temperature and salinity, the 2-D dynamic fields zeta/ubar/vbar, and
52
+ the binary wet mask) on the model crop
53
+ (MAB 104 x 240, CCS 176 x 184) to an 84-channel latent (MAB 13 x 30,
54
+ CCS 22 x 23); the denoiser is trained with the EDM objective on four-state
55
+ latent sequences and generates with a 20-step Karras schedule (rho 7, Heun,
56
+ sigma 0.002-80, sigma_data 0.5). Inference for the paper ran in bf16 on a
57
+ single NVIDIA A40. Full hyperparameters are in each `training_config.yaml`.
58
+
59
+ ## Verification
60
+
61
+ The code repository's equivalence suite loads these files and must reproduce
62
+ the recorded probe statistics (tolerance 1e-5) and rounded-array SHA-256 hashes
63
+ on CPU:
64
+
65
+ | probe | sha256 (outputs rounded to 1e-4) |
66
+ |---|---|
67
+ | MAB denoiser, fixed-noise probe | `974408e42ee9e5247ffab7fba85031cb0bd633c09726b5cfd73c106f1cd08056` |
68
+ | MAB autoencoder, decode probe | `ef675e85f337909433474cdb975bfce693693f02703fe645040ee93fb88bc6c9` |
69
+ | MAB autoencoder, encode probe | `c2d2311393633d82ed3a88fd3a645a0b8f60f8420daa926b2a57d585501fe5e4` |
70
+ | CCS denoiser, fixed-noise probe | `1b19d9d1119d6e398897a63028a2a8d86608ab403f4b124c0355f0c8ba892521` |
71
+
72
+ Retrained weights will not reproduce these hashes; they identify the released
73
+ checkpoints.
74
+
75
+ ## Lineage and license
76
+
77
+ The forecaster architecture derives from LaDCast (Zhuang and Duraisamy, 2025;
78
+ `github.com/tonyzyl/ladcast`), adapted to regional ocean domains. LaDCast is
79
+ dual-licensed: code adapted from third-party sources under Apache-2.0, original
80
+ content under MIT. The code repository pins the upstream commit and fetches it
81
+ at setup rather than redistributing it. These weights, trained from
82
+ scratch on the reanalysis data by the authors, are released under MIT.
83
+
84
+ Training data: MAB from the Doppio reanalysis (Wilkin et al., 2022,
85
+ Progress in Oceanography 209:102919; distributed by Rutgers University and via
86
+ the NOAA Open Data Dissemination program); CCS from CCSRA31 (Neveu et al.,
87
+ 2016, Ocean Modelling 99:133-151; distributed by the UC Santa Cruz ocean
88
+ modeling group). Neither reanalysis is redistributed here.
89
+
90
+ ## Use
91
+
92
+ ```
93
+ pip install -e . # the code repository
94
+ export CLOSEDLOOP_WEIGHTS=/path/to/weights
95
+ python tools/download_weights.py
96
+ python experiments/run_closed_loop.py --region mab \
97
+ --ic_datetime 2022-04-09T12:00 --nfleet 50 --strategy a_optimal --rseed 0
98
+ ```
99
+
100
+ ## Citation
101
+
102
+ ```bibtex
103
+ @inproceedings{hafezi2027closedloop,
104
+ author = {Hafezi, Shayesteh and Papalia, Alan},
105
+ title = {Closed-Loop Adaptive Sampling on a Generative Ocean Model},
106
+ year = {2027},
107
+ note = {Under review},
108
+ }
109
+ @misc{zhuang2025ladcast,
110
+ author = {Zhuang, Yilin and Duraisamy, Karthik},
111
+ title = {{LaDCast}: A Latent Diffusion Model for Medium-Range
112
+ Ensemble Weather Forecasting},
113
+ year = {2025},
114
+ howpublished = {arXiv preprint arXiv:2506.09193},
115
+ }
116
+ ```
ccs/dcae/ema.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0f49d8ca61ff26dd54f7ad0df2a978a9ce402286c3dc6d11a91d39cc2df6a5d3
3
+ size 1025594896
ccs/dcae/meta.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kind": "autoencoder",
3
+ "region": "ccs",
4
+ "epoch": 10,
5
+ "val_loss": 0.01927414374506992,
6
+ "param_count": 256388460,
7
+ "source_run": "dcae_ccs_pilot0/checkpoint-best",
8
+ "ema": true,
9
+ "format": "safetensors"
10
+ }
ccs/dcae/training_config.yaml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AS-RUN recipe of the released CCS DC-AE checkpoint (overlay for
2
+ # scripts/train_dcae.py --region ccs --config this-file).
3
+ # Production selection: best-on-val (epoch 10, val_loss 0.019274); EMA at inference.
4
+ region: ccs
5
+ seed: 42
6
+
7
+ pretrain_epochs: 30
8
+ decoder_finetune_epochs: 0 # explicitly zero in the production run
9
+ lr_pretrain: 1.0e-4
10
+ lr_finetune: 1.0e-5
11
+ warmup_steps: 1000
12
+ lr_cosine_cycles: 0.5
13
+ optimizer_betas: [0.9, 0.999]
14
+ optimizer_eps: 1.0e-8
15
+ weight_decay: 0.01
16
+ gradient_clip_norm: 1.0
17
+
18
+ train_year_range: [1980, 2014]
19
+ val_year_range: [2015, 2015]
20
+
21
+ batch_size_per_device: 4
22
+ gradient_accumulation_steps: 1
23
+ num_workers: 4
24
+
25
+ ema_decay: 0.9999
26
+ ema_use_warmup: true
27
+ ema_update_after_step: 1000
28
+ ema_inv_gamma: 1.0
29
+ ema_power: 0.667
30
+
31
+ mixed_precision: bf16
32
+ checkpoint_every_n_epochs: 5
33
+ keep_last_n_checkpoints: 3
34
+ save_best_val: true
35
+ val_every_n_epochs: 2
36
+ val_max_batches: 200
ccs/denoiser/seed0/ema.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:63419d94c821e46391b6de1e9e97899491774db751677e4a4e926656719c49e3
3
+ size 1499773608
ccs/denoiser/seed0/meta.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kind": "denoiser",
3
+ "region": "ccs",
4
+ "epoch": 6,
5
+ "val_loss": 0.24139750391244888,
6
+ "param_count": 374938452,
7
+ "source_run": "seed_000/checkpoint-best",
8
+ "ema": true,
9
+ "format": "safetensors"
10
+ }
ccs/denoiser/seed0/training_config.yaml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AS-RUN recipe of the released CCS denoiser checkpoints (seeds 0 and 1)
2
+ # (overlay for scripts/train_denoiser.py --region ccs --config this-file --seed {0,1}).
3
+ # Production selection: best-on-val (seed 0: epoch 6, val 0.241398;
4
+ # seed 1: epoch 8, val 0.257570); EMA weights at inference.
5
+ region: ccs
6
+ # seed: pass --seed 0 or --seed 1 (both released)
7
+
8
+ epochs: 15
9
+ lr: 1.0e-4
10
+ warmup_steps: 1000
11
+ lr_cosine_cycles: 0.5
12
+ optimizer_eps: 1.0e-8
13
+ weight_decay: 0.01
14
+ gradient_clip_norm: 1.0
15
+
16
+ train_year_range: [1980, 2014]
17
+ val_year_range: [2015, 2015]
18
+
19
+ batch_size_per_device: 4
20
+ gradient_accumulation_steps: 1
21
+ num_workers: 4
22
+
23
+ num_train_timesteps: 1000
24
+ sigma_min: 0.002
25
+ sigma_max: 80.0
26
+ sigma_data: 0.5
27
+ p_mean: -1.2
28
+ p_std: 1.2
29
+ num_push_forward_steps: 1
30
+
31
+ ema_decay: 0.9999
32
+ ema_use_warmup: true
33
+ ema_update_after_step: 1000
34
+ ema_inv_gamma: 1.0
35
+ ema_power: 0.667
36
+
37
+ mixed_precision: bf16
38
+ checkpoint_every_n_epochs: 2
39
+ keep_last_n_checkpoints: 3
40
+ save_best_val: true
41
+ val_every_n_epochs: 2
42
+ val_max_batches: 100
ccs/region.yaml ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CCS (California Current System; UCSC CCSRA31 ROMS 4D-Var reanalysis) —
2
+ # RegionConfig. AUTHORITATIVE source for every CCS dataset-specific value;
3
+ # parsed by closedloop_sampling.regions.load("ccs"). Paths RELATIVE to
4
+ # ${CLOSEDLOOP_DATA_ROOT} / ${CLOSEDLOOP_RUNS} / ${CLOSEDLOOP_WEIGHTS}.
5
+ # Locked decisions, as trained: crop mask_rho[2:178, 1:185] -> 176x184; drop the
6
+ # DEEPEST staged sigma-level -> 20 kept (surface-preserving); latent 22x23;
7
+ # natively 6-hourly (internal_stride 1); later-file-wins dedup -> 57,441 steps.
8
+ name: ccs
9
+ description: UCSC CCSRA31 ROMS 4D-Var reanalysis, California Current (eastern-boundary upwelling).
10
+
11
+ raw:
12
+ staging_glob_patterns: ["wc12_ccsra31_his_*.nc", "fwd_*_001_*.nc"] # core + ext collections
13
+ staging_dir: ccs/staging
14
+ steps_per_file: 33
15
+ time_units: "seconds since 1900-01-01 00:00:00"
16
+ calendar: gregorian
17
+ decode_times_on_read: false # staged raw numeric time (decode at ingest)
18
+ dtype_on_disk: float64
19
+
20
+ grid:
21
+ native_eta_rho: 181
22
+ native_xi_rho: 186
23
+ u_point_dims: [181, 185] # destagger xi 185 -> 186
24
+ v_point_dims: [180, 186] # destagger eta 180 -> 181
25
+ crop_eta_slice: [2, 178] # drop 3 rows NORTH (high eta) + 2 SOUTH
26
+ crop_xi_slice: [1, 185] # drop 1 col each side
27
+ cropped_h: 176
28
+ cropped_w: 184
29
+ # Scalar mean cell size over WET cells: lon 1/mean(pm) = 8686 m,
30
+ # lat 1/mean(pn) = 11113 m -> mean 9899.6 m. Kept SCALAR (parallel to the MAB
31
+ # 7000 m constant); the 0.1-deg grid is anisotropic by design. Reachability
32
+ # uses the per-axis metres from the store's pm/pn, not this scalar.
33
+ cell_size_m: 9900.0
34
+ crop_note: "drop 3 NORTH (~48N, land-heavy) + 2 SOUTH (~30N, open ocean); 1 col each side. crop wet frac 0.6559 vs full 0.6554."
35
+ metric_crop: # THE crop (mirrors the grid slices; the loader
36
+ eta: [2, 178] # asserts agreement). The CCS crop lives here
37
+ xi: [1, 185] # and nowhere else.
38
+
39
+ vertical:
40
+ native_level_count: 42 # s_w = 43 -> 42 native rho levels
41
+ staged_level_indices: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]
42
+ kept_level_indices: [3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41]
43
+ n_levels_kept: 20 # deepest staged level dropped (surface-preserving)
44
+ dropped_staged_pos: 0 # drop the deepest staged level (Cs_r = -0.9007)
45
+ surface_level_index: 19 # true surface preserved
46
+ # The CCS deepest kept Cs_r (-0.792) is SHALLOWER than MAB's (-0.9079); the
47
+ # two regions do not share a common depth axis.
48
+ cs_r_kept_note: "deepest kept Cs_r = -0.792 (vs MAB -0.9079), surface = -0.0008 (20 levels)"
49
+
50
+ channels:
51
+ dyn3d_vars: [u, v, temp, salt] # same var/level order as MAB
52
+ dyn2d_vars: [zeta, ubar, vbar]
53
+ n_dynamic_channels: 83
54
+ static_channels: 1 # mask_rho
55
+ total_in_channels: 84
56
+ total_out_channels: 84
57
+ # Same 8 rho-grid statics as MAB (all present in ccs_static.nc, which also
58
+ # carries u/v/psi masks + s-coord scalars; join against it at ingest).
59
+ static_vars_2d: [mask_rho, h, lat_rho, lon_rho, angle, pm, pn, f]
60
+ static_vars_1d: [s_rho, Cs_r]
61
+ destagger_masks: [mask_u, mask_v]
62
+
63
+ latent:
64
+ latent_h: 22 # 176 // 8
65
+ latent_w: 23 # 184 // 8
66
+ latent_channels: 84
67
+ compression_per_dim: 8
68
+ rope_spatial_grid_start_pos: [0, 0]
69
+ rope_spatial_grid_end_pos: [21, 22]
70
+ n_spatial_tokens: 506
71
+
72
+ timesplit:
73
+ cadence_hours: 6 # natively 6-hourly
74
+ internal_stride: 1 # 6 h == 1 index step (MAB's 6 must NOT be inherited)
75
+ interval_between_pred: 6
76
+ sequence_length: 5 # 1 cond + 4 pred
77
+ n_cond_frames: 1
78
+ n_pred_frames: 4
79
+ n_timesteps_total: 57441 # de-overlapped unique 6-h steps
80
+ expected_deoverlapped_steps: 57441 # hard build-time assertion target
81
+ start_time: "1980-01-09T00:00:00"
82
+ end_time: "2019-05-04T00:00:00"
83
+ # LOCKED end-loaded temporal holdout: train strictly precedes val/test; test
84
+ # (2016-2019) contiguous, never touched by training or tuning; val (2015) for
85
+ # region-specific tuning. Under any end-loaded holdout the calendar decides
86
+ # where the 2014-16 marine heatwave lands (onset in train, peak in val, decay
87
+ # in test) — a pre-registered asymmetry vs the regime-benign MAB test window.
88
+ train_year_range: [1980, 2014] # AS-RUN production split
89
+ val_year_range: [2015, 2015]
90
+ test_year_range: [2016, 2019]
91
+
92
+ dedup:
93
+ rule: later-file-wins
94
+ slice_len_steps: 16 # 4-day non-overlapping lead per file
95
+ last_file_keeps_tail: true
96
+ seam_prefers: core # float64 core over int16 ext at the 2010 seam
97
+ half_open: true
98
+
99
+ validation:
100
+ # Tuned for the upwelling regime. temp locked from the observed clean 40-yr
101
+ # full-column range (real max 26.44 C; deep floor ~1.5 C); physically
102
+ # impossible wet cells (2.7e-6 % of wet values) are CLIPPED to [0, 28] in the
103
+ # store before norm stats (datasets/clip_ccs_temp_artifacts.py).
104
+ temp_min: 0.0
105
+ temp_max: 28.0
106
+ # Surface salt reaches 24.43 PSU in the Columbia/Juan-de-Fuca plume
107
+ # (physical river/strait freshening) -> bound loosened with headroom.
108
+ salt_min: 20.0
109
+ salt_max: 36.0
110
+ zeta_abs_max: 1.5 # no tides -> small SSH (observed -0.20 .. 0.72 m)
111
+
112
+ paths:
113
+ preprocessed_zarr: ccs/ccs_his_preprocessed.zarr
114
+ pixel_norm_stats: ccs/ccs_norm_stats.json
115
+ latents_zarr: ccs/ccs_latents.zarr
116
+ latent_norm_stats: ccs/ccs_latent_norm_stats.json
117
+ static_source: ccs/staging/ccs_static.nc # CCS statics are a separate file
118
+ dcae_run_dir: dcae_ccs
119
+ denoiser_runs_dir: "."
ccs/wet_mask.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cb5549b934e3083dadcc80a34099d763a57bc713d1cba462e0eda070fc56ea51
3
+ size 129664
extras/README.md ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # Extras
2
+
3
+ Seed-1 denoisers for both regions, trained identically to the released seed-0
4
+ checkpoints; not used in any paper result.
extras/denoiser_seed1_ccs/ema.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8ce6fe7647ec51e0782dc0a8636a3ff94bae9d2823c70a2a853967fd5d900e15
3
+ size 1499773608
extras/denoiser_seed1_ccs/meta.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kind": "denoiser",
3
+ "region": "ccs",
4
+ "epoch": 8,
5
+ "val_loss": 0.25756953686475753,
6
+ "param_count": 374938452,
7
+ "source_run": "seed_001/checkpoint-best",
8
+ "ema": true,
9
+ "format": "safetensors",
10
+ "note": "trained identically with seed 1; not used in any paper result"
11
+ }
extras/denoiser_seed1_ccs/training_config.yaml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AS-RUN recipe of the released CCS denoiser checkpoints (seeds 0 and 1)
2
+ # (overlay for scripts/train_denoiser.py --region ccs --config this-file --seed {0,1}).
3
+ # Production selection: best-on-val (seed 0: epoch 6, val 0.241398;
4
+ # seed 1: epoch 8, val 0.257570); EMA weights at inference.
5
+ region: ccs
6
+ # seed: pass --seed 0 or --seed 1 (both released)
7
+
8
+ epochs: 15
9
+ lr: 1.0e-4
10
+ warmup_steps: 1000
11
+ lr_cosine_cycles: 0.5
12
+ optimizer_eps: 1.0e-8
13
+ weight_decay: 0.01
14
+ gradient_clip_norm: 1.0
15
+
16
+ train_year_range: [1980, 2014]
17
+ val_year_range: [2015, 2015]
18
+
19
+ batch_size_per_device: 4
20
+ gradient_accumulation_steps: 1
21
+ num_workers: 4
22
+
23
+ num_train_timesteps: 1000
24
+ sigma_min: 0.002
25
+ sigma_max: 80.0
26
+ sigma_data: 0.5
27
+ p_mean: -1.2
28
+ p_std: 1.2
29
+ num_push_forward_steps: 1
30
+
31
+ ema_decay: 0.9999
32
+ ema_use_warmup: true
33
+ ema_update_after_step: 1000
34
+ ema_inv_gamma: 1.0
35
+ ema_power: 0.667
36
+
37
+ mixed_precision: bf16
38
+ checkpoint_every_n_epochs: 2
39
+ keep_last_n_checkpoints: 3
40
+ save_best_val: true
41
+ val_every_n_epochs: 2
42
+ val_max_batches: 100
extras/denoiser_seed1_mab/ema.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5a7824530f39f6f4fa3f434b51332ad1c8fc10efb0bd53df4e7753e7f0df909f
3
+ size 1499773608
extras/denoiser_seed1_mab/meta.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kind": "denoiser",
3
+ "region": "mab",
4
+ "epoch": 12,
5
+ "val_loss": 0.39647472962737085,
6
+ "param_count": 374938452,
7
+ "source_run": "seed_001/checkpoint-best",
8
+ "ema": true,
9
+ "format": "safetensors",
10
+ "note": "trained identically with seed 1; not used in any paper result"
11
+ }
extras/denoiser_seed1_mab/training_config.yaml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AS-RUN recipe of the released MAB denoiser checkpoints (seeds 0 and 1)
2
+ # (overlay for scripts/train_denoiser.py --region mab --config this-file --seed {0,1}).
3
+ # Production selection: best-on-val (seed 0: epoch 10, val 0.396540;
4
+ # seed 1: epoch 12, val 0.396475); EMA weights at inference.
5
+ region: mab
6
+ # seed: pass --seed 0 or --seed 1 (both released)
7
+
8
+ epochs: 15
9
+ lr: 1.0e-4
10
+ warmup_steps: 1000
11
+ lr_cosine_cycles: 0.5
12
+ optimizer_eps: 1.0e-8
13
+ weight_decay: 0.01
14
+ gradient_clip_norm: 1.0
15
+
16
+ train_year_range: [2007, 2020]
17
+ val_year_range: [2021, 2021]
18
+
19
+ batch_size_per_device: 4
20
+ gradient_accumulation_steps: 1
21
+ num_workers: 4
22
+
23
+ # EDM training constants (Karras 2022 preconditioning; see evaluation/sampler.py)
24
+ num_train_timesteps: 1000
25
+ sigma_min: 0.002
26
+ sigma_max: 80.0
27
+ sigma_data: 0.5
28
+ p_mean: -1.2
29
+ p_std: 1.2
30
+ num_push_forward_steps: 1 # single-step training (push-forward off)
31
+
32
+ ema_decay: 0.9999
33
+ ema_use_warmup: true
34
+ ema_update_after_step: 1000
35
+ ema_inv_gamma: 1.0
36
+ ema_power: 0.667
37
+
38
+ mixed_precision: bf16
39
+ checkpoint_every_n_epochs: 2
40
+ keep_last_n_checkpoints: 3
41
+ save_best_val: true
42
+ val_every_n_epochs: 2
43
+ val_max_batches: 100
mab/dcae/ema.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3bcbee198e95a9b4f7f27fea08f7cd356f9476ef7028bb831c016d1c2530feef
3
+ size 1025594888
mab/dcae/meta.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kind": "autoencoder",
3
+ "region": "mab",
4
+ "epoch": 18,
5
+ "val_loss": 0.004576773925218731,
6
+ "param_count": 256388460,
7
+ "source_run": "dcae_pilot0/checkpoint-best",
8
+ "ema": true,
9
+ "format": "safetensors"
10
+ }
mab/dcae/training_config.yaml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AS-RUN recipe of the released MAB DC-AE checkpoint (overlay for
2
+ # scripts/train_dcae.py --region mab --config this-file).
3
+ # Production selection: best-on-val (epoch 18 of the 30-epoch pretrain,
4
+ # val_loss 0.004577); EMA weights are the inference convention.
5
+ region: mab
6
+ seed: 42
7
+
8
+ pretrain_epochs: 30
9
+ # Disabled (non-functional under DDP); production weights are
10
+ # pretrain-phase best-on-val EMA — the decoder-finetune stage was configured
11
+ # in the research run but NEVER executed.
12
+ decoder_finetune_epochs: 0
13
+ lr_pretrain: 1.0e-4
14
+ lr_finetune: 1.0e-5 # unused at finetune 0; kept for completeness
15
+ warmup_steps: 1000
16
+ lr_cosine_cycles: 0.5
17
+ optimizer_betas: [0.9, 0.999]
18
+ optimizer_eps: 1.0e-8
19
+ weight_decay: 0.01
20
+ gradient_clip_norm: 1.0
21
+
22
+ train_year_range: [2007, 2020]
23
+ val_year_range: [2021, 2021]
24
+
25
+ batch_size_per_device: 4
26
+ gradient_accumulation_steps: 1
27
+ num_workers: 4
28
+
29
+ ema_decay: 0.9999
30
+ ema_use_warmup: true
31
+ ema_update_after_step: 1000
32
+ ema_inv_gamma: 1.0
33
+ ema_power: 0.667
34
+
35
+ mixed_precision: bf16
36
+ checkpoint_every_n_epochs: 5
37
+ keep_last_n_checkpoints: 3
38
+ save_best_val: true
39
+ val_every_n_epochs: 2
40
+ val_max_batches: 200
mab/denoiser/seed0/ema.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1f4a09ac5fe18a51e561b583d5fbd56c20e7ca3cc2434300a60fa6d7623169e5
3
+ size 1499773608
mab/denoiser/seed0/meta.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "kind": "denoiser",
3
+ "region": "mab",
4
+ "epoch": 10,
5
+ "val_loss": 0.39654042705893516,
6
+ "param_count": 374938452,
7
+ "source_run": "seed_000/checkpoint-best",
8
+ "ema": true,
9
+ "format": "safetensors"
10
+ }
mab/denoiser/seed0/training_config.yaml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AS-RUN recipe of the released MAB denoiser checkpoints (seeds 0 and 1)
2
+ # (overlay for scripts/train_denoiser.py --region mab --config this-file --seed {0,1}).
3
+ # Production selection: best-on-val (seed 0: epoch 10, val 0.396540;
4
+ # seed 1: epoch 12, val 0.396475); EMA weights at inference.
5
+ region: mab
6
+ # seed: pass --seed 0 or --seed 1 (both released)
7
+
8
+ epochs: 15
9
+ lr: 1.0e-4
10
+ warmup_steps: 1000
11
+ lr_cosine_cycles: 0.5
12
+ optimizer_eps: 1.0e-8
13
+ weight_decay: 0.01
14
+ gradient_clip_norm: 1.0
15
+
16
+ train_year_range: [2007, 2020]
17
+ val_year_range: [2021, 2021]
18
+
19
+ batch_size_per_device: 4
20
+ gradient_accumulation_steps: 1
21
+ num_workers: 4
22
+
23
+ # EDM training constants (Karras 2022 preconditioning; see evaluation/sampler.py)
24
+ num_train_timesteps: 1000
25
+ sigma_min: 0.002
26
+ sigma_max: 80.0
27
+ sigma_data: 0.5
28
+ p_mean: -1.2
29
+ p_std: 1.2
30
+ num_push_forward_steps: 1 # single-step training (push-forward off)
31
+
32
+ ema_decay: 0.9999
33
+ ema_use_warmup: true
34
+ ema_update_after_step: 1000
35
+ ema_inv_gamma: 1.0
36
+ ema_power: 0.667
37
+
38
+ mixed_precision: bf16
39
+ checkpoint_every_n_epochs: 2
40
+ keep_last_n_checkpoints: 3
41
+ save_best_val: true
42
+ val_every_n_epochs: 2
43
+ val_max_batches: 100
mab/region.yaml ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MAB (Mid-Atlantic Bight; Doppio v3 ROMS reanalysis) — RegionConfig.
2
+ # AUTHORITATIVE source for every MAB dataset-specific value; parsed by
3
+ # closedloop_sampling.regions.load("mab"). Historical region name: "doppio"
4
+ # (after the dataset); load("doppio") resolves here. Paths are RELATIVE to
5
+ # ${CLOSEDLOOP_DATA_ROOT} (data) / ${CLOSEDLOOP_RUNS} or ${CLOSEDLOOP_WEIGHTS}
6
+ # (runs/weights). Values are the production pipeline's, not invented.
7
+ name: mab
8
+ description: Doppio v3 ROMS reanalysis, Mid-Atlantic Bight (western-boundary shelf).
9
+
10
+ raw:
11
+ staging_glob_patterns: ["doppio_fwd_*_plusdye.nc"]
12
+ staging_dir: mab/his_raw
13
+ steps_per_file: 72
14
+ time_units: "hours since 2007-01-02 01:00:00"
15
+ calendar: proleptic_gregorian
16
+ decode_times_on_read: true
17
+ dtype_on_disk: float32
18
+
19
+ grid:
20
+ native_eta_rho: 106
21
+ native_xi_rho: 242
22
+ u_point_dims: [106, 241] # destagger xi: xi_u = 241
23
+ v_point_dims: [105, 242] # destagger eta: eta_v = 105
24
+ crop_eta_slice: [1, 105] # 1 cell per edge -> [1:-1] on 106
25
+ crop_xi_slice: [1, 241] # [1:-1] on 242
26
+ cropped_h: 104
27
+ cropped_w: 240
28
+ cell_size_m: 7000.0
29
+ crop_note: "1 cell per edge, symmetric."
30
+ metric_crop: # THE crop (mirrors the grid slices; the loader
31
+ eta: [1, 105] # asserts agreement). Single source of truth for
32
+ xi: [1, 241] # dataloaders, truth reads, and metric domains.
33
+
34
+ vertical:
35
+ native_level_count: 40
36
+ staged_level_indices: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39]
37
+ kept_level_indices: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39]
38
+ n_levels_kept: 20 # 20 selected directly, no drop
39
+ dropped_staged_pos: null
40
+ surface_level_index: 19 # last of 20 kept
41
+ cs_r_kept_note: "deepest kept Cs_r = -0.9079, surface = -0.0 (20 levels)"
42
+
43
+ channels:
44
+ dyn3d_vars: [u, v, temp, salt] # x 20 sigma-levels = 80 channels
45
+ dyn2d_vars: [zeta, ubar, vbar] # + 3
46
+ n_dynamic_channels: 83
47
+ static_channels: 1 # mask_rho (binary wet mask)
48
+ total_in_channels: 84
49
+ total_out_channels: 84
50
+ static_vars_2d: [mask_rho, h, lat_rho, lon_rho, angle, pm, pn, f]
51
+ static_vars_1d: [s_rho, Cs_r]
52
+ destagger_masks: [mask_u, mask_v] # read per raw file for destaggering, not stored
53
+
54
+ latent:
55
+ latent_h: 13 # 104 // 8
56
+ latent_w: 30 # 240 // 8
57
+ latent_channels: 84
58
+ compression_per_dim: 8
59
+ rope_spatial_grid_start_pos: [0, 0]
60
+ rope_spatial_grid_end_pos: [12, 29]
61
+ n_spatial_tokens: 390
62
+
63
+ timesplit:
64
+ cadence_hours: 1 # hourly store
65
+ internal_stride: 6 # 6 index steps = 6 h
66
+ interval_between_pred: 6
67
+ sequence_length: 5 # 1 cond + 4 pred
68
+ n_cond_frames: 1
69
+ n_pred_frames: 4
70
+ n_timesteps_total: 157752
71
+ expected_deoverlapped_steps: null # no overlap in the raw files
72
+ start_time: "2007-01-02T01:00:00"
73
+ end_time: "2024-12-31T00:00:00"
74
+ train_year_range: [2007, 2020] # AS-RUN production split
75
+ val_year_range: [2021, 2021]
76
+ test_year_range: [2022, 2024]
77
+
78
+ dedup: null # raw files are contiguous, no overlap
79
+
80
+ validation:
81
+ temp_min: -5.0
82
+ temp_max: 45.0
83
+ salt_min: 0.0
84
+ salt_max: 45.0
85
+ zeta_abs_max: 15.0
86
+
87
+ paths:
88
+ preprocessed_zarr: mab/mab_his_preprocessed.zarr
89
+ pixel_norm_stats: mab/mab_norm_stats.json
90
+ latents_zarr: mab/mab_latents.zarr
91
+ latent_norm_stats: mab/mab_latent_norm_stats.json
92
+ static_source: mab/mab_his_preprocessed.zarr # MAB statics live inline in the store
93
+ dcae_run_dir: dcae_mab
94
+ denoiser_runs_dir: "." # denoiser_<region>/seed_* under the runs/weights root
mab/wet_mask.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3ce45a50c57f1f92d89cad4930f5fa3d57cb24964146091613f1632c424a4cb9
3
+ size 99968