Skip to content

Skip redundant inverse transforms in _predict when return_all_rounds=False#241

Open
TaXxER wants to merge 1 commit intomainfrom
export-D96827345
Open

Skip redundant inverse transforms in _predict when return_all_rounds=False#241
TaXxER wants to merge 1 commit intomainfrom
export-D96827345

Conversation

@TaXxER
Copy link
Contributor

@TaXxER TaXxER commented Mar 16, 2026

Summary:
_predict previously called _inverse_transform_predictions (the logistic/sigmoid function over the full prediction array) on every boosting round, even when return_all_rounds=False and only the final round's result was needed. The first R-1 inverse transforms were computed and discarded.

This is especially costly during early stopping, where _predict is called once per fold per round. At early stopping round r, the fold model has r boosters, so _predict was making r logistic calls but using only the last. Over all R rounds and F folds, total logistic calls were F·R·(R+1)/2 (quadratic in R). After this change they are F·R (linear in R), saving F·R·(R-1)/2 calls.

Benchmarking utils.logistic (median of 20 runs, buck test) shows ~26 ns/element, scaling linearly with array size:

  • n=100K: 2.6 ms/call
  • n=1M: 26 ms/call
  • n=10M: 277 ms/call

Estimated wall-clock savings during early stopping (F=5 folds, 26 ns/element):

Rounds (R) Saved calls n_val=100K n_val=1M n_val=10M
10 225 0.6s 5.9s 62s
20 950 2.5s 25s 4.4 min
50 6,125 15.9s 2.7 min 28 min

The 2D predictions_per_round allocation is also skipped when not needed.

No change in behavior — RegressionMCGrad is unaffected (its inverse transform is the identity).

Differential Revision: D96827345

…False

Summary:
`_predict` previously called `_inverse_transform_predictions` (the logistic/sigmoid function over the full prediction array) on every boosting round, even when `return_all_rounds=False` and only the final round's result was needed. The first R-1 inverse transforms were computed and discarded.

This is especially costly during early stopping, where `_predict` is called once per fold per round. At early stopping round r, the fold model has r boosters, so `_predict` was making r logistic calls but using only the last. Over all R rounds and F folds, total logistic calls were F·R·(R+1)/2 (quadratic in R). After this change they are F·R (linear in R), saving F·R·(R-1)/2 calls.

Benchmarking `utils.logistic` (median of 20 runs, `buck test`) shows ~26 ns/element, scaling linearly with array size:
- n=100K: 2.6 ms/call
- n=1M: 26 ms/call
- n=10M: 277 ms/call

Estimated wall-clock savings during early stopping (F=5 folds, 26 ns/element):

| Rounds (R) | Saved calls | n_val=100K | n_val=1M  | n_val=10M |
|------------|-------------|------------|-----------|-----------|
| 10         | 225         | 0.6s       | 5.9s      | 62s       |
| 20         | 950         | 2.5s       | 25s       | 4.4 min   |
| 50         | 6,125       | 15.9s      | 2.7 min   | 28 min    |

The 2D `predictions_per_round` allocation is also skipped when not needed.

No change in behavior — `RegressionMCGrad` is unaffected (its inverse transform is the identity).

Differential Revision: D96827345
@meta-cla meta-cla bot added the CLA Signed This label is managed by the Meta Open Source bot. label Mar 16, 2026
@meta-codesync
Copy link

meta-codesync bot commented Mar 16, 2026

@TaXxER has exported this pull request. If you are a Meta employee, you can view the originating Diff in D96827345.

@codecov
Copy link

codecov bot commented Mar 16, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.82%. Comparing base (76f0707) to head (10d40b5).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #241   +/-   ##
=======================================
  Coverage   95.81%   95.82%           
=======================================
  Files           9        9           
  Lines        1887     1891    +4     
=======================================
+ Hits         1808     1812    +4     
  Misses         79       79           
Flag Coverage Δ
unittests 95.82% <100.00%> (+<0.01%) ⬆️

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

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

Labels

CLA Signed This label is managed by the Meta Open Source bot. fb-exported meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant