Add DANRA tutorial notebook with pytest-nbmake (#69) - #577
Conversation
|
@sadamov once free have a look here :) |
|
Okay I organized the hello_world issue and PRs:
If there was some oversight let me know, tried my best to look through all previous comms. |
68046d5 to
fd789f2
Compare
…tebooks/conftest.py with session fixture to create zarr datastore
There was a problem hiding this comment.
Thanks for taking over here @Sharkyii. We are almost done! Please see inline suggestions for CHANGELOG.md, pyproject.toml, and the workflow, plus the notebook notes below.
Make sure sure to fully render the notebook before the next review. And also track the other PRs that implement model weight loading (fixes the workaround below) and the implementation of WMG if it lands.
Notebook — please address before merging:
Cell 17 (graph visualisation): The current cell runs plot_graph via CLI and embeds the full graph_viz.html inline. The HTML is ~300 MB (g2m: 12 716 edges, m2g: 30 720 edges serialised as inline JSON) — this makes the notebook hang on render. Replace both the CLI cell and the display cell with a single Python cell that calls the plot_graph API directly, writes the full HTML for browser use, and displays a lightweight filtered view inline (M2M edges + mesh nodes only, <1 MB):
from IPython.display import HTML
from neural_lam.config import load_config_and_datastore
from neural_lam import utils
from neural_lam.plot_graph import plot_graph as _plot_graph
config_path = "tests/datastore_examples/mdp/danra_100m_winds/config.yaml"
_, datastore = load_config_and_datastore(config_path=config_path)
xy = datastore.get_xy("state", stacked=True)
grid_pos = xy / np.max(np.abs(xy))
graph_dir = os.path.join(datastore.root_path, "graph", "1level")
hierarchical, graph_ldict = utils.load_graph(graph_dir_path=graph_dir)
fig = _plot_graph(grid_pos=grid_pos, hierarchical=hierarchical, graph_ldict=graph_ldict)
fig.write_html("graph_viz.html", include_plotlyjs="cdn")
print("Full interactive graph saved to graph_viz.html — open in a browser.")
fig.data = tuple(t for t in fig.data if t.name in {"M2M", "Mesh nodes"})
display(HTML(fig.to_html(include_plotlyjs="cdn", full_html=False)))Cell 23 (sitecustomize workaround): sitecustomize.py only registers argparse.Namespace. PyTorch 2.6 also rejects all neural_lam.config dataclasses when loading a checkpoint with weights_only=True, causing _pickle.UnpicklingError. Extend the safe globals list:
from neural_lam.config import (
DatastoreSelection, ManualStateFeatureWeighting, NeuralLAMConfig,
OutputClamping, TrainingConfig, UniformFeatureWeighting,
)
torch.serialization.add_safe_globals([
argparse.Namespace, DatastoreSelection, ManualStateFeatureWeighting,
NeuralLAMConfig, OutputClamping, TrainingConfig, UniformFeatureWeighting,
])Cell 24 (eval command): --processor_layers 2 is set in the training cell but absent from the eval cell. The default is 4, so eval fails with RuntimeError: Missing key(s) in state_dict. Add --processor_layers 2 to the eval command.
Cell 25 (eval output display): The cell searches for test_rmse.pdf and pred_*.png — neither matches what eval actually writes. All outputs land as PNGs in wandb/latest-run/files/media/images/: metric plots as test_rmse_*.png, example predictions as {var}_example_*.png. No forecast zarr is produced. Replace with:
img_dir = "wandb/latest-run/files/media/images"
rmse_plots = sorted(glob.glob(os.path.join(img_dir, "test_rmse_*.png")))
if rmse_plots:
print("RMSE scorecard:", rmse_plots[0])
display(Image(filename=rmse_plots[0]))
else:
print("test_rmse plot not found — check eval output above.")
example_plots = sorted(glob.glob(os.path.join(img_dir, "*_example_*.png")))
if example_plots:
n_show = min(2, len(example_plots))
print(f"Showing {n_show} of {len(example_plots)} prediction plot(s):")
for p in example_plots[:n_show]:
print(" ", p)
display(Image(filename=p))
else:
print("No prediction plots found — check eval output above.")Co-authored-by: sadamov <45732287+sadamov@users.noreply.github.com>
Co-authored-by: sadamov <45732287+sadamov@users.noreply.github.com>
|
@sadamov have a look :) |
Co-authored-by: Hurricane <hurricane@hermes.local>
|
@sadamov just have a view when free |
- Route training and checkpoint reload through build_predictor - Omit hierarchical mesh GNN kwargs for graph_lam - Remove GraphLAM **_kwargs swallow - Add regression test for graph_lam kwargs
Round-2 review of the DANRA notebook PR. Most of these are regressions from merging main into the stale branch, not issues with the original work. - workflow: the `Run tests (excluding notebooks)` step had no `run:` and every new step gated on a non-existent `matrix.package_manager`, so `CPU+GPU testing` failed to parse (0 jobs) and the notebook CI this PR adds never ran. Collapse to a plain test step plus a push/label-gated notebook step. - notebook cell 18: pass the now-required `mesh_node_features_scaling` to `utils.load_graph` (introduced in mllam#323), which otherwise TypeErrors. - CHANGELOG: move the entries out of the frozen v0.6.0 block (they created duplicate `### Added`/`### Changed` headers) into a single consolidated `[unreleased]` entry. - pyproject: restore the `[tool.hatch.build.targets.sdist]` exclude that was dropped when `[tool.pytest.ini_options]` was moved. - train_model: import `MODELS` from `neural_lam.models` instead of redefining the registry locally. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review of the DANRA hello-world notebook: - Install: replace the executable uv-venv / pip cells (Option A/B) with a single markdown instruction using the README's `uv sync --extra cpu --group dev`. The old `uv venv --no-project` cell recreated the repo's .venv, and the parallel pip path was redundant. As markdown it no longer mutates the running env and is skipped by nbmake in CI. - Graph viz (cell 18): the plotly 3D figure needs WebGL and fails to render inline (e.g. in VSCode). Keep writing the interactive graph_viz.html for the browser, and add a lightweight static matplotlib 2D preview (mesh nodes + grid nodes + M2M edges only, dense G2M/M2G skipped) that renders anywhere without WebGL. - Versions: Python note 3.10-3.12 -> 3.10-3.14; GPU scaling tip and the mllam-data-prep hint use uv (`uv sync --extra gpu`, cu130) instead of the stale `pip install torch ... cu121`. Verified: notebook passes `pytest --nbmake` end-to-end (52s). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pull in @gitcommit90's fix for the graph_lam GNN kwarg bug (mllam#688, closes mllam#686): train_model passed hierarchical-only mesh_up/mesh_down gnn_type kwargs to every model, so `--model graph_lam` crashed with a TypeError. mllam#688 adds a `build_predictor` helper that only forwards those kwargs to hi_lam / hi_lam_parallel. This is carried here only to give the notebook a working training run. mllam#688 is the canonical fix - merge it first, then rebase/merge mllam#577 on top. Conflict resolved in tests/test_train_model_warnings.py: kept both main's test_steps_to_log_validation and mllam#688's new gnn-kwarg tests.
Make the DANRA notebook run end-to-end and render everywhere: - Run training/eval via subprocess.run(..., check=True) instead of the `!` shell escape, which silently swallowed non-zero exits (training was failing invisibly in CI and local renders). - Set MPLBACKEND=Agg for the train/eval subprocesses. The default interactive TkAgg backend aborts (Tcl_AsyncDelete, surfacing as a "double free" SIGABRT) when Lightning plots from callback threads; Agg is non-interactive and stable. - Fix stale output paths after the runs/ refactor: checkpoints under runs/<run>/checkpoints (glob runs/**/*.ckpt, raise clearly if none), eval plots under runs/<run>/wandb/.../media/images (glob runs/**/test_rmse_*.png and runs/**/*_example_*.png). - Graph viz: static matplotlib 3D preview (grid + mesh layers, no WebGL so it renders inline in VSCode) with the interactive plotly 3D below it, and the full interactive graph saved to graph_viz.html. - num_workers 0 for the single-process CPU hello-world. Verified end-to-end with pytest --nbmake (train + eval + plots, no crash). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…errors - Add .github/workflows/notebook-tests.yml: runs docs/notebooks/ via nbmake on every PR that touches neural_lam/**, docs/notebooks/**, the datastore fixtures or the lockfile (plus push to main and manual dispatch), so notebook rot from API drift is caught before merge instead of after. CPU-only, and no longer double-runs on the gpu matrix leg like the old in-job step did. - Drop the label-gated notebook step from install-and-test.yml. - train_model.main: use @logger.catch(reraise=True) so a Python error propagates (non-zero exit) instead of being logged and swallowed. Without this the notebook's subprocess.run(check=True) could not detect train/eval failures. Update the test mock to accept the parametrised decorator form. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Finalise DANRA notebook: merge-artifact fixes + polish (mllam#577)
Describe your changes
Added hello_world_danra.ipynb, an end-to-end tutorial demonstrating neural-lam training on a small DANRA dataset (data prep → graph creation → 1-epoch CPU training → evaluation). This is taken from #202, credits: @Jayant-kernel
Enabled notebook CI using pytest-nbmake; notebooks under docs/notebooks/ now run as pytest tests, with a conftest.py fixture pre-creating danra.datastore.zarr via MDPDatastore to avoid runtime downloads, and notebook logic skipping data prep if it already exists. Dev dependencies updated with nbmake>=1.5.0 and ipykernel>=6.0.0.
Issue Link
Solves #69
Type of change
Checklist before requesting a review
pullwith--rebaseoption if possible).Checklist for reviewers
Each PR comes with its own improvements and flaws. The reviewer should check the following:
Author checklist after completed review
reflecting type of change (add section where missing):
Checklist for assignee