Skip to content

feat(export): add MONAI bundle export - #381

Open
dhritimandas wants to merge 1 commit into
neuronets:alphafrom
dhritimandas:feat/monai-bundle-export
Open

feat(export): add MONAI bundle export#381
dhritimandas wants to merge 1 commit into
neuronets:alphafrom
dhritimandas:feat/monai-bundle-export

Conversation

@dhritimandas

@dhritimandas dhritimandas commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Summary

What: We add nobrainer export bundle. It wraps a trained model as a MONAI model-zoo bundle. MONAI Label, MONAI Deploy, and the zoo consume this format.
Why: Trained models could not leave nobrainer. The weights were a bare state_dict with nobrainer-only metadata. External tools could not load them.

Exporter (nobrainer/export/bundle.py)

  • reads a Segmentation.save() dir (model.pth + croissant.json), reconstructs via the existing Segmentation.load() strict path
  • writes LICENSE, configs/metadata.json, configs/inference.json, models/model.pt, models/model.ts (when scriptable), docs/README.md
  • all version fields read from live packages (monai.__version__, importlib.metadata); nothing hardcoded
  • spatial_shape = literal provenance block_shape with is_patch_data: true — MONAI's symbolic grammar binds only p/n and cannot express swin_unetr's real constraint (multiple of 32 AND >= 64, measured); block_shape is also the SlidingWindowInferer roi_size, so metadata and inferer cannot drift
  • torch.jit.script only; on failure warns and omits model.ts (optional per spec). --trace opt-in — segformer3d.forward has a shape-dependent branch a trace would freeze
  • self-verification before writing: two forward passes check output shape + determinism; bayesian_meshnet/bayesian_vnet ignore mc=False (genuinely stochastic) and require --allow-stochastic
  • rejects autoencoder/simsiam/dcgan/progressivegan — no (B, n_classes, D, H, W) contract
  • shells out to python -m monai.bundle verify_metadata after writing; missing-optional-import degrades to a warning

CLI + deps

  • export group + bundle subcommand in nobrainer/cli/main.py, existing conventions
  • new optional extra bundle = ["fire", "jsonschema"] — both required by MONAI's own verify_metadata; neither was declared anywhere

Test plan

  • 396 unit tests pass
  • 36 new exporter tests (ConfigParser round-trip + strict load, verify_net_in_out, script-failure path, stochastic gate, CLI contract)
  • python -m monai.bundle verify_metadata exits 0 on a fresh export
  • pre-commit clean
  • CI

Trained nobrainer models could not be consumed outside nobrainer: weights
are a bare state_dict and the architecture lives only as a registry name
in croissant.json. Export them as MONAI model-zoo bundles instead.

- nobrainer/export/bundle.py: export_bundle(), build_metadata(),
  build_inference_config(). Reads a Segmentation.save() directory and
  writes LICENSE, configs/metadata.json, configs/inference.json,
  models/model.pt, docs/README.md.
- CLI: `nobrainer export bundle MODEL_DIR OUTPUT`
- pyproject: new [bundle] extra (fire, jsonschema) — required by
  `python -m monai.bundle verify_metadata`, which the exporter shells
  out to and which fails without them.

Design notes:
- spatial_shape uses the literal block_shape from provenance, not a
  symbolic divisibility expression. MONAI's grammar binds only `p` and
  `n`, which cannot express swin_unetr's real constraint (multiple of 32
  AND >= 64). block_shape is also the SlidingWindowInferer roi_size, so
  metadata and inferer cannot drift.
- All version fields read from live packages; nothing hardcoded.
- torch.jit.script only. segformer3d/swin_unetr/bayesian nets fail to
  script (**kwargs in forward); that warns and omits models/model.ts,
  which is optional per spec. Tracing is opt-in (--trace) since it bakes
  in a fixed input shape.
- Export self-verifies with two forward passes: output shape, and a
  determinism check. bayesian_meshnet/bayesian_vnet ignore mc=False and
  are stochastic, so they require --allow-stochastic.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant