Skip to content

research: BlackJAX adaptive-tempered SMC with gradient inner kernel (MGE) #113

Description

@Jammy2211

Overview

Stage (a) of the JAX-native posterior sampler wave (2026-07-16 deep-research shortlist). Upgrade the existing gradient-free blackjax_smc.py (adaptive-tempered SMC with an RWM inner kernel, sampling in unit-cube space via a non-differentiable pure_callback bridge) to a gradient inner kernel (MALA first, HMC behind a flag) that samples in physical-parameter space, where jax.grad of the MGE imaging likelihood is already certified OK_HMC_VIABLE (probe_grad.py). SMC is stage (a) because it yields log-evidence for free (sum of tempering log_likelihood_increment) while using gradients — the one gradient sampler that also produces logZ. Scope: MGE parametric likelihood only; pixelized work is a deferred follow-up. First stage of a 5-stage wave — issued alone; do not bulk-issue b–e.

Plan

  • Add a gradient inner-kernel SMC variant sampling in physical space (differentiable; no per-step host roundtrip), replacing the cube uniform log-prior with a JAX-native physical-space log-prior.
  • Start with MALA (cheapest gradient kernel), then HMC behind a flag, both via blackjax.adaptive_tempered_smc with inner_kernel_tuning for per-temperature step-size adaptation.
  • Preserve SMC log-evidence recovery and report it against the Nautilus / nss_jit / RWM-SMC baselines.
  • Deliverable: runnable script + smc_gradient_findings.md. Workspace-only, no library edits.
Detailed implementation plan

Affected Repositories

  • autolens_workspace_developer (primary)

Branch Survey

Repository Current Branch Dirty?
./autolens_workspace_developer main dirty (pre-existing dev-scratch under searches_minimal/; target files blackjax_smc.py/_setup.py/probe_grad.py are clean) — work runs in an isolated worktree off origin/main

Suggested branch: feature/blackjax-smc-gradient-kernel
Concurrent worktree alongside the parked pix-gradient-slogdet-revalidation claim (different files; git supports N worktrees per repo).

Implementation Steps

  1. New searches_minimal/blackjax_smc_grad.py (sibling to blackjax_smc.py, reusing _setup + _metrics.MLTracker):
    • log_likelihood(params) in physical spacemodel.instance_from_vector(vector=params, xp=jnp)analysis.log_likelihood_function(instance=…) (the probe_grad.py form; fully differentiable, no pure_callback).
    • log_prior(params) JAX-native: iterate model.priors_ordered_by_id, Gaussian→-0.5*((x-mu)/sigma)**2, Uniform→where(in-bounds,-log(width),-inf), LogUniform→log-space form; NaN masking via jnp.where at degenerate points.
    • Inner kernel: MALA (blackjax.mala) first, then HMC behind a flag, fed to blackjax.adaptive_tempered_smc via mcmc_step_fn/mcmc_init_fn, wrapped with blackjax.smc.inner_kernel_tuning for per-temperature step-size (HMC: + mass matrix / trajectory length).
    • Initial particles drawn from the prior in physical space (host-side vector_from_unit_vector at init only; hot path stays JAX-native).
  2. Time the one-shot value_and_grad compile separately (mirrors existing scripts; nss_grad baseline compile ≈ 1291 s is the figure to report/beat).
  3. Run on the standard MGE problem; write output/blackjax_smc_grad_summary.txt, regenerate the output/comparison.txt row, author smc_gradient_findings.md (physical-vs-cube design note, MALA-vs-HMC, logZ vs Nautilus, gradient-kernel viability verdict). RAL A100 fp32 GPU pass if warranted; laptop CPU fp64 for wiring smoke.

Constraints (from prior campaigns)

  • Reverse-mode gradients only; NaN-gradient degenerate points masked at the log-prior.
  • lax.map batch_size tiling (PyAutoFit#1374 lever) if particle vmap fan-out pressures memory.
  • No silent None/NaN guards — mask at the prior, let genuinely bad likelihoods crash loudly.

Key Files

  • searches_minimal/blackjax_smc.py — RWM baseline to upgrade from.
  • searches_minimal/probe_grad.py — the gradient-certified physical-space likelihood form.
  • searches_minimal/_setup.pybuild_dataset / build_model / build_analysis(use_jax=True).
  • searches_minimal/_metrics.pyMLTracker convergence metric.
  • searches_minimal/output/comparison.txt — benchmark baseline (Nautilus / nss_jit / nss_grad rows).

Original Prompt

Click to expand starting prompt (full 5-stage wave)

Research: JAX-native posterior sampler wave — implement and benchmark the ranked sampler shortlist from the 2026-07-16 deep-research session on the standard searches_minimal problem in @autolens_workspace_developer, via the sampler_pipeline ingest-prototype-profile-promote flow. Ranked stages: (a) blackjax adaptive tempered SMC upgraded to a gradient inner kernel (MALA/HMC + inner_kernel_tuning; extends the existing blackjax_smc.py RWM smoke script; gives logZ from tempering increments), (b) ChEES-HMC many-chain adaptation, (c) MCLMC + adjusted MCLMC warm-started from the multi-start Adam basin, paired with harmonic (learned harmonic mean) for evidence, (d) flowMC (normalizing-flow global jumps; multimodality insurance), (e) jaxns cameo (independent GPU-native nested-sampling cross-check vs Nautilus). Constraints from prior campaigns: reverse-mode-only gradients, NaN-gradient degenerate points need masking, vmap fan-out needs lax.map batch_size tiling (Fit#1374 lever), RAL A100 float32. Deliverable per stage: findings doc + benchmark vs Nautilus baseline. Issue stages one at a time as predecessors ship — do not bulk-issue.

This issue = stage (a) only. Scope narrowed by the user to the MGE parametric test case (gradients confirmed working); pixelized deferred to a later stage.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions