0.14.2 — predict 1.35–1.63× faster, bit-identical
Cuts the 0.14.2 release. The diff here is just the version bump and CHANGELOG
date stamp -the changes being released are already on main (merge a5810fa).
What's in this release
Predict is 1.35–1.63× faster end-to-end, with predictions unchanged to the
last bit. Two changes:
- Row-major fused predict kernels (
_predict_forest_rm,
_predict_forest_linear_rm) — predict consumes the binner's row-major
output directly, so each sample's bins sit in one or two cache lines for
the whole forest walk and the per-predict feature-major transpose copy is
gone. Fit-side kernels keep the feature-major layout (histograms want it);
SHAP keeps the feature-major kernels for its background walk. - No more whole-matrix copy for all-numeric input —
FeaturePreprocessorextracted the numeric block as
X[:, num_features_]even when every column is numeric, a full
fancy-index copy on each transform (~18% of end-to-end predict on large
batches). Plainasarraynow covers that case; mixed/categorical inputs
keep the gather.
Numbers (fit 200k / predict 2M×30 / 200 trees / 12 threads, min-of-5)
| config | 0.14.1 | 0.14.2 | speedup |
|---|---|---|---|
| classifier, linear leaves (default) | 2.140 s | 1.588 s | 1.35× |
| classifier, constant leaves | 1.244 s | 0.764 s | 1.63× |
| regressor | 1.236 s | 0.757 s | 1.63× |
Against the field on the same benchmark (benchmarks/scaling_predict.py):
default binary predict is now 1.26 Mrows/s — 1.30× LightGBM, 3.0×
sklearn-HGB, 0.50× XGBoost; constant-leaf paths reach ~2.6 Mrows/s, on par
with XGBoost. CatBoost's SIMD-fused C++ inference remains ~10× faster.
Why "bit-identical" is safe to claim
- Exact-equality kernel test (
test_rowmajor_predict_kernels_match_feature_major_exactly):
row-major vs feature-major kernels compared withnp.array_equalacross
depth-0 trees, constant and linear leaf blocks, NaN center bins, n ∈ {0, 1, many}. - Regenerated golden baseline changed only machine-relative timing ratios —
every accuracy metric field is byte-identical. - Full suite: 378 passed.
warmup()compiles the new kernels automatically
(same numba argument types), so the 0.14.1 fresh-worker JIT fix carries over.
After merging
-
git tag v0.14.2 && git push origin v0.14.2 - build + upload to PyPI
🤖 Generated with Claude Code