Skip to content

research: JAX autodiff gradients audit across likelihoods #87

Description

@Jammy2211

Overview

Audit JAX autodiff support across the PyAutoLens likelihoods so gradient-based inference (NUTS/HMC via BlackJAX, gradient-aware nested sampling) stands on validated ground. Covers parametric light profiles (Sérsic, linear Sérsic, MGE), pixelized source reconstructions (Delaunay, rectangular), the point-source source-plane χ², and the weak-lensing likelihood. Deliverables are a per-likelihood gradient status report, autodiff-vs-finite-difference correctness tests (none exist today — current jax_grad/ scripts assert finiteness only), and documented root causes where differentiation breaks.

Plan

  • Build a shared finite-difference comparison helper in autolens_workspace_test/scripts/jax_grad/ (vmap-honest evaluation so pure_callback const-folding can't fake results).
  • Phase 1 — light profiles: re-run existing gradient probes on current mains; upgrade imaging_lp.py/imaging_mge.py from finiteness-only to FD-correctness; add a standard (non-linear) Sérsic case; document any breaks.
  • Phase 2 — pixelized sources: re-confirm and write up why full Delaunay gradients are infeasible today (scipy pure_callback has no JVP rule); validate rectangular-mesh gradients vs FD, characterising the intentional stop_gradient approximation (anchor paper: https://arxiv.org/abs/2606.30620); check gradient flow through the NNLS solve.
  • Phase 3 — validate point-source source-plane χ² gradients (they work under value_and_grad despite the forward-JIT blocker) and probe + validate the weak-lensing FitWeak likelihood (xp=jnp path exists, never gradient-probed).
  • Wrap-up: audit README in jax_profiling/gradient/, follow-up tasks (e.g. Delaunay custom_jvp, Grid2DIrregular xp gap) filed as ideas, not fixed here.
Detailed implementation plan

Affected Repositories

  • autolens_workspace_developer (primary — gradient probes + audit report)
  • autolens_workspace_test (FD correctness tests)
  • Read-only: PyAutoArray, PyAutoGalaxy, PyAutoLens, autolens_profiling (claimed by in-flight tasks; any library fix escalates as a follow-up task)

Branch Survey

Repository Current Branch Dirty?
./autolens_workspace_developer main 1 untracked
./autolens_workspace_test main clean
./autolens_profiling main claimed: profiling-preopt-campaign
./PyAutoArray main claimed: nnls-solver-optimization

Suggested branch: feature/jax-autodiff-gradients-audit
Worktree: ~/Code/PyAutoLabs-wt/jax-autodiff-gradients-audit/

Implementation Steps

  1. Shared FD helper autolens_workspace_test/scripts/jax_grad/util.py: central finite differences of the log-likelihood per model parameter (step scaled to parameter magnitude), compared to jax.grad with per-parameter rel/abs tolerance report; evaluate via vmapped fitness (fitness._vmap), never single-JIT on concrete arrays.
  2. Phase 1: re-run autolens_workspace_developer/jax_profiling/gradient/imaging/mge.py and autolens_workspace_test/scripts/jax_grad/{imaging_lp,imaging_mge}.py on current mains; upgrade both jax_grad scripts to FD comparison; add lp.Sersic (standard, non-linear) coverage alongside lp_linear.Sersic and MGE; document tracing/differentiation breaks with file:line root cause.
  3. Phase 2a (Delaunay): reproduce the 3 PASS / 8 ERROR result of jax_profiling/gradient/imaging/delaunay.py — root cause jax.pure_callbackscipy.spatial.Delaunay at PyAutoArray/autoarray/inversion/mesh/interpolator/delaunay.py:80, no JVP rule; write up why full gradients are infeasible (frozen triangulation = discrete combinatorial structure; a custom_jvp zero-rule unblocks the chain but leaves mesh-position derivatives undefined at cell boundaries).
  4. Phase 2b (rectangular): read arXiv:2606.30620 first; validate existing gradients vs FD, explicitly characterising which parameter directions the lax.stop_gradient in create_transforms drops; add jax_grad/imaging_pixelization.py with tolerances informed by that analysis.
  5. Phase 2c: gradient flow through the linear-inversion NNLS/fnnls solve — extend the existing solver-level guard jax_assertions/nnls.py, don't duplicate it.
  6. Phase 3a: jax_grad/point_source.py — FD-validate FitPositionsSource.log_likelihood gradients including the magnification-via-Hessian term.
  7. Phase 3b: new probe jax_profiling/gradient/weak/likelihood.py (FitWeak, xp=jnp) + jax_grad/weak.py FD test.
  8. Wrap-up: per-likelihood status README (jax_profiling/gradient/README.md), follow-up ideas filed to the backlog, ship both workspace repos.

Key Files

  • autolens_workspace_developer/jax_profiling/gradient/ — existing step-by-step value_and_grad probes (imaging mge/pixelization/delaunay, interferometer mge, point_source ×2); docstrings hold prior findings to re-validate.
  • autolens_workspace_test/scripts/jax_grad/{imaging_lp,imaging_mge}.py — finiteness-only tests to upgrade.
  • autolens_workspace_test/scripts/jax_assertions/nnls.py — solver-level finite-grad guard to extend.
  • PyAutoLens/autolens/weak/fit.py — FitWeak, traceable with xp=jnp, pytree registered (read-only).
  • PyAutoArray/autoarray/inversion/mesh/interpolator/{delaunay,rectangular}.py — the two gradient-killers/fixes under audit (read-only).

Verification

  • Every new/upgraded jax_grad/ script runs green from the autolens_workspace_test root on CPU JAX; existing finiteness checks keep passing.
  • FD agreement reported per parameter; intentional stop_gradient deviations documented with measured magnitude, not hidden by loose tolerances.
  • Delaunay failure reproduced on current mains before being documented as current fact.

Original Prompt

Click to expand starting prompt

You're working in the PyAutoLens or PyAutoArray codebase, using the usual profiling workspace, profiling agent, and PyAutoBrain flow. First, investigate the state of JAX autodiff support for Sérsic light profiles, linear Sérsic light profiles, and Multi-Gaussian Expansion light profiles. Profile what's there, identify what breaks tracing or differentiation, and add or refine automated tests comparing autodiff against finite differences. Second, investigate gradients for pixelized source reconstructions, starting with the Delaunay mesh. We expect that full gradients may not be feasible there. Confirm why and document where it fails. Then move to the rectangular mesh, where we think gradients might be possible. Before starting that part, ask me for the relevant paper if you don't already have it. Third, validate gradients for the source plane chi-squared used for point sources, and for the weak lensing likelihood.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions