Chapter 07 of 10

Inference

NUTS for anything quotable, mean-field SVI for iterating on priors, and why the distinction is carried on the artifact.

Two inference modes exist because they answer different questions. Preview is for the prior studio, where the analyst is still deciding what they believe and wants an answer in seconds. Full is what any reported number must come from.

full     NUTS   4 chains · 1000 warmup · 1000 draws each
                target_accept 0.9 · max_tree_depth 10
preview  SVI    AutoNormal mean-field · Adam(0.01)
                20,000 ELBO steps · 500 draws

NUTS

Initialization is at the prior median rather than a random draw. A LogNormal ROI has a long right tail, and starting in it puts the sampler where the derived coefficient is enormous — warmup then spends its budget crawling back to a sensible region instead of adapting the mass matrix.

Warmup and sampling are separate calls, and sampling is batched into roughly twenty chunks so a long fit can report where it is. NumPyro resumes from the post-warmup state exactly where it stopped, and the batched run reproduces a single fused call draw for draw — which is tested, because otherwise watching a run would be capable of changing its answer. The batching is unconditional for the same reason: if it only happened when a progress callback was attached, the registry’s reproducibility claim would depend on whether anyone was looking.

n = max(1, min(20, num_samples // 25))
while n > 1 and num_samples % n: n -= 1
Batch sizes are equal by construction; a ragged final batch is a different scan length and would cost a second JIT compilation.

source · engine/mmm/inference.py

SVI, and what it costs

The preview uses a mean-field automatic guide: every latent gets an independent normal in unconstrained space. It is fast and it is wrong in a known direction. Mean-field ignores posterior correlations, and the correlations here are the whole problem — collinear channels trade off against each other, and adstock trades off against saturation. The approximation therefore understates uncertainty, sometimes badly, and it has no chains to disagree with each other so there is no R-hat to catch it.

It is the right tool for the loop it serves: deciding whether a prior is sane does not need a calibrated interval. It is the wrong tool for anything that leaves the building, and the artifact says so.

Diagnostics

CheckMeasuresTrips atReading
R-hatWorst across all sites> 1.01 · > 1.05Above 1.01 the chains have not mixed and the posterior is not yet the posterior.
ESS bulkMinimum across sites< 400 · < 100Under 400 the point estimates carry visible Monte Carlo error.
ESS tailMinimum at the 5th/95th quantiles< 400 · < 100Interval endpoints are what this tool reports, so tail ESS matters as much as bulk.
DivergencesRate over total draws> 0.1% · > 1%The sampler could not follow the posterior’s curvature, so the region it failed in is under-represented in the answer.

Divergences are not noise

A handful of divergent transitions is routinely dismissed. It should not be: divergences are not random failures, they cluster in the part of the posterior with the sharpest curvature — which in this model is the funnel around a poorly-informed geo, or the ridge between two collinear channels. Those are precisely the regions whose shape determines the interval width being reported. A fit with divergences is under-representing the geometry that the uncertainty estimate depends on.