Skip to content

Add DANRA tutorial notebook with pytest-nbmake (#69) - #577

Open
Sharkyii wants to merge 33 commits into
mllam:mainfrom
Sharkyii:add-notebook-ci-nbmake
Open

Add DANRA tutorial notebook with pytest-nbmake (#69)#577
Sharkyii wants to merge 33 commits into
mllam:mainfrom
Sharkyii:add-notebook-ci-nbmake

Conversation

@Sharkyii

@Sharkyii Sharkyii commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

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

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📖 Documentation (Addition or improvements to documentation)

Checklist before requesting a review

  • My branch is up-to-date with the target branch - if not update your fork with the changes from the target branch (use pull with --rebase option if possible).
  • I have performed a self-review of my code
  • For any new/modified functions/classes I have added docstrings that clearly describe its purpose, expected inputs and returned values
  • I have placed in-line comments to clarify the intent of any hard-to-understand passages of my code
  • I have updated the README to cover introduced code changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have given the PR a name that clearly describes the change, written in imperative form (context).
  • I have requested a reviewer and an assignee (assignee is responsible for merging). This applies only if you have write access to the repo, otherwise feel free to tag a maintainer to add a reviewer and assignee.

Checklist for reviewers

Each PR comes with its own improvements and flaws. The reviewer should check the following:

  • the code is readable
  • the code is well tested
  • the code is documented (including return types and parameters)
  • the code is easy to maintain

Author checklist after completed review

  • I have added a line to the CHANGELOG describing this change, in a section
    reflecting type of change (add section where missing):
    • added: when you have added new functionality
    • changed: when default behaviour of the code has been changed
    • fixes: when your contribution fixes a bug
    • maintenance: when your contribution is relates to repo maintenance, e.g. CI/CD or documentation

Checklist for assignee

  • PR is up to date with the base branch
  • the tests pass
  • (if the PR is not just maintenance/bugfix) the PR is assigned to the next milestone. If it is not, propose it for a future milestone.
  • author has added an entry to the changelog (and designated the change as added, changed, fixed or maintenance)
  • Once the PR is ready to be merged, squash commits and merge the PR.

@Sharkyii Sharkyii changed the title Add notebook ci nbmake Add CI-tested DANRA tutorial notebook with pytest-nbmake Apr 3, 2026
@Sharkyii Sharkyii closed this Apr 3, 2026
@Sharkyii
Sharkyii deleted the add-notebook-ci-nbmake branch April 3, 2026 13:18
@Sharkyii Sharkyii reopened this Apr 3, 2026
@Sharkyii

Sharkyii commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

@sadamov once free have a look here :)

@Sharkyii Sharkyii changed the title Add CI-tested DANRA tutorial notebook with pytest-nbmake DANRA tutorial notebook with pytest-nbmake Apr 6, 2026
@sadamov
sadamov self-requested a review April 10, 2026 08:43
@sadamov sadamov self-assigned this Apr 10, 2026
@sadamov sadamov added the documentation Improvements or additions to documentation label Apr 10, 2026
@sadamov sadamov added this to the v0.7.0 milestone Apr 10, 2026
@sadamov

sadamov commented Apr 10, 2026

Copy link
Copy Markdown
Collaborator

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.

@sadamov sadamov linked an issue Apr 13, 2026 that may be closed by this pull request
@sadamov sadamov changed the title DANRA tutorial notebook with pytest-nbmake DANRA tutorial notebook with pytest-nbmake (#69) Apr 13, 2026
@sadamov sadamov changed the title DANRA tutorial notebook with pytest-nbmake (#69) Add DANRA tutorial notebook with pytest-nbmake (#69) Apr 13, 2026
@sadamov sadamov linked an issue Apr 13, 2026 that may be closed by this pull request
@Sharkyii
Sharkyii force-pushed the add-notebook-ci-nbmake branch from 68046d5 to fd789f2 Compare April 15, 2026 12:58

@sadamov sadamov left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.")

Comment thread CHANGELOG.md Outdated
Comment thread CHANGELOG.md Outdated
Comment thread pyproject.toml Outdated
Comment thread pyproject.toml Outdated
Comment thread .github/workflows/install-and-test.yml Outdated
Sharkyii and others added 2 commits April 22, 2026 14:32
Co-authored-by: sadamov <45732287+sadamov@users.noreply.github.com>
Co-authored-by: sadamov <45732287+sadamov@users.noreply.github.com>
@Sharkyii

Sharkyii commented May 8, 2026

Copy link
Copy Markdown
Contributor Author

@sadamov have a look :)

@Sharkyii

Sharkyii commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

@sadamov just have a view when free

gitcommit90 and others added 3 commits July 1, 2026 21:07
- 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
sadamov and others added 2 commits July 15, 2026 20:03
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>
sadamov and others added 8 commits July 15, 2026 21:20
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add DANRA tutorial notebook with pytest-nbmake

3 participants