Skip to content

Add NPE-PFN#1778

Open
jsvetter wants to merge 35 commits intosbi-dev:mainfrom
jsvetter:npe_pfn_dev
Open

Add NPE-PFN#1778
jsvetter wants to merge 35 commits intosbi-dev:mainfrom
jsvetter:npe_pfn_dev

Conversation

@jsvetter
Copy link
Copy Markdown
Contributor

@jsvetter jsvetter commented Feb 24, 2026

The goal of this PR is to add NPE-PFN to SBI, as discussed in #1682.

The implementation is realized mostly by three new components, which I will briefly describe in the following.
Happy to discuss all of this, as the exisiting assumptions encoded trough base classes like NeuralInference or ConditionalDensityEstimator sometimes make more and sometimes make less sense for NPE-PFN.

There are three key files that implement the method:

1.) tabpfn_flow.py implements the in-context ConditionalDensityEstimator based on the autoregressive use of TabPFN. It behaves exactly like other estimators, and given some context dataset provides sampling and log-prob functionality.

2.) npe_pfn.py implements the NPE_PFN class which, inherits from NeuralInference and implements the basic logic used across the package (append_simulations, train, build_posterior etc.). Since NPE-PFN is training free, the train method is a stub, and most functionality is handled directly by build_posterior. This allows users to call train without breaking any previous workflow, but they can also "forget" about it as would be suggested by a training-free method.

Since the TabPFN-based flow behaves like any other flow, NPE-PFN supports out-of-the-box many different types of posteriors (Direct, Rejection, IS, could add more, but inference is too slow for MCMC). However, a crucial feature of NPE-PFN is filtering, where the context dataset is selected based on a given observation.

To support this functionality, a new posterior class is required.

3.) filtered_direct_posterior.py implements this posterior (inheriting from DirectPosterior), which allows filtering based on different filters (usually KNN, but users can also provide a custom callable).

