|
| 1 | +# (C) Copyright 2025 WeatherGenerator contributors. |
| 2 | +# |
| 3 | +# This software is licensed under the terms of the Apache Licence Version 2.0 |
| 4 | +# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. |
| 5 | +# |
| 6 | +# In applying this licence, ECMWF does not waive the privileges and immunities |
| 7 | +# granted to it by virtue of its status as an intergovernmental organisation |
| 8 | +# nor does it submit to any jurisdiction. |
| 9 | + |
| 10 | +embed_orientation: "channels" |
| 11 | +embed_unembed_mode: "block" |
| 12 | +embed_dropout_rate: 0.1 |
| 13 | + |
| 14 | +ae_local_dim_embed: 2048 |
| 15 | +ae_local_num_blocks: 2 |
| 16 | +ae_local_num_heads: 16 |
| 17 | +ae_local_dropout_rate: 0.1 |
| 18 | +ae_local_with_qk_lnorm: true |
| 19 | +ae_local_num_queries: 1 |
| 20 | +ae_local_queries_per_cell: false |
| 21 | + |
| 22 | +ae_adapter_num_heads: 16 |
| 23 | +ae_adapter_embed: 128 |
| 24 | +ae_adapter_with_qk_lnorm: true |
| 25 | +ae_adapter_with_residual: true |
| 26 | +ae_adapter_dropout_rate: 0.1 |
| 27 | + |
| 28 | +ae_global_dim_embed: 2048 |
| 29 | +ae_global_num_blocks: 4 |
| 30 | +ae_global_num_heads: 32 |
| 31 | +ae_global_dropout_rate: 0.1 |
| 32 | +ae_global_with_qk_lnorm: true |
| 33 | +ae_global_att_dense_rate: 1.0 |
| 34 | +ae_global_block_factor: 64 |
| 35 | +ae_global_mlp_hidden_factor: 2 |
| 36 | +ae_global_trailing_layer_norm: false |
| 37 | + |
| 38 | +ae_aggregation_num_blocks: 0 |
| 39 | +ae_aggregation_num_heads: 32 |
| 40 | +ae_aggregation_dropout_rate: 0.1 |
| 41 | +ae_aggregation_with_qk_lnorm: true |
| 42 | +ae_aggregation_att_dense_rate: 1.0 |
| 43 | +ae_aggregation_block_factor: 64 |
| 44 | +ae_aggregation_mlp_hidden_factor: 2 |
| 45 | + |
| 46 | +decoder_type: "PerceiverIOCoordConditioning" |
| 47 | +pred_adapter_kv: false |
| 48 | +pred_self_attention: true |
| 49 | +pred_dyadic_dims: false |
| 50 | +pred_mlp_adaln: true |
| 51 | +num_class_tokens: 0 |
| 52 | +num_register_tokens: 0 |
| 53 | + |
| 54 | +# number of steps offset applied to first target window; if set to zero and forecast_steps=0 then |
| 55 | +# one is training an auto-encoder |
| 56 | +fe_num_blocks: 12 |
| 57 | +fe_num_heads: 16 |
| 58 | +fe_dropout_rate: 0.1 |
| 59 | +fe_with_qk_lnorm: True |
| 60 | +fe_diffusion_latent_dim: 2048 # set to an int > ae_global_dim_embed to inflate the diffusion latent space; null = use ae_global_dim_embed |
| 61 | +fe_diffusion_model: True |
| 62 | +fe_diffusion_predict_residual: False |
| 63 | +fe_diffusion_classifier_free_guidance_prob: 0.0 |
| 64 | +fe_diffusion_model_conditioning: "forecast" # options: "date_time", "time", "forecast" |
| 65 | +fe_diffusion_model_conditioning_type: "concatenate" # options: "cross_attn", "concatenate", ..., "ada_ln" |
| 66 | +fe_layer_norm_after_blocks: [11] # Index starts at 0. Thus, [3] adds a LayerNorm after the fourth block |
| 67 | +fe_impute_latent_noise_std: 0.0 # 1e-4 |
| 68 | +fe_impute_latent_diffusion_noise_std: 1e-3 # 1e-4 |
| 69 | +# currently fixed to 1.0 (due to limitations with flex_attention and triton) |
| 70 | +forecast_att_dense_rate: 1.0 |
| 71 | +with_step_conditioning: True # False |
| 72 | +# Diffusion related parameters |
| 73 | +frequency_embedding_dim: 256 |
| 74 | +embedding_dim: 512 |
| 75 | +noise_distribution: &noise_distribution "log_uniform" # "log_uniform" or "log_normal" |
| 76 | +sigma_min: &sigma_min 0.02 |
| 77 | +sigma_max: &sigma_max 10 |
| 78 | +sigma_data: 1.0 |
| 79 | +rho: 7 |
| 80 | +p_mean: 3.5 # only required if noise_distribution is log_normal |
| 81 | +p_std: 1.2 # only required if noise_distribution is log_normal |
| 82 | + |
| 83 | +healpix_level: 5 |
| 84 | + |
| 85 | +# Use 2D RoPE instead of traditional global positional encoding |
| 86 | +# When True: uses 2D RoPE based on healpix cell coordinates (lat/lon) |
| 87 | +# When False: uses traditional pe_global positional encoding |
| 88 | +rope_2D: False |
| 89 | +# mlp_type: swiglu |
| 90 | +# use_xsa: True |
| 91 | +mlp_type: mlp |
| 92 | +use_xsa: False |
| 93 | + |
| 94 | +with_mixed_precision: True |
| 95 | +with_flash_attention: True |
| 96 | +compile_model: False |
| 97 | +with_fsdp: False |
| 98 | +attention_dtype: bf16 |
| 99 | +mixed_precision_dtype: bf16 |
| 100 | +mlp_norm_eps: 1e-5 |
| 101 | +norm_eps: 1e-4 |
| 102 | + |
| 103 | +latent_noise_kl_weight: 0.0 # 1e-5 |
| 104 | +latent_noise_gamma: 2.0 |
| 105 | +latent_noise_saturate_encodings: 5 |
| 106 | +latent_noise_use_additive_noise: False |
| 107 | +latent_noise_deterministic_latents: True |
| 108 | + |
| 109 | + |
| 110 | +#below for FE training only |
| 111 | +freeze_modules: ".*latent_pre_norm.*|.*latent_heads.*|.*pred_heads.*|.*target_token_engines.*|.*embed_target_coords.*|.*encoder.*|.*StreamEmbedder_ERA5.*|.*embed_engine.*|.*embed_engine.*|.*ae_local_engine.*|.*ae_local_global_engine.*|.*ae_global_engine.*" |
| 112 | +#below for DECODER training only |
| 113 | +# freeze_modules: ".*latent_pre_norm.*|.*latent_heads.*|.*encoder.*|.*StreamEmbedder_ERA5.*|.*embed_engine.*|.*noise_embedder.*|.*fe.*|.*ae_local_engine.*|.*ae_local_global_engine.*|.*ae_global_engine.*" |
| 114 | +#below for FE and DECODER training |
| 115 | +# freeze_modules: ".*latent_pre_norm.*|.*latent_heads.*|.*encoder.*|.*StreamEmbedder_ERA5.*|.*embed_engine.*|.*embed_engine.*|.*ae_local_engine.*|.*ae_local_global_engine.*|.*ae_global_engine.*" |
| 116 | + |
| 117 | +# load_chkpt: {'run_id': 't0bdz7qn', 'epoch': -1} # multi-var d2048 hl5, sigma_data=1.7 |
| 118 | +# load_chkpt: {'run_id': 'dcl584vo', 'epoch': -1} # z500 d2048 hl5, sigma_data=159.08 |
| 119 | +# load_chkpt: {'run_id': 'tvkicam9', 'epoch': -1} # z500 d2048 hl3 enc-lnorm, sigma_data=1.0 |
| 120 | +# load_chkpt: {'run_id': 'q9grso75', 'epoch': -1} # z500 d2048 hl3, sigma_data=39.2936 |
| 121 | +# load_chkpt: {'run_id': 'qxivdyqz', 'epoch': -1} # z500 d2048 hl5 enc-lnorm, sigma_data=1.0 |
| 122 | +# load_chkpt: {'run_id': 'h8x1qgz3', 'epoch': -1} # z500 d128 hl5, sigma_data=12.93 |
| 123 | +# load_chkpt: {'run_id': '', 'epoch': -1} # z500 d128 hl5 enc-lnorm, sigma_data=1.0 |
| 124 | +# load_chkpt: {'run_id': 'wvpb76ai', 'epoch': -1} # multi-var d2048 hl3 enc-lnorm, sigma_data=1.0 |
| 125 | +# load_chkpt: {'run_id': 'ae4wlc5m', 'epoch': -1} # multi-var d2048 hl3, sigma_data=2.7047 |
| 126 | +# load_chkpt: {'run_id': 'r45iwyns', 'epoch': -1} # multi-var d512 hl3, sigma_data=1.1785 |
| 127 | +# load_chkpt: {'run_id': 'ydka6uql', 'epoch': -1} # multi-var d512 hl4, sigma_data=0.827 |
| 128 | +# load_chkpt: {'run_id': 'lwjkb3y4', 'epoch': -1} # multi-var d512 hl5, sigma_data=0.5789 |
| 129 | +# load_chkpt: {'run_id': 'v8kd6xc1', 'epoch': -1} # multi-var d512 hl5 nopos, sigma_data=0.6481 |
| 130 | +# load_chkpt: {'run_id': 'lwjkb3y4', 'epoch': -1} # multi-var d512 hl5 enc-lnorm, sigma_data=1.0 |
| 131 | +# load_chkpt: {'run_id': 'y1gu5md8', 'epoch': -1} # multi-var d512 hl5, sigma_dqta=1.0, diffusion-full-pipeline |
| 132 | +# load_chkpt: {'run_id': 'mal6u4gc', 'epoch': -1} # multi-var d512 hl5, sigma_dqta=1.0, geoinfos 64 epochs, diffusion-full-pipeline |
| 133 | +# load_chkpt: {'run_id': 'zrpncqb0', 'epoch': -1} # multi-var d512 hl5, sigma_dqta=1.0, geoinfos 196 epochs, diffusion-full-pipeline |
| 134 | +# load_chkpt: {'run_id': 'm6fs8wvj', 'epoch': -1} # multi-var d512 hl5, sigma_data=1.0, swiglu xsa geoinfos, diffusion-full-pipeline |
| 135 | +# load_chkpt: {'run_id': 'cgxt9imf', 'epoch': -1} # diffusion model d512 to fine-tune decoder, p_mean=0.5, SwiGLU+XSA+geoinfos, based on m6fs8wvj backbone |
| 136 | +# load_chkpt: {'run_id': 'wo5mf2z4', 'epoch': -1} # diffusion model d512 to fine-tune decoder, p_mean=1.5, SwiGLU+XSA+geoinfos, based on m6fs8wvj backbone |
| 137 | +# load_chkpt: {'run_id': 'zf6wnmpe', 'epoch': -1} # multi-var d2048 hl5, sigma_data=1.832 |
| 138 | +# load_chkpt: {'run_id': 'mivw6jda', 'epoch': -1} # multi-var d2048 hl5 enc-lnorm, sigma_data=1.0 |
| 139 | +# load_chkpt: {'run_id': 'l3rxe29i', 'epoch': -1} # multi-var d2048 hl5, sigma_data=1.0, swiglu xsa geoinfos, diffusion-full-pipeline |
| 140 | +# load_chkpt: {'run_id': 'riyz96d4', 'epoch': -1} # diffusion model d2048 to fine-tune decoder, p_mean=0.5, based on l3rxe29i backbone |
| 141 | +# load_chkpt: {'run_id': 'bokn5d2w', 'epoch': -1} # diffusion model d2048 to fine-tune decoder, p_mean=1.5, based on l3rxe29i backbone |
| 142 | +# load_chkpt: {'run_id': 'uwyv1zdh', 'epoch': -1} # diffusion model d2048 to fine-tune decoder, p_mean=2.0, based on l3rxe29i backbone |
| 143 | +# load_chkpt: {'run_id': 'dvslhdp3', 'epoch': -1} # diffusion model d2048 to fine-tune decoder, p_mean=2.5, based on l3rxe29i backbone |
| 144 | +# load_chkpt: {'run_id': 'mtlfdgvh', 'epoch': -1} # diffusion model d2048 to fine-tune decoder, p_mean=3.0, based on l3rxe29i backbone |
| 145 | +# load_chkpt: {'run_id': 'jnxvjtur', 'epoch': -1} # d2048 hl5, p_mean=-2.5, forecasting |
| 146 | +# load_chkpt: {'run_id': 'ulw4wid5', 'epoch': -1} # d2048 hl5, p_mean=-2.0, forecasting |
| 147 | +# load_chkpt: {'run_id': 'lxpbthna', 'epoch': -1} # d2048 hl5, p_mean=-1.5, forecasting |
| 148 | +# load_chkpt: {'run_id': 'n1e97r8z', 'epoch': -1} # d2048 hl5, p_mean=-1.2, forecasting |
| 149 | +# load_chkpt: {'run_id': 'halvwj21', 'epoch': -1} # d2048 hl5, p_mean=-0.5, forecasting |
| 150 | +# load_chkpt: {'run_id': 'dlsp3k31', 'epoch': -1} # d2048 hl5, p_mean=0.5, forecasting |
| 151 | +# load_chkpt: {'run_id': 'ug7huxi2', 'epoch': -1} # d2048 hl5, p_mean=1.5, forecasting |
| 152 | +# load_chkpt: {'run_id': 'i3y5fhda', 'epoch': -1} # d2048 hl5, p_mean=2.5, forecasting |
| 153 | +# load_chkpt: {'run_id': 'wd0u4he8', 'epoch': -1} # d2048 hl5, p_mean=3.5, forecasting |
| 154 | +# load_chkpt: {'run_id': 'iy534ge3', 'epoch': -1} # d2048 hl5 pre-training with z, 64 epochs |
| 155 | +# load_chkpt: {'run_id': 'btnf4goa', 'epoch': -1} # d2048 hl5 pre-training with z, 128 epochs |
| 156 | +load_chkpt: {'run_id': 'c7d5iw3q', 'epoch': -1} # n320, 82 epochs |
| 157 | + |
| 158 | + |
| 159 | +norm_type: "LayerNorm" |
| 160 | + |
| 161 | +##################################### |
| 162 | + |
| 163 | +# streams_directory: "./config/streams/era5_1deg_forecasting_d2048/" |
| 164 | +# streams_directory: "./config/streams/era5_1deg_forecasting_z500/" |
| 165 | +streams_directory: "./config/streams/era5_n320_forecasting/" |
| 166 | +streams: ??? |
| 167 | + |
| 168 | +# type of zarr_store |
| 169 | +zarr_store: "zip" # "zarr" for LocalStore, "zip" for ZipStore |
| 170 | + |
| 171 | +general: |
| 172 | + |
| 173 | + # mutable parameters |
| 174 | + istep: 0 |
| 175 | + rank: ??? |
| 176 | + world_size: ??? |
| 177 | + |
| 178 | + # local_rank, |
| 179 | + # with_ddp, |
| 180 | + # data_path_*, |
| 181 | + # model_path, |
| 182 | + # run_path, |
| 183 | + # path_shared_ |
| 184 | + |
| 185 | + multiprocessing_method: "fork" |
| 186 | + |
| 187 | + desc: "" |
| 188 | + run_id: ??? |
| 189 | + run_history: [] |
| 190 | + |
| 191 | +# logging frequency in the training loop (in number of batches) |
| 192 | +train_logging: |
| 193 | + terminal: 10 |
| 194 | + metrics: 20 |
| 195 | + checkpoint: 250 |
| 196 | + log_grad_norms: False |
| 197 | + |
| 198 | +# parameters for data loading |
| 199 | +data_loading : |
| 200 | + |
| 201 | + num_workers: 12 |
| 202 | + rng_seed: ??? |
| 203 | + repeat_data_in_mini_epoch : False |
| 204 | + |
| 205 | + |
| 206 | +# config for training |
| 207 | +training_config: |
| 208 | + |
| 209 | + # training_mode: "masking", "student_teacher", "latent_loss" |
| 210 | + training_mode: ["masking","student_teacher"] # ["student_teacher", "physical_loss"] |
| 211 | + |
| 212 | + num_mini_epochs: 128 |
| 213 | + samples_per_mini_epoch: 4096 |
| 214 | + shuffle: True |
| 215 | + |
| 216 | + start_date: 1979-01-01T00:00 |
| 217 | + end_date: 2022-12-31T18:00 |
| 218 | + |
| 219 | + time_window_step: 06:00:00 |
| 220 | + time_window_len: 06:00:00 |
| 221 | + |
| 222 | + learning_rate_scheduling : |
| 223 | + lr_start: 1e-6 #5e-5 |
| 224 | + lr_max: 1e-5 #1e-4 |
| 225 | + lr_final_decay: 1e-6 |
| 226 | + lr_final: 0.0 |
| 227 | + num_steps_warmup: 64 |
| 228 | + num_steps_cooldown: 512 |
| 229 | + policy_warmup: "cosine" |
| 230 | + policy_decay: "constant" |
| 231 | + policy_cooldown: "linear" |
| 232 | + parallel_scaling_policy: "sqrt" |
| 233 | + |
| 234 | + optimizer: |
| 235 | + grad_clip: 1.0 |
| 236 | + weight_decay: 0.1 |
| 237 | + log_grad_norms: False |
| 238 | + adamw : |
| 239 | + # parameters are scaled by number of DDP workers |
| 240 | + beta1 : 0.975 |
| 241 | + beta2 : 0.9875 |
| 242 | + eps : 2e-08 |
| 243 | + |
| 244 | + losses : { |
| 245 | + #"physical": { |
| 246 | + # type: LossPhysical, |
| 247 | + # weight: 0.0, |
| 248 | + # loss_fcts: { |
| 249 | + # "mse": {}, |
| 250 | + # }, |
| 251 | + # target_and_aux_calc: "Physical", |
| 252 | + #}, |
| 253 | + "latent_diff": { |
| 254 | + type: LossLatentDiffusion, |
| 255 | + weight: 1.0, |
| 256 | + target_and_aux_calc: DiffusionLatentTargetEncoder, |
| 257 | + loss_fcts: { "mse": { }, }, |
| 258 | + } |
| 259 | + } |
| 260 | + |
| 261 | + model_input: { |
| 262 | + "forecasting" : { |
| 263 | + # masking strategy: "random", "healpix", "forecast" |
| 264 | + masking_strategy: "forecast", |
| 265 | + masking_strategy_config: { |
| 266 | + diffusion_rn: True, |
| 267 | + noise_distribution: *noise_distribution, |
| 268 | + sigma_min: *sigma_min, |
| 269 | + sigma_max: *sigma_max |
| 270 | + }, |
| 271 | + num_steps_input: 2, |
| 272 | + num_samples: 1, |
| 273 | + } |
| 274 | + } |
| 275 | + |
| 276 | + target_input: { |
| 277 | + "forecasting" : { |
| 278 | + masking_strategy: "forecast", |
| 279 | + masking_strategy_config: {diffusion_rn: True}, |
| 280 | + num_steps_input: 1, |
| 281 | + num_samples: 1, |
| 282 | + } |
| 283 | + } |
| 284 | + |
| 285 | + forecast : |
| 286 | + time_step: 06:00:00 |
| 287 | + num_steps: 1 |
| 288 | + offset: 0 |
| 289 | + policy: "fixed" |
| 290 | + |
| 291 | + |
| 292 | +# validation config; full validation config is merge of training and validation config |
| 293 | +validation_config: |
| 294 | + |
| 295 | + # Noise levels (eta values in standard normal space) at which to evaluate the |
| 296 | + # diffusion model during validation. sigma = exp(eta * p_std + p_mean). |
| 297 | + # Each value produces a separate validation pass with independently logged metrics. |
| 298 | + validation_noise_levels: [1.0, 2.0, 3.0, 4.0] |
| 299 | + |
| 300 | + samples_per_mini_epoch: 256 |
| 301 | + shuffle: True |
| 302 | + |
| 303 | + start_date: 2023-10-01T00:00 |
| 304 | + end_date: 2023-12-31T18:00 |
| 305 | + |
| 306 | + # whether to track the exponential moving average of weights for validation |
| 307 | + validate_with_ema: |
| 308 | + enabled : True |
| 309 | + ema_ramp_up_ratio: 0.09 |
| 310 | + ema_halflife_in_thousands: 1e-3 |
| 311 | + |
| 312 | + # parameters for validation samples that are written to disk |
| 313 | + output : { |
| 314 | + # number of samples that are written |
| 315 | + num_samples: 0, |
| 316 | + # write samples in normalized model space |
| 317 | + normalized_samples: False, |
| 318 | + # output streams to write; default all |
| 319 | + streams: null, |
| 320 | + } |
| 321 | + |
| 322 | + # run validation before training starts (mainly for model development) |
| 323 | + validate_before_training: False |
| 324 | + |
| 325 | + |
| 326 | +# test config; full test config is merge of validation and test config |
| 327 | +# test config is used by default when running inference |
| 328 | + |
| 329 | +# Tags for experiment tracking |
| 330 | +# These tags will be logged in MLFlow along with completed runs for train, eval, val |
| 331 | +# The tags are free-form, with the following rules: |
| 332 | +# - tags should be primitive types (strings, numbers, booleans). NO lists or dictionaries |
| 333 | +# - tags should not duplicate existing config entries. |
| 334 | +# - try to reuse existing tags where possible. MLFlow does not like having too many unique tags |
| 335 | +# - do not use long strings in values (less than 20 characters is a good rule of thumb, we may enforce this in the future) |
| 336 | +wgtags: |
| 337 | + # The name of the organization of the person running the experiment. |
| 338 | + # This may be autofilled in the future. Expected values are lowercase strings |
| 339 | + # e.g. "ecmwf", "cmcc", "metnor", "jsc", "escience" |
| 340 | + org: null |
| 341 | + # The Github issue corresponding to this run (number such as 1234) |
| 342 | + # Github issues are the central point when running experiment and contain |
| 343 | + # links to hedgedocs, code branches, pull requests etc. |
| 344 | + # It is recommended to associate a run with a Github issue. |
| 345 | + issue: null |
| 346 | + # The name of the experiment. This is a distinctive codename for the experiment campaign being run. |
| 347 | + # This is expected to be the primary tag for comparing experiments in MLFlow, along with the |
| 348 | + # issue number. |
| 349 | + # Expected values are lowercase strings with no spaces, just underscores: |
| 350 | + # Examples: "rollout_ablation_grid" |
| 351 | + exp: null |
| 352 | + # *** Experiment-specific tags *** |
| 353 | + # All extra tags (including lists, dictionaries, etc.) are treated |
| 354 | + # as strings by mlflow, so treat all extra tags as simple string key: value pairs. |
| 355 | + grid: null |
0 commit comments