agentleFS
mcfrankmcfrank/claude-skills/stan-mixing-cold-start/SKILL.md

stan-mixing-cold-start

Skill12 starsChanged 19 days agoMITView on GitHub

Diagnose and fix Stan fits that completed sampling but didn't converge (high Rhat, low n_eff, treedepth saturation). The dominant cause in hierarchical model "family build" workflows is warm-starting a variant from a source posterior that pinned a parameter the target variant frees. Use whenever a fit comes back with Rhat > 1.1, n_eff < 100, large between-chain time spread, or "100% of transitions hit max treedepth" warnings.

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If yes: cold-start N+1. The source posterior is degenerate on those parameters.

    line 42
  2. Distinctive:

    If no: warm-start is fine.

    line 43
  3. Very specific:

    When recovering from a mixing failure, don't bump adapt_delta to 0.97 or max_treedepth to 12 just in case.

    line 56
  4. Distinctive:

    Don't fix the underlying boundary problem (which comes from init, not from sampler config)

    line 59
  5. Very specific:

    Default knobs (adapt_delta=0.95, max_treedepth=10) are fine.

    line 62
  6. Very specific:

    If the family driver crashed (e.g., bash set -e killed it after a bad fit), the standard recovery is:

    line 75
  7. Very specific:

    Delete the bad fit's .rds (so the driver doesn't think it's done): rm fits/<bad-tag>.rds

    line 77
  8. Very specific:

    If the family driver doesn't have skip-if-exists, add one — it makes recovery from any kind of mid-family failure trivial.

    line 80

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Stan mixing failures: the cold-start / boundary-parking pattern

Symptoms

A Stan fit that sampled all the way through but came back with:

  • Rhat 2.5–3.0 on key parameters (target: <1.05)
  • n_eff ≈ 5 (target: >>100)
  • 100% of transitions hit max treedepth=10
  • All chains had E-BFMI < 0.3 (energy diagnostic failure)
  • Large between-chain wall-clock spread during sampling — fastest chain finishes 25–50% earlier than slowest (e.g., 10 h vs 14 h)

These usually co-occur. If you see one, the others are likely true.

Most common cause: warm-start from a degenerate prior fit

Hierarchical "family build" workflows fit a sequence of nested variants — each one adds a parameter (a variance component, a slope, etc.) the previous didn't have. Warm-starting variant N+1 from variant N's posterior means initializing the newly-freed parameter at the value variant N pinned it to.

Concrete pattern (encountered in standard_model_2, May 2026):

demo_pure pins σ_α = 0. demo_alpha frees σ_α but is initialized from demo_pure's posterior, where σ_α ≈ 0. All chains then start at the σ_α = 0 boundary. The geometry there is highly correlated (σ_α and σ_r trade off ambiguously near zero), and the sampler can't escape — every transition saturates max_treedepth trying. Result: Rhat ~2.7, n_eff ~5, full treedepth saturation.

The fix is the init, not the sampler config

This is not fixed by:

  • Bumping max_treedepth (chains still can't move; they spend more time per trajectory — wall-clock goes 6–8× slower)
  • Bumping adapt_delta (smaller step, more leapfrog steps, same stuck region)
  • More warmup iters (warmup is doing the right thing; the init is wrong)

The fix is to cold-start the variant (drop init = ..., let cmdstanr draw initial values from the prior).

Policy for nested family builds

For each variant N+1, ask: does the source variant N pin (force to a specific value) any parameter that N+1 frees?

  • If yes: cold-start N+1. The source posterior is degenerate on those parameters; warm-init parks chains in a corner.
  • If no: warm-start is fine. Source posterior is in the typical set, init savings are real (~10–15% warmup reduction on big fits).

Concretely in a typical incrementally-built family:

SourceTargetPin in source?Init from source?
pure (pins σ_α=0)+α (frees σ_α)yescold-start
+α (pins κ=1)+κ (frees κ)yescold-start
+κ (pins σ_ζ=0)+σ_ζ (frees σ_ζ)yescold-start
+σ_ζ (well-mixed, all params free)+σ_s (adds onset)nowarm-start OK

Don't reach for adapt_delta / max_treedepth defensively

When recovering from a mixing failure, don't bump adapt_delta to 0.97 or max_treedepth to 12 just in case. They:

  • Cost ~6–8× per-iteration wall-clock on healthy chains
  • Don't fix the underlying boundary problem (which comes from init, not from sampler config)
  • Make it harder to tell whether the fix actually worked, because everything is slow

Default knobs (adapt_delta=0.95, max_treedepth=10) are fine. Only bump after a cold-start fit ALSO fails to converge, and you've ruled out other causes.

Spread between chain finish times is the early warning

If chain 1 finishes sampling at 10 h and chain 3 is still at 70% sampling 13 h in, you're likely already in the boundary-parking regime. Don't wait for the final summary — check Rhat from a partial chain readback, and if it's bad, abort and switch to cold-start.

ps -eo etime,cmd | grep -i stan      # remaining chain elapsed times
grep "Iteration" <log> | tail -10    # iter progression per chain

Recovering a stalled family

If the family driver crashed (e.g., bash set -e killed it after a bad fit), the standard recovery is:

  1. Delete the bad fit's .rds (so the driver doesn't think it's done): rm fits/<bad-tag>.rds
  2. Re-run the family driver. A well-written family driver should have a skip-if-exists check on fits/<tag>.rds so it picks up from the failed variant.

If the family driver doesn't have skip-if-exists, add one — it makes recovery from any kind of mid-family failure trivial. Reference pattern in standard_model_2/gcp/run_family.sh.

A note on Rhat and admin density

With sparse longitudinal data (e.g., median 3 admins/child), per-child slope parameters become weakly identified. The population-level "intercept-and-slope" decomposition shifts across data densities even when the aggregate (e.g., κ_i) distribution is the same. Don't read too much into a population-mean term shift between datasets with very different per-unit measurement density — read the aggregate.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.