Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
e8dcc66
feat: add latent encoder/decoder infrastructure for Graph-EFM port
Sir-Sloth-The-Lazy May 27, 2026
6c23ff3
Update neural_lam/models/latent/constant_encoder.py
Sir-Sloth-The-Lazy Jun 5, 2026
3cebe5a
feat: address review feedback on latent encoder/decoder infra
Sir-Sloth-The-Lazy Jun 5, 2026
df632b7
style: apply black formatting to hierarchical latent modules
Sir-Sloth-The-Lazy Jun 5, 2026
1274b02
feat: add GraphEFM single-step probabilistic predictor (PR-6)
Sir-Sloth-The-Lazy Jun 11, 2026
ea9ab9c
refactor: hard-code constrained latent GNN types, reuse existing flag…
Sir-Sloth-The-Lazy Jun 12, 2026
cd3d4f0
fix: satisfy interrogate docstring coverage from upstream main
Sir-Sloth-The-Lazy Jun 12, 2026
8f41e5e
docs: describe current code only in docstrings and comments
Sir-Sloth-The-Lazy Jun 12, 2026
0e50d9c
docs: convert latent module and make_gnn_seq docstrings to numpy style
Sir-Sloth-The-Lazy Jun 12, 2026
706fbe1
refactor: skip on-mesh/intra-level processing explicitly instead of I…
Sir-Sloth-The-Lazy Jun 12, 2026
d2d249b
docs: align ConstantLatentEncoder.compute_dist_params docstring with …
Sir-Sloth-The-Lazy Jun 12, 2026
527227c
Update neural_lam/models/latent/base_decoder.py
Sir-Sloth-The-Lazy Jun 12, 2026
b9d22ce
docs: expand parameter descriptions in latent decoder docstrings
Sir-Sloth-The-Lazy Jun 12, 2026
f38036d
docs: clarify role of grid update MLP in latent decoder forward
Sir-Sloth-The-Lazy Jun 12, 2026
c45d8ac
docs: explain mean/std chunking of decoder output parameters
Sir-Sloth-The-Lazy Jun 12, 2026
cdaa6f9
refactor: split Graph-EFM into hierarchical and flat subclasses
Sir-Sloth-The-Lazy Jun 12, 2026
0663a87
refactor: avoid processor terminology in Graph-EFM parameters
Sir-Sloth-The-Lazy Jun 12, 2026
5d1e75b
docs: document all constructor parameters in Graph-EFM subclasses
Sir-Sloth-The-Lazy Jun 12, 2026
e29e0c7
refactor: remove sample_obs_noise option from Graph-EFM
Sir-Sloth-The-Lazy Jun 12, 2026
441be4b
refactor: extract shared graph-setup helpers to remove duplication
Sir-Sloth-The-Lazy Jun 13, 2026
e12f139
refactor: give descriptive names to Graph-EFM grid embedding methods
Sir-Sloth-The-Lazy Jun 13, 2026
4a11d20
refactor: drop redundant last_state alias in Graph-EFM forward
Sir-Sloth-The-Lazy Jun 13, 2026
99d86c8
Update neural_lam/utils.py
Sir-Sloth-The-Lazy Jun 18, 2026
76c0dab
refactor: move graph-type compatibility check into GraphEFM subclasses
Sir-Sloth-The-Lazy Jun 24, 2026
3bec96c
refactor: remove stale mesh-node-index NOTE from BaseGraphEFM
Sir-Sloth-The-Lazy Jun 24, 2026
ab005c3
refactor: hoist shared prior construction into BaseGraphEFM
Sir-Sloth-The-Lazy Jun 24, 2026
00ec230
refactor: rename GraphEFMMS to GraphEFMMultiScale
Sir-Sloth-The-Lazy Jun 24, 2026
dc6600e
refactor: derive grid static dim from datastore in compute_grid_input…
Sir-Sloth-The-Lazy Jun 24, 2026
a476711
fix: handle missing static dataarray in compute_grid_input_dim
Sir-Sloth-The-Lazy Jun 24, 2026
b4f1175
Merge branch 'main' into feat/latent-encoder-decoder-infra
Sir-Sloth-The-Lazy Jun 27, 2026
1713911
feat: move training loss onto Forecaster, add probabilistic interface
Sir-Sloth-The-Lazy Jul 5, 2026
3f5402d
Address PR review: clarify scoring-rule wording, rename score_fn to s…
Sir-Sloth-The-Lazy Jul 6, 2026
987fecd
Address PR review: move loss and per_var_std onto the Forecaster
Sir-Sloth-The-Lazy Jul 8, 2026
511a6d5
Fail fast when a forecaster is missing per_var_std it needs
Sir-Sloth-The-Lazy Jul 8, 2026
56b3d6b
Rename ensemble_std to per_member_std, document mixture semantics
Sir-Sloth-The-Lazy Jul 8, 2026
d64878c
Update neural_lam/models/forecasters/probabilistic.py
Sir-Sloth-The-Lazy Jul 8, 2026
6fd050a
Leave ProbabilisticARForecaster.compute_training_loss abstract
Sir-Sloth-The-Lazy Jul 8, 2026
a1350ff
Require an explicit member count instead of a stored ensemble_size
Sir-Sloth-The-Lazy Jul 8, 2026
1cbded6
Implement ProbabilisticForecasterModule.test_step
Sir-Sloth-The-Lazy Jul 8, 2026
703e53d
Address PR review: separate ensemble RMSE from validation loss naming
Sir-Sloth-The-Lazy Jul 10, 2026
45ffdeb
Address PR review: drop redundant inline comments in probabilistic tests
Sir-Sloth-The-Lazy Jul 10, 2026
d020691
Address PR review: split ForecasterModule into an abstract base + con…
Sir-Sloth-The-Lazy Jul 10, 2026
f5c5bc0
docs: clarify GNN-type flag scope in train_model.py
Sir-Sloth-The-Lazy Jul 11, 2026
961d1f2
refactor: build the latent prior from BaseGraphEFM.__init__
Sir-Sloth-The-Lazy Jul 11, 2026
c7b7848
refactor: strip likelihood/ELBO assembly out of GraphEFMPredictor
Sir-Sloth-The-Lazy Jul 14, 2026
c086298
Merge branch 'main' into feat/latent-encoder-decoder-infra
Sir-Sloth-The-Lazy Jul 15, 2026
98ab692
Ignore .idea directory in .gitignore
Sir-Sloth-The-Lazy Jul 18, 2026
f0e01b1
Address PR review: delegate validation/test loss computation to Forec…
Sir-Sloth-The-Lazy Jul 18, 2026
8b3ab33
Address PR review: move per_var_std/config validation into the Foreca…
Sir-Sloth-The-Lazy Jul 18, 2026
7dc0b90
Address PR review: move ForecasterModules out of forecasters/ into mo…
Sir-Sloth-The-Lazy Jul 18, 2026
8a998e8
Merge branch 'main' into feat/probabilistic-forecasting-interface
Sir-Sloth-The-Lazy Jul 18, 2026
390d380
Merge branch 'main' into feat/latent-encoder-decoder-infra
Sir-Sloth-The-Lazy Jul 20, 2026
e027608
Address PR review: inline build_prior, move graph-type check to subcl…
Sir-Sloth-The-Lazy Jul 20, 2026
780941f
Address PR review: remove now-unnecessary TYPE_CHECKING guard on Base…
Sir-Sloth-The-Lazy Jul 21, 2026
b0dbea0
Merge branch 'feat/latent-encoder-decoder-infra' into feat/graph-efm-…
Sir-Sloth-The-Lazy Jul 25, 2026
d18a09b
feat: instantiate Graph-EFM model (ELBO forecaster + probabilistic co…
Sir-Sloth-The-Lazy Jul 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ tags
# Coc configuration directory
.vim
.vscode
.idea

# macos
.DS_Store
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Add `--train_steps_to_log` CLI option to log training loss for individual unroll steps, and deduplicate common prediction and loss computation steps across loops [\#674](https://github.com/mllam/neural-lam/issues/674) @GiGiKoneti

- Add a general probabilistic forecasting interface (`ProbabilisticForecaster`,
`ProbabilisticARForecaster`, `ProbabilisticForecasterModule`) and move
ownership of the training objective, scoring rule and per-variable std
from `ForecasterModule` onto the `Forecaster`.
[\#685](https://github.com/mllam/neural-lam/issues/685)
@Sir-Sloth-The-Lazy

- Add `PropagationNet` GNN layer that incentivises directional message
propagation from sender to receiver nodes, and expose it alongside
`InteractionNet` through four new CLI arguments (`--g2m_gnn_type`,
Expand Down
51 changes: 50 additions & 1 deletion neural_lam/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Standard library
import dataclasses
from pathlib import Path
from typing import Dict, Union
from typing import Dict, Optional, Union

# Third-party
import dataclass_wizard
Expand Down Expand Up @@ -116,6 +116,49 @@ class TrainingConfig:
)


@dataclasses.dataclass
class ProbabilisticConfig:
"""
Configuration for the probabilistic (Graph-EFM) models.

Only used when training or evaluating a probabilistic model
(``--model graph_efm``/``graph_efm_ms``); ignored otherwise. Every field
has a default, so the ``probabilistic`` config section may be omitted
entirely for deterministic models.

Attributes
----------
latent_dim : int, optional
Dimensionality of the latent variable at each latent-carrying mesh
node. Defaults to the model's ``hidden_dim`` when None.
prior_layers : int
Number of on-mesh GNN layers in the prior.
encoder_layers : int
Number of on-mesh GNN layers in the variational encoder.
decoder_layers : int
Number of on-mesh GNN layers in the latent decoder.
learn_prior : bool
If True, the prior is a learned encoder conditioned on the previous
state; if False, a constant ``Normal(0, 1)`` prior is used.
prior_dist : str
Output distribution of the prior: ``"isotropic"`` or ``"diagonal"``.
kl_beta : float
Weight of the KL term in the ELBO. When 0, the prior and KL are not
computed (pure auto-encoder training).
eval_ensemble_size : int
Number of ensemble members sampled during validation and testing.
"""

latent_dim: Optional[int] = None
prior_layers: int = 2
encoder_layers: int = 2
decoder_layers: int = 4
learn_prior: bool = True
prior_dist: str = "isotropic"
kl_beta: float = 1.0
eval_ensemble_size: int = 5


@dataclasses.dataclass
class NeuralLAMConfig(dataclass_wizard.JSONWizard, dataclass_wizard.YAMLWizard):
"""
Expand All @@ -133,10 +176,16 @@ class NeuralLAMConfig(dataclass_wizard.JSONWizard, dataclass_wizard.YAMLWizard):
training : TrainingConfig
Configuration for training the model, including loss function and
feature-weighting strategy. Defaults to ``TrainingConfig()``.
probabilistic : ProbabilisticConfig
Configuration for the probabilistic (Graph-EFM) models. Defaults to
``ProbabilisticConfig()`` and is ignored by deterministic models.
"""

datastore: DatastoreSelection
training: TrainingConfig = dataclasses.field(default_factory=TrainingConfig)
probabilistic: ProbabilisticConfig = dataclasses.field(
default_factory=ProbabilisticConfig
)

class _(dataclass_wizard.JSONWizard.Meta):
"""
Expand Down
2 changes: 1 addition & 1 deletion neural_lam/datastore/mdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from numpy import ndarray

# Local
from ..utils import log_on_rank_zero
from ..utils.logging import log_on_rank_zero
from .base import BaseRegularGridDatastore, CartesianGridShape


Expand Down
18 changes: 17 additions & 1 deletion neural_lam/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,32 @@
# Local
from .forecasters.autoregressive import ARForecaster
from .forecasters.base import Forecaster
from .module import ForecasterModule
from .forecasters.graph_efm import GraphEFMForecaster
from .forecasters.probabilistic import (
ProbabilisticARForecaster,
ProbabilisticForecaster,
)
from .modules.base import BaseForecasterModule
from .modules.deterministic import DeterministicForecasterModule
from .modules.probabilistic import ProbabilisticForecasterModule
from .step_predictors.base import StepPredictor
from .step_predictors.graph.base import BaseGraphModel
from .step_predictors.graph.graph_efm import GraphEFM, GraphEFMMultiScale
from .step_predictors.graph.graph_lam import GraphLAM
from .step_predictors.graph.hi_lam import HiLAM
from .step_predictors.graph.hi_lam_parallel import HiLAMParallel
from .step_predictors.graph.hierarchical import BaseHiGraphModel

# Graph-EFM models are probabilistic: train_model.py builds them with a
# config-aware, probabilistic assembly path (GraphEFMForecaster wrapped in a
# ProbabilisticForecasterModule), distinct from the deterministic models
# above. ``PROBABILISTIC_MODELS`` marks which entries take that path.
MODELS = {
"graph_lam": GraphLAM,
"hi_lam": HiLAM,
"hi_lam_parallel": HiLAMParallel,
"graph_efm": GraphEFM,
"graph_efm_ms": GraphEFMMultiScale,
}

PROBABILISTIC_MODELS = {"graph_efm", "graph_efm_ms"}
2 changes: 2 additions & 0 deletions neural_lam/models/forecasters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
# Local
from .autoregressive import ARForecaster
from .base import Forecaster
from .graph_efm import GraphEFMForecaster
from .probabilistic import ProbabilisticARForecaster, ProbabilisticForecaster
Loading
Loading