Skip to content

fix(classifier): honour PASSTHROUGH_INF in predict_proba_batched - #1351

Open
aniruddhaadak80 wants to merge 3 commits into
PriorLabs:mainfrom
aniruddhaadak80:fix/batched-passthrough-inf
Open

aniruddhaadak80 wants to merge 3 commits into
PriorLabs:mainfrom
aniruddhaadak80:fix/batched-passthrough-inf

Conversation

@aniruddhaadak80

Copy link
Copy Markdown
Contributor

Issue

Fixes #1346

Motivation and Context

predict_proba_batched calls clean_data_transform without passthrough_inf, so an explicit inference_config={"PASSTHROUGH_INF": True} is silently ignored on that path.

Batched path (classifier.py ~1260):

python X_test = clean_data_transform( X_test, cat_indices=worker.inferred_feature_schema_.indices_for(FeatureModality.CATEGORICAL), ord_encoder=getattr(worker, "ordinal_encoder_", None), )

Standard path (classifier.py ~1615) is identical except that it also passes passthrough_inf=self.get_inference_config().PASSTHROUGH_INF.

The two paths are documented to validate and clean input identically, and the code comment above the batched call says as much, so a user cannot tell that one of them honours this setting.

The consequence is worse than losing the value. get_ordinal_encoder is configured with handle_unknown="use_encoded_value", unknown_value=-1, encoded_missing_value=np.nan, so an inf in a column the encoder selects becomes the finite code -1.0 - not a missing value, but an ordinary ordinal level the model reads as real. Measured at the two call sites:

--- CATEGORICAL column: +inf at row 1, column 1 --- input : inf standard (flag=True) : np.float64(inf) batched (flag=False) : np.float64(-1.0) paths agree : False

The bug is confined to columns the ordinal encoder selects; a numeric column already agreed, because it passes through the remainder untouched.

The fix forwards worker.get_inference_config().PASSTHROUGH_INF. worker is clone(self) and has already been fitted at that point, so this is the same call the standard path makes on self.

Public API Changes

  • No Public API changes
  • Yes, Public API changes (Details below)

No signature changes. predict_proba_batched now honours PASSTHROUGH_INF as documented.

How Has This Been Tested?

Three tests added to ests/test_preprocessing/test_inf_handling.py, running the real predict_proba_batched with a randomly-initialised abpfn_v3 so no checkpoint download is needed:

  • est__predict_proba_batched__forwards_passthrough_inf_to_clean_data_transform - asserts the setting reaches the call.
  • est__predict_proba_batched__matches_standard_path_on_passthrough_inf - asserts the two paths agree.
  • est__predict_proba_batched__passes_passthrough_inf_false_when_disabled - guards that the default config is still not a passthrough one. This one passes both before and after by design; it is an over-correction guard, not a regression test for the bug.

With the one line removed, the first two fail (�ssert False is True, and an array mismatch); with the fix all three pass:

$ python -m pytest tests/test_preprocessing/test_inf_handling.py -k predict_proba_batched -q 3 passed, 52 deselected in 12.20s

Six further files exercising this path were run before and after the change with byte-identical results (28 failed / 137 passed / 25 skipped in both), and every one of those failures is a TabPFNLicenseError or a gated-repo error from having no TABPFN_TOKEN on this machine - so the change introduces no regression.
uff check and
uff format --check are clean.

Not verified here: end-to-end prediction with trained weights, since no checkpoint is available locally. The divergence is demonstrated at the preprocessing call site that is the subject of the fix.

Checklist

  • The changes have been tested locally.
  • Documentation has been updated (if the public API or usage changes).
  • A changelog entry has been added (see changelog/README.md), or "no changelog needed" label requested.
  • The code follows the project's style guidelines.
  • I have considered the impact of these changes on the public API.

The batched prediction path called clean_data_transform without the
passthrough_inf kwarg, so the argument fell back to its False default even
when the user set inference_config={"PASSTHROUGH_INF": True}. The standard
path (_raw_predict) forwards the same setting, so the two predict paths
disagreed for that one user configuration.

The divergence is only visible on categorical columns: a numeric column
carrying a +/-inf passes through the ordinal encoder's remainder untouched,
which is why the comment in clean_data_transform calls the flag a no-op
when the encoder selects nothing. On a categorical column the infinity is a
category value the encoder never saw at fit, so with the flag dropped it was
encoded as the unknown-category code -1.0 -- a finite value the model reads
as a legitimate category level, with the infinity silently gone.

Forward worker.get_inference_config().PASSTHROUGH_INF, matching the standard
path. worker is a clone(self) that has already been fitted at that point, so
inference_config_ is set and the accessor is a plain deepcopy.
Copilot AI balanced review requested due to automatic review settings October 2, 2026 06:27

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions
github-actions Bot requested a review from eliott-kalfon October 2, 2026 06:28

@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.

Reviewed by Cursor Bugbot for commit 621219b. Configure here.

Comment thread changelog/1351.fixed.md Outdated
@aniruddhaadak80

Copy link
Copy Markdown
Contributor Author

Thanks. Fixed in ad4910a.

changelog/1351.fixed.md is now a single user-facing line - it honours PASSTHROUGH_INF in predict_proba_batched, matching the standard prediction path - without naming the internal helper or the encoded sentinel value.

This branch has not been deployed

No deployments
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.

predict_proba_batched ignores PASSTHROUGH_INF, turning a categorical +inf into the ordinal code -1

2 participants