Skip to content

Integrate bayesflow NLE via ONNX exporter (tutorial only)#965

Open
AlexanderFengler wants to merge 4 commits into
mainfrom
bayesflow-integration
Open

Integrate bayesflow NLE via ONNX exporter (tutorial only)#965
AlexanderFengler wants to merge 4 commits into
mainfrom
bayesflow-integration

Conversation

@AlexanderFengler
Copy link
Copy Markdown
Member

Summary

Adds docs/tutorials/bayesflow_nle_onnx_integration.ipynb — the bayesflow sibling of sbi_nle_integration.ipynb (#964). Demonstrates the full pipeline:

  1. Train a bayesflow ContinuousApproximator (CouplingFlow NLE) on synthetic DDM data.
  2. Export to ONNX via lanfactory.onnx.transform_bayesflow_to_onnx (companion LANfactory PR).
  3. Hand the file to HSSM via the identical loglik="*.onnx" / loglik_kind="approx_differentiable" gesture that sbi exports already use.
  4. Sample with numpyro NUTS and overlay the bayesflow-NLE posterior against HSSM's analytical Navarro & Fuss DDM posterior as ground truth.

Docs-only PR — no HSSM code changes.

Branch relationship — important context

This PR's branch (bayesflow-integration) is a sibling of sbi-integration (#964), not a child of it. Both target main. They can land in any order.

Decision rationale: the bayesflow tutorial doesn't depend on any HSSM-side code from #964. The two HSSM-side ONNX patches in #964 (auto-jax_enable_x64, jaxort_only_allow_initializers_as_static_args=False) are improvements that this tutorial would benefit from — but Part 1 of this notebook sets both flags explicitly so it runs standalone against current main. Once #964 lands, a small follow-up commit removes the redundant workaround lines.

Architecturally this matches reality: bayesflow and sbi are independent training frameworks whose ONNX exports converge on the same HSSM-side consumption path.

What's in this PR

File Action Purpose
docs/tutorials/bayesflow_nle_onnx_integration.ipynb new 21-cell tutorial mirroring sbi_nle_integration.ipynb's structure

Section structure:

  1. Setup (env vars, x64 enable, jaxort strict-mode relax — both flagged in Part 1 markdown as removable once Integrate sbi NRE via ONNX exporter (keystone tutorial + HSSM-side patches) #964 merges)
  2. Simulate observed DDM data via ssm-simulators
  3. Train bayesflow CouplingFlow NLE
  4. Export with transform_bayesflow_to_onnx
  5. Load into HSSM, sample with numpyro
  6. Ground-truth posterior via HSSM's analytical DDM
  7. Posterior comparison plots (analytical vs bayesflow NLE, with true values marked)

Companion PRs

v1 constraints documented in the tutorial

The CouplingFlow setup in Part 3 uses non-default values for permutation, transform, use_actnorm, and subnet_kwargs.activation. These are the v1 ONNX-friendly knobs documented in LANfactory's exporting_bayesflow_models.md. The Part 3 markdown explains each choice so readers know why their training config might differ from a "vanilla" bayesflow setup.

Test plan

🤖 Generated with Claude Code

Sibling of sbi_nle_integration.ipynb. Demonstrates the end-to-end path:
train a bayesflow CouplingFlow NLE on DDM data, export to ONNX via
lanfactory.onnx.transform_bayesflow_to_onnx (companion LANfactory PR),
and hand the file to HSSM via the same loglik="*.onnx" /
loglik_kind="approx_differentiable" gesture that sbi exports already use.
Final part overlays the bayesflow-NLE posterior against HSSM's analytical
Navarro & Fuss DDM posterior as ground truth.

Part 1 includes a temporary workaround line setting
jaxort_only_allow_initializers_as_static_args=False directly so the
notebook runs standalone on main. HSSM PR #964 sets this automatically
inside hssm.distribution_utils.onnx2jax; once it merges, the manual line
can be deleted.

This is a docs-only addition - no HSSM code changes.

Companion PRs:
- LANfactory bayesflow-connector (stacked on #79 sbi-connector)
- HSSMSpine: bayesflow-onnx-integration.md design doc +
  upstream-bugs-from-bayesflow-onnx-work.md catalog of upstream defects
  surfaced during this work

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app
Copy link
Copy Markdown

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

Replaces the hardcoded ./bayesflow_onnx_artifacts/ path in Part 4 with a
clearly-named ARTIFACT_DIR constant that defaults to ~/bayesflow_onnx_tutorial/
(outside the HSSM repo). Comment block in the cell shows two override
examples: an arbitrary user path, or tempfile.mkdtemp() for an ephemeral
demo run. Adds `import tempfile` in Part 1 so the override example works
out of the box.

Why: the previous default (./bayesflow_onnx_artifacts/) wrote into whatever
directory the notebook was running from, which for typical setups meant
docs/tutorials/ inside the HSSM repo. Re-running the notebook would
accumulate untracked artifacts in the working tree (the same pattern that
left sbi-logs/ and sbi_onnx_artifacts/ around from earlier sbi tutorial
work). Moving the default outside the repo eliminates that footgun.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new documentation tutorial notebook demonstrating how to train a BayesFlow NLE (CouplingFlow), export it to ONNX via LANfactory, and use the exported file in HSSM through the existing loglik="*.onnx" / loglik_kind="approx_differentiable" pathway, with posterior comparisons against HSSM’s analytical DDM as a reference.

Changes:

  • Add bayesflow_nle_onnx_integration.ipynb tutorial covering BayesFlow NLE → ONNX export → HSSM consumption.
  • Include a full end-to-end example (simulation, training, export, numpyro sampling, analytical comparison plots).
Comments suppressed due to low confidence (1)

docs/tutorials/bayesflow_nle_onnx_integration.ipynb:248

  • Same as above for the analytical reference model: consider setting mp_ctx="spawn" (and/or cores=1) on this sample(...) call to avoid multiprocessing issues during notebook execution on some platforms.
    "idata_analytical = model_analytical.sample(\n",
    "    sampler=\"numpyro\",\n",
    "    draws=1000,\n",
    "    tune=1000,\n",
    "    chains=2,\n",
    "    target_accept=0.9,\n",
    ")\n",

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/tutorials/bayesflow_nle_onnx_integration.ipynb Outdated
Comment on lines +83 to +90
"## Part 3 — Train a bayesflow CouplingFlow NLE on DDM simulations\n",
"\n",
"The CouplingFlow setup below is the v1 ONNX-friendly configuration documented in [LANfactory's `exporting_bayesflow_models.md`](https://github.com/lnccbrown/LANFactory/blob/main/docs/exporting_bayesflow_models.md). Three opinionated choices that aren't bayesflow's defaults:\n",
"\n",
"- `permutation=None` — `FixedPermutation` uses `keras.ops.take`, which exports as `aten::ravel`, unsupported in ONNX opset 17/20.\n",
"- `transform=AffineTransform(clamp=False)` (explicit instance) — default `clamp=True` emits `aten::asinh`. Also, `bf.networks.CouplingFlow(..., transform_kwargs={\"clamp\": False})` silently drops the kwarg (upstream bug); pass an instance.\n",
"- `activation=\"silu\"` — default `\"hard_silu\"` exports as a single fused `HardSwish` op that jaxonnxruntime can't run. Real SiLU decomposes to `Sigmoid` + `Mul`."
]
Comment on lines +152 to +159
"source": "## Part 4 — Export the trained approximator to ONNX\n\nOne call. The exporter raises clearly if any v1 constraint is violated (wrong `KERAS_BACKEND`, non-identity adapter, missing `inference_network`).\n\n**Where to write the file.** The cell below sets `ARTIFACT_DIR` to `~/bayesflow_onnx_tutorial/` — outside the HSSM repo, so re-running the notebook doesn't leave artifacts in your working tree. Change it to any path you want to keep the trained ONNX around for downstream work; set it to `tempfile.mkdtemp()` for an ephemeral demo run."
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": "# User-configurable: where the .onnx file lands. Default is outside the HSSM\n# repo so notebook re-runs don't pollute the working tree.\n# Override examples:\n# ARTIFACT_DIR = Path(\"/path/to/my/project/onnx\") # keep nearby\n# ARTIFACT_DIR = Path(tempfile.mkdtemp()) # ephemeral\nARTIFACT_DIR = Path.home() / \"bayesflow_onnx_tutorial\"\nARTIFACT_DIR.mkdir(parents=True, exist_ok=True)\nonnx_path = ARTIFACT_DIR / \"ddm_nle.onnx\"\n\ntransform_bayesflow_to_onnx(\n approximator,\n str(onnx_path),\n mode=\"nle\",\n example_theta_dim=len(DDM_PARAM_NAMES),\n example_x_dim=2,\n)\nprint(f\"wrote {onnx_path} ({onnx_path.stat().st_size:,} bytes)\")"
Comment thread docs/tutorials/bayesflow_nle_onnx_integration.ipynb
Comment on lines +1 to +6
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
AlexanderFengler and others added 2 commits May 22, 2026 18:51
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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.

2 participants