There are many other smaller changes (builders, dataclasses, etc.) and so far no tests.
Also, this PR contains the core functionality for amortized inference. More advanced stuff like sequential inference, or even support for finetuning etc. (which we didn't even do in the paper) are not added.

It probably makes sense to dicuss this approach first, before I add fine-grained tests or possibly more functionality.

Here are results for the mini benchmark:
Bildschirmfoto 2026-02-26 um 11 15 33

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 24, 2026

Codecov Report

❌ Patch coverage is 31.04396% with 251 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.29%. Comparing base (cd69050) to head (ebb9895).

Files with missing lines Patch % Lines
sbi/neural_nets/estimators/tabpfn_flow.py 21.60% 127 Missing ⚠️
sbi/inference/trainers/npe/npe_pfn.py 36.78% 55 Missing ⚠️
.../inference/posteriors/filtered_direct_posterior.py 34.32% 44 Missing ⚠️
sbi/neural_nets/net_builders/flow.py 20.00% 8 Missing ⚠️
sbi/inference/posteriors/posterior_parameters.py 53.84% 6 Missing ⚠️
sbi/utils/torchutils.py 40.00% 6 Missing ⚠️
sbi/utils/user_input_checks.py 0.00% 3 Missing ⚠️
sbi/inference/trainers/base.py 60.00% 2 Missing ⚠️

❌ Your patch check has failed because the patch coverage (31.04%) is below the target coverage (50.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1778      +/-   ##
==========================================
- Coverage   87.83%   86.29%   -1.54%     
==========================================
  Files         140      143       +3     
  Lines       12958    13313     +355     
==========================================
+ Hits        11382    11489     +107     
- Misses       1576     1824     +248     
Flag Coverage Δ
fast 81.27% <31.04%> (?)

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

Files with missing lines Coverage Δ
sbi/inference/__init__.py 100.00% <100.00%> (ø)
sbi/inference/posteriors/__init__.py 100.00% <100.00%> (ø)
.../inference/potentials/posterior_based_potential.py 96.36% <100.00%> (ø)
sbi/inference/trainers/npe/__init__.py 100.00% <100.00%> (ø)
sbi/neural_nets/factory.py 95.06% <ø> (ø)
sbi/neural_nets/net_builders/__init__.py 100.00% <ø> (ø)
sbi/neural_nets/net_builders/estimator_configs.py 100.00% <100.00%> (ø)
sbi/inference/trainers/base.py 93.59% <60.00%> (-0.51%) ⬇️
sbi/utils/user_input_checks.py 76.68% <0.00%> (ø)
sbi/inference/posteriors/posterior_parameters.py 80.88% <53.84%> (-2.86%) ⬇️
... and 5 more

Copy link
Copy Markdown
Contributor

@manuelgloeckler manuelgloeckler left a comment

Choose a reason for hiding this comment

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

Looks overall great already! I added a comment on a few minor issues.

What is currently still missing is adding some tests i.e.:

  • standard test suite for DensityEstimators here
  • add tests on device here

By keeping the context size small should allow these tests to run relatively fast, no? Otherwise we might mark most of them as slow.

Comment thread sbi/utils/torchutils.py
Comment thread pyproject.toml Outdated
Comment thread sbi/inference/trainers/npe/npe_pfn.py
Comment thread sbi/inference/trainers/npe/npe_pfn.py Outdated
Comment thread sbi/inference/trainers/npe/npe_pfn.py Outdated
Comment thread sbi/neural_nets/estimators/tabpfn_flow.py Outdated
Comment thread sbi/neural_nets/estimators/tabpfn_flow.py
Comment thread sbi/neural_nets/estimators/tabpfn_flow.py Outdated
Comment thread sbi/neural_nets/estimators/tabpfn_flow.py Outdated
Comment thread sbi/neural_nets/estimators/tabpfn_flow.py Outdated
@dgedon
Copy link
Copy Markdown
Collaborator

dgedon commented Apr 28, 2026

I addressed your comments @manuelgloeckler.

Some changes:

  • I added TabPFN as an optional dependency. This means that all imports of tabpfn had to be fail safe
  • We default to tabpfn regressor v2, not the latest version v2.6 (or v2.5). This is because from any version >2.0 there is a one time prior labs license agreement. This would mean that our automatic tests fail.

@dgedon dgedon requested a review from manuelgloeckler April 28, 2026 09:22
Copy link
Copy Markdown
Contributor

@manuelgloeckler manuelgloeckler left a comment

Choose a reason for hiding this comment

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

Thanks. Looks good overall.

We just need to add a few more tests, and fix a few problems that mostly came from merging in current main (and its corresponding changes). These problems just surfaced on running mini-sbibm, but there should be some tests in place that would catch this.

So I think mostly what is left todo is to add whole workflow tests like for other methods e.g. in linearGaussian_snpe_test.py

Comment thread .github/workflows/ci.yml Outdated
Comment thread tests/density_estimator_test.py
Comment thread sbi/neural_nets/net_builders/flow.py
Comment thread sbi/inference/trainers/npe/npe_pfn.py Outdated
@dgedon dgedon requested a review from manuelgloeckler April 29, 2026 11:41
Copy link
Copy Markdown
Contributor

@manuelgloeckler manuelgloeckler left a comment

Choose a reason for hiding this comment

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

Looks good.

I added one small full workflow tests. There is one issue with the device identification on TabPFN (see comment above). But I dont see a good way to avoid it for now.

Comment thread sbi/utils/torchutils.py
except StopIteration:
try:
return str(next(module.buffers()).device)
except StopIteration:
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.

Not entirely sure, but will this be triggered everytime a TabPFNFlow is build (as they do not have parameters, no?).

If so this warning would be a bit of spam-like as there its by design without parameters.

Note sure whats the best solution here, however.

@dgedon
Copy link
Copy Markdown
Collaborator

dgedon commented May 6, 2026

Thanks @manuelgloeckler. I did already add a full workflow test in ‎tests/posterior_nn_test.py‎‎tests/posterior_nn_test.py‎. Let me know whether that should be removed with the new cpu test that you added.

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.

3 participants