Skip to content

Rename Predictive's exclude_deterministic to condition_deterministic - #2259

Open
Agi-Asi wants to merge 1 commit into
pyro-ppl:masterfrom
Agi-Asi:feat/condition-deterministic-rename
Open

Rename Predictive's exclude_deterministic to condition_deterministic#2259
Agi-Asi wants to merge 1 commit into
pyro-ppl:masterfrom
Agi-Asi:feat/condition-deterministic-rename

Conversation

@Agi-Asi

@Agi-Asi Agi-Asi commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Implements the rename discussed in #2086: Predictive's exclude_deterministiccondition_deterministic (name suggested by @kylejcaron, endorsed by @juanitorduz).

Why: the old name reads as if it filters deterministic sites out of the returned dictionary, but it actually controls whether deterministic sites in posterior_samples are conditioned on during substitution — the returned sites are governed by return_sites. That mismatch is exactly what confused the issue reporter (and, per the thread, the argument's own author).

What this PR does:

  • New keyword condition_deterministic: bool = False — the default is behaviour-identical to the old exclude_deterministic=True default, so nothing changes for existing users.
  • Full backward compatibility: exclude_deterministic= is still accepted (mapped to not condition_deterministic) with a FutureWarning; passing both raises ValueError. The predictive.exclude_deterministic attribute is kept as a deprecated property (getter + setter) so code that flips it after construction keeps working.
  • Docstring rewritten to say what the flag actually does, point at return_sites for output filtering, and explain why conditioning on deterministic sites is off by default (shape/staleness bugs when predicting on new data — see numpyro.deterministic static on infer.Predictive #1772).
  • Tests: deprecation warnings for kwarg/getter/setter, both-kwargs ValueError, default value, and the existing discrete-predictive test migrated to the new name.

Note: MCMC.print_summary(exclude_deterministic=...) is a different API where the name is accurate (it filters printed output), so it is deliberately untouched.

ruff check, ruff format --check, and ty check all pass; relevant test selection (18 predictive tests) passes locally.

Closes #2086

Issue pyro-ppl#2086 reported that Predictive.exclude_deterministic reads as if
it controls which sites are returned, when it actually controls whether
deterministic sites in posterior_samples are conditioned on during
substitution. Maintainers converged on the clearer name
condition_deterministic (suggested by kylejcaron, endorsed by
juanitorduz).

- new keyword condition_deterministic (default False, same behaviour
  as the old default exclude_deterministic=True)
- exclude_deterministic kwarg still accepted with a FutureWarning;
  passing both raises ValueError
- exclude_deterministic attribute kept as a deprecated property
  (getter and setter) so existing code that flips it keeps working
- docstring now explains what the flag actually does, points to
  return_sites for output filtering, and documents why conditioning
  on deterministic sites is off by default (shape/staleness bugs,
  see pyro-ppl#1772)
- tests for the deprecation path, both-kwargs error, and default

Closes pyro-ppl#2086
@github-actions github-actions Bot added the awaiting review Awaiting review from maintainers label Aug 28, 2026
@github-actions

Copy link
Copy Markdown

Benchmark report

this PR feat/condition-deterministic-rename at ece8672c vs baseline master at 0059d3af

- run time:     1 slower, 1 faster
  compile time: unchanged across 32 benchmarks

Significant changes (2)

                     ─────── run time ───────     ────── compile time ─────
  benchmark          baseline  this PR      Δ     baseline   this PR      Δ
───────────────────────────────────────────────────────────────────────────
+ dirichlet_sample    50.0 ms  45.8 ms  -8.5%     854.8 ms  884.1 ms  +3.4%
- normal_sample       22.3 ms  23.5 ms  +5.4%     209.4 ms  209.3 ms  -0.0%

Red is slower, green is faster; a row is coloured by the worse of its two columns. A delta in parentheses cleared the threshold on a measurement below the resolution floor, so it is shown without being called a change. † marks a benchmark that could not be compared — see below.

Full results

distributions

                                 ──────── run time ────────     ────── compile time ──────
  benchmark                      baseline  this PR        Δ     baseline   this PR       Δ
──────────────────────────────────────────────────────────────────────────────────────────
  biject_to_constraints            4.1 ms   4.0 ms    -1.6%     349.5 ms  363.2 ms   +3.9%
  categorical_log_prob             2.0 ms   2.1 ms    +2.6%      74.0 ms   68.0 ms   -8.1%
  dirichlet_log_prob               631 µs   652 µs    +3.3%     428.3 ms  473.8 ms  +10.6%
+ dirichlet_sample                50.0 ms  45.8 ms    -8.5%     854.8 ms  884.1 ms   +3.4%
  gamma_log_prob                   2.1 ms   2.2 ms    +3.8%       2.36 s    2.48 s   +5.0%
  gamma_sample                    21.5 ms  21.6 ms    +0.2%     827.2 ms  853.0 ms   +3.1%
  lkj_cholesky_sample              5.2 ms   5.4 ms    +4.2%       1.21 s    1.20 s   -0.9%
  mixture_same_family_log_prob     989 µs   995 µs    +0.7%      81.5 ms   84.0 ms   +3.1%
  multivariate_normal_log_prob     269 µs   257 µs    -4.2%     167.5 ms  155.2 ms   -7.4%
  normal_log_prob                  736 µs   694 µs  (-5.7%)      57.4 ms   57.7 ms   +0.6%
- normal_sample                   22.3 ms  23.5 ms    +5.4%     209.4 ms  209.3 ms   -0.0%
  stick_breaking_transform         6.3 ms   6.3 ms    +0.3%     208.1 ms  222.7 ms   +7.0%
  student_t_log_prob               3.1 ms   3.1 ms    +0.8%      78.2 ms   77.6 ms   -0.8%
  truncated_normal_log_prob        715 µs   743 µs    +3.9%      53.4 ms   56.4 ms   +5.6%

handlers

                                  ───────── run time ─────────     ────── compile time ──────
  benchmark                       baseline   this PR         Δ     baseline   this PR       Δ
─────────────────────────────────────────────────────────────────────────────────────────────
  initialize_model_hierarchical    44.3 ms   43.2 ms     -2.4%       3.51 s    3.49 s   -0.6%
  log_density_hierarchical          3.8 ms    3.7 ms     -1.1%       1.09 s    1.09 s   -0.2%
  nested_handler_stack              1.4 ms    1.4 ms     +1.4%       557 µs    531 µs   -4.7%
  potential_energy_and_grad          27 µs     22 µs  (-18.8%)     102.5 ms  100.3 ms   -2.2%
  predictive_forward_sampling     720.7 ms  718.0 ms     -0.4%     228.7 ms  197.5 ms  -13.6%
  trace_seeded_model                820 µs    841 µs     +2.6%     522.8 ms  528.3 ms   +1.1%

mcmc

                             ──────── run time ───────     ────── compile time ─────
  benchmark                  baseline   this PR      Δ     baseline  this PR       Δ
────────────────────────────────────────────────────────────────────────────────────
  hmc_logistic_regression    734.8 ms  741.7 ms  +1.0%       3.01 s   3.07 s   +2.1%
  nuts_dense_mass_funnel       1.16 s    1.16 s  -0.7%       2.45 s   2.42 s   -1.2%
  nuts_eight_schools           1.16 s    1.16 s  -0.6%       2.28 s   2.26 s   -0.7%
  nuts_hierarchical_glm        4.89 s    4.87 s  -0.3%       6.19 s   4.79 s  -22.6%
  nuts_logistic_regression     1.09 s    1.08 s  -0.6%       3.11 s   3.08 s   -0.9%
  nuts_vectorized_chains       2.56 s    2.57 s  +0.2%       2.80 s   2.75 s   -1.8%

svi

                                             ──────── run time ───────     ───── compile time ─────
  benchmark                                  baseline   this PR      Δ     baseline  this PR      Δ
───────────────────────────────────────────────────────────────────────────────────────────────────
  svi_autodelta_map_logistic                 317.3 ms  325.1 ms  +2.4%       3.18 s   3.02 s  -5.1%
  svi_autodiagonalnormal_hierarchical          1.06 s    1.06 s  -0.0%       4.84 s   4.84 s  +0.1%
  svi_automultivariatenormal_eight_schools   779.8 ms  762.8 ms  -2.2%       3.61 s   3.68 s  +2.1%
  svi_autonormal_logistic                    767.7 ms  766.5 ms  -0.2%       3.18 s   3.27 s  +3.0%
  svi_multi_particle_elbo                      1.51 s    1.50 s  -0.5%       3.22 s   3.31 s  +2.6%
  svi_trace_mean_field_elbo                    1.34 s    1.34 s  +0.1%       4.95 s   4.94 s  -0.2%
Methodology and environment

Each benchmark is set up untimed, then called once with the JAX caches cleared and several more times warm. Run is the fastest warm call; compile is the first call minus that, i.e. the tracing, lowering and XLA compilation the warm calls did not have to pay for.

Both refs were measured on the same runner over 2 interleaved round(s), taking the best observation per benchmark. A result is called neutral when it moves less than ±5% (run) or ±25% (compile), or when the measurement itself is under 1 ms (run) / 50 ms (compile) — a shared CI runner cannot resolve changes below that. Compile time gets the looser band because it is measured once per round rather than best-of-N, and swings by roughly 20% even between two runs of identical code. A delta shown in parentheses did clear its threshold, but on a measurement below the resolution floor, so it is reported without being called a change.

baseline this PR
ref master feat/condition-deterministic-rename
commit 0059d3af ece8672c
numpyro 0.21.0 0.21.0
jax 0.11.1 0.11.1
backend cpu cpu
python 3.14.7 3.14.7

Runner: Linux-6.17.0-1022-azure-x86_64-with-glibc2.39, 4 CPUs.

Produced by this benchmark run.

@juanitorduz juanitorduz left a comment

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.

I like the suggestion :) It is clearer

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

Labels

awaiting review Awaiting review from maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Predictive.exclude_deterministic does not filter deterministic sites

2 participants