Skip to content

fix: correct biased pymc HMC sampling (target_accept)#1908

Open
janfb wants to merge 3 commits into
mainfrom
fix/pymc-c2st-flaky
Open

fix: correct biased pymc HMC sampling (target_accept)#1908
janfb wants to merge 3 commits into
mainfrom
fix/pymc-c2st-flaky

Conversation

@janfb

@janfb janfb commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #1894 because CD is failing again. Once the lockfile fix let the pymc tests run again in CD, test_c2st_pymc_sampler_on_Gaussian failed on the hmc parametrizations with c2st around 0.62.

However, it's not flaky: pymc's HamiltonianMC defaults to target_accept=0.65, which mixes poorly on this peaked Gaussian and biases the samples, regardless of seed, warmup, or number of draws. NUTS works fine.

To fix this:

  • expose seed and target_accept on PyMCSampler
  • set target_accept=0.9 for the hmc_pymc step in MCMCPosterior to get accurate HMC posteriors (c2st ~0.51 vs ~0.62); nuts_pymc/slice_pymc unchanged
  • seed + target_accept=0.95 in the c2st test for reproducible sampling

slice does not take target_accept, so it is only applied to hmc/nuts.

Note: the c2st test is marked slow, I will run the CD on this branch via workflow dispatch.

janfb added 2 commits July 1, 2026 10:59
The hmc parametrizations of test_c2st_pymc_sampler_on_Gaussian were
failing in CD (c2st ~0.62). Root cause is PyMC's HamiltonianMC default
target_accept=0.65, which mixes poorly on this peaked target regardless
of seed, warmup, or number of draws (NUTS is unaffected).

Expose seed and target_accept on PyMCSampler and set target_accept=0.95
(c2st ~0.51-0.54 across seeds and chain counts) plus a fixed seed in the
test for reproducibility.
MCMCPosterior._pymc_mcmc left PyMC's HamiltonianMC at its default
target_accept=0.65, which produces biased hmc_pymc posteriors
(c2st ~0.62 on a Gaussian). Default it to 0.9 for the HMC step, leaving
nuts_pymc and slice_pymc unchanged. hmc_pymc now samples accurately
(c2st ~0.51).
@janfb
janfb requested a review from dgedon July 1, 2026 10:00
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 87.89%. Comparing base (5f227ac) to head (2d5a99f).
⚠️ Report is 5 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
sbi/inference/posteriors/mcmc_posterior.py 87.50% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1908      +/-   ##
==========================================
+ Coverage   87.81%   87.89%   +0.07%     
==========================================
  Files         143      143              
  Lines       13387    13403      +16     
==========================================
+ Hits        11756    11780      +24     
+ Misses       1631     1623       -8     
Flag Coverage Δ
fast 81.39% <93.75%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sbi/inference/posteriors/posterior_parameters.py 83.45% <100.00%> (+0.36%) ⬆️
sbi/samplers/mcmc/pymc_wrapper.py 80.82% <100.00%> (+1.41%) ⬆️
sbi/inference/posteriors/mcmc_posterior.py 83.92% <87.50%> (+0.10%) ⬆️

... and 1 file with indirect coverage changes

step = steps[mcmc_method]

if target_accept is None and step == "hmc":
target_accept = 0.9

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably add a CHANGELOG for this. Currently it's a silent change of default values

Comment on lines +138 to +139
a higher value (e.g. 0.9-0.95) gives markedly less biased samples.
Ignored for the `"slice"` step.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably mention our new default of 0.9 here explicitly

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants