v0.5.0
Highlights
Three independent extensions to the v0.4.0 API surface, all backward-compatible at their default values.
Inverse-temperature beta everywhere it has a unique physical meaning. A single beta knob (defaulting to 1.0) joins the four KL losses, langevin / hmc, and Gaussian.samples; importance_weights{,_log} get two betas (beta_source / beta_target) for tempered SMC ladder rungs.
loss.compile split into compile_raw / compile_beta.
compile_raw(loss_fn, *captured)— single-input fast path, returned closure is(x_batch) -> scalar, every non-batch argument baked in as a Python closure constant. No wrapper / no per-callas_tensor, lowest-overhead choice for fixed-betatraining.compile_beta(loss_fn, *captured)— same captured-once trick but the closure exposes(x_batch, beta=1.0) -> scalar. A 0-d-tensor cast at the boundary keeps Dynamo from value-specializing on the Python float, so a single compiled artifact handles every value ofbeta. Use for annealed / adaptive schedules.- The old
loss.compilename is gone; both helpers live inzflows.lossand can be imported directly:from zflows.loss import reverse_KL, compile_raw.
RealNVP learnable linear mixing (Glow-style 1×1 conv). New optional mixing: str | None = None kwarg interleaves a learnable mixing=\"rotation\" is an orthogonal mixing=\"lu\" is a PLU map whose learnable None keeps the byte-exact pre-mixing architecture.
Smaller additions
-
Linear_Combinationgeneralised from the two-potential form to an N-potential form:Linear_Combination([U_0, U_1, ...], [c_0, c_1, ...]). Coefficients can also be a 1-dtorch.Tensor, registered as annn.Modulebuffer so.to(device)follows them in lockstep with the potentials. - New utility helpers in
zflows.utils:suppress_warnings(),set_cache_size_limit(N),check_compile_available()— three one-shot calls to silence Triton / Inductor / Dynamo / Python chatter, give Dynamo more cache headroom, and verify the compile toolchain. -
randmask: bool = Trueis now the default per-layer feature ordering forNSF/NCSF/RealNVP(freshtorch.randperm(d)each layer);randmask=Falseswitches back to the legacyarange / arange.flipalternation. -
Gaussian.samples(N, beta=1.0)draws from the tempered$\mathcal N(\mu, \Sigma / \beta)$ .
Documentation
- README gains a Guidance on choosing flow classes subsection (comparison table of NSF / NCSF / RealNVP / CNF + decision-tree code snippet), a section on the unified
Potentialclass with thesuper().__init__()safety warning, install step 4 forcheck_compile_available(), and FAQ entries on conditional flows and JAX alternatives. - New benchmark writeup
tests/compare_compiled_loss.md:compile_rawvs. rawreverse_KLacross adimension × hidden_featuresgrid on an RTX 5070 Ti — 4–10× per-step speedup withmode='default', up to ~13× withmode='reduce-overhead'.
Verification
The test suite was consolidated into three banner-separated harnesses, all CPU-runnable, no external fixtures:
tests/_verify_flows.py— 14 sections covering construction, round-trip bijection,.zeros()identity,call_and_ladjvs autogradslogdet, NSF/NCSF box preservation, RealNVP forward+inverse ladj cancellation, CNF Hutchinson unbiasedness, the newRealNVPmixing layers, and thecompile_raw/compile_betacache-stability check.tests/_verify_potential.py—Potential.enable_eval/Linear_Combination/Gaussian.samples(beta)checks.tests/_verify_utils.py— tamed Langevin, HMC, L-BFGS, and the new beta-tempered-stationary / IS-linearity-in-beta checks.
Plus a tests/_all.py runner that executes every demo under MPLBACKEND=Agg.
Dependencies
Unchanged: `torch>=2.10.0`, `numpy>=2.4.0`. `numpy` is only used in `zflows/core/numerics.py` for a one-shot `np.polynomial.legendre.leggauss` call (cached), so the runtime footprint is the same as v0.4.0.
🤖 Generated with Claude Code