Skip to content

Fix FullSupportBarDistribution tail sampling and quantiles - #1215

Open
ppguo wants to merge 4 commits into
PriorLabs:mainfrom
ppguo:fix/full-support-tail-cdf-icdf
Open

Fix FullSupportBarDistribution tail sampling and quantiles#1215
ppguo wants to merge 4 commits into
PriorLabs:mainfrom
ppguo:fix/full-support-tail-cdf-icdf

Conversation

@ppguo

@ppguo ppguo commented Aug 27, 2026

Copy link
Copy Markdown

Summary

  • make FullSupportBarDistribution.cdf() and icdf() use the half-normal outer components already used by forward()
  • sample the outer components from their half-normal tails and keep uniform sampling for interior buckets
  • preserve batch shape, device, dtype, and temperature behavior with vectorized sampling
  • leave bounded BarDistribution unchanged

Fixes #1200

Rationale

The original PFN paper defines both bounded and infinite-support Riemann distributions (arXiv:2112.10510). FullSupportBarDistribution is the infinite-support form used by the regression checkpoints: its existing forward() already evaluates the two outer components as half-normal tails, but inherited cdf(), icdf(), and the old sample() kept all mass within the finite borders.

For a component-conditional probability r, this change uses b_1 - H_L^{-1}(1-r) in the left tail and b_{K-1} + H_R^{-1}(r) in the right tail. Interior buckets retain linear interpolation.

With borders [-2, -1, 1, 2] and component probabilities [0.25, 0.50, 0.25]:

  • before: 0/20,000 samples were outside [-2, 2], although the reported density assigns 25% mass there
  • after: 4,934/20,000 samples are outside (0.2467); empirical-CDF KS distance is 0.00716 to the documented full-support law versus 0.1266 to the old finite law
  • analytic checks now give icdf(0.125) == -2 and icdf(0.875) == 2

Public behavior

This is a public behavior correction: sample(), cdf(), quantiles, median/UCB, and the class's border translation now agree with the existing full-support log density. Samples from the outer components can now lie beyond the finite borders.

There are no function-signature, checkpoint-format, state-dict, border, component-probability, or forward()/log-density changes.

Tests

Validated in an isolated Linux CPU/CUDA environment with Python 3.10.18, PyTorch 2.6.0+cu124, pytest 8.4.2, and Ruff 0.15.12:

  • pytest tests/test_architectures/test_bar_distribution.py with CUDA excluded: 19 passed
  • pytest tests/test_architectures/test_bar_distribution.py with CPU excluded on CUDA: 19 passed
  • ruff check src/tabpfn/architectures/shared/bar_distribution.py tests/test_architectures/test_bar_distribution.py: passed
  • ruff format --check src/tabpfn/architectures/shared/bar_distribution.py tests/test_architectures/test_bar_distribution.py: passed
  • independent 20,000-sample tail-bucket audit: outside mass 0.2467, full-support KS 0.00716

tests/test_architectures/test_bar_distribution.py is the repository's existing bar-distribution test file; this PR adds the full-support regression cases there. They cover analytic tail checkpoints, CDF/ICDF round trips including probabilities 0 and 1, float32 cumulative-probability roundoff, interior buckets and borders, inherited quantile helpers and border translation, 1D and multidimensional batches, float32/float64, CPU/CUDA, and empirical tail mass/CDF. The repository's full CI suite is separate from these targeted runs.

Follow-up audit

The default regressor also has a standalone finite _cdf() path in utils.translate_probs_across_borders(), and target preprocessing can use the nonlinear safepower transform. Those paths are intentionally unchanged here so this fix stays scoped to FullSupportBarDistribution; maintainers can decide whether they should be addressed in a follow-up PR.

@CLAassistant

CLAassistant commented Aug 27, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@ppguo
ppguo marked this pull request as ready for review August 27, 2026 15:14
Copilot AI lite review requested due to automatic review settings August 27, 2026 15:14
@github-actions
github-actions Bot requested a review from eliott-kalfon August 27, 2026 15:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This pull request corrects FullSupportBarDistribution so its cdf(), icdf(), and sample() behavior matches the half-normal tail construction already implemented in forward() (log-density), bringing sampling/quantiles/CDF into agreement for infinite-support regression checkpoints.

Changes:

  • Override FullSupportBarDistribution.cdf() and icdf() to use half-normal tails in the two outer buckets while keeping interior buckets as within-bin interpolation.
  • Rework FullSupportBarDistribution.sample() to sample outer buckets from half-normal tails and interior buckets uniformly, preserving batch shape/device/dtype without Python loops.
  • Add regression tests covering analytic checkpoints, CDF/ICDF round-trips, inherited quantile helpers, border-probability translation, and sampling tail mass; add a changelog entry.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
tests/test_architectures/test_bar_distribution.py Adds regression tests ensuring full-support CDF/ICDF/sampling match the half-normal tail law and preserve shape/device/dtype.
src/tabpfn/architectures/shared/bar_distribution.py Implements full-support CDF/ICDF and vectorized tail-aware sampling for FullSupportBarDistribution.
changelog/1215.fixed.md Documents the public behavior fix for full-support CDF/quantiles/sampling.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3b4d727. Configure here.

Comment thread src/tabpfn/architectures/shared/bar_distribution.py
@oscarkey

Copy link
Copy Markdown
Contributor

hey @eliott-kalfon, I'm happy to take the review on this one, as I was assigned the original ticket, unless you would like to!

@oscarkey
oscarkey requested review from oscarkey and removed request for eliott-kalfon August 28, 2026 08:59
@eliott-kalfon

Copy link
Copy Markdown
Contributor

hey @eliott-kalfon, I'm happy to take the review on this one, as I was assigned the original ticket, unless you would like to!

Hey Oscar, that would nice thanks. Happy to double check after you too :)

@oscarkey

oscarkey commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

hey @ppguo , sorry it's taking so long for me to get to this PR, it has been a busy couple of weeks. But I will review it as soon as possible.

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.

FullSupportBarDistribution.sample()/cdf()/icdf() disagree with forward() in outer buckets

5 participants