bosk
A bosk is a small thicket of trees — here, an ensemble of decision trees.
Gradient-boosting model inference behind one small trait — load a
trained LightGBM, ONNX, or CatBoost model and call predict.
The headline is the LightGBM backend: it parses the .lgb text format
directly, with no C dependency and no FFI to lib_lightgbm. Building with
--no-default-features gives you a LightGBM predictor with zero dependencies
— trivial to cross-compile, embed, or drop into a musl target.
use ;
let model = load_model?;
let p = model.predict?; // probability for a binary classifier
let ps = model.predict_batch?; // row-major batch, n features per row
Backends
| Extension | Backend | Feature flag | Extra deps |
|---|---|---|---|
.lgb / .txt |
pure-Rust LightGBM text parser | always on | none (zero deps) |
.onnx |
ONNX Runtime via ort |
onnx (default) |
prebuilt ONNX Runtime |
.cbm |
CatBoost via catboost-rust |
catboost (default) |
native CatBoost |
load_model auto-detects the format by extension; supported_extensions()
reports what the current build can load. The default build enables onnx and
catboost. For the zero-C-dependency LightGBM-only build:
= { = "0.1", = false }
A .cbm loaded through load_model is assumed to be a binary classifier
(the CatBoost C API does not expose the trained loss function). For a CatBoost
regression or ranking model, construct the backend explicitly:
CatBoostModel::load(path, Output::Raw).
The Model trait
predict_batch takes the samples row-major in one flat slice — no per-row
allocation — and backends override it with a single native batched run (ONNX,
CatBoost). predict checks the feature count against the model (LightGBM's
max_feature_idx, CatBoost's float-feature count, the ONNX graph's declared
input dimension when static) and refuses a wrong-length vector with
Error::FeatureCount instead of silently treating the tail as missing. On
the LightGBM path that refusal is the only possible error — evaluation
itself cannot fail once the model is loaded and validated. Where an
infallible call matters more than the length check, hold a concrete
LgbModel and use predict_unchecked (out-of-range feature indices are
then evaluated as missing; the objective transform is still applied — it is
not a raw-score prediction).
LightGBM coverage
The pure-Rust parser reproduces LightGBM's own predictions bit-for-bit (verified against LightGBM 4.6 across the full objective matrix):
- numerical splits with full missing-value semantics (default direction +
missing type: none/zero/NaN, including the
kZeroThresholdzero band); - categorical splits (bitset lookup), including unseen, negative, and NaN categories;
- random-forest averaging (
average_output); - the output transform of every single-output objective:
binary(honoring itssigmoidparameter),cross_entropy,cross_entropy_lambda,poisson/gamma/tweedie(exponential link), the regression family (includingreg_sqrt), and ranking (raw scores).
Models it cannot evaluate faithfully are rejected at load with
Error::Unsupported rather than mispredicted silently: multiclass
(num_class > 1), linear trees (is_linear=1), unrecognised objectives, and
unrecognised objective tokens (a token like sqrt can change the output
transform, so an unknown one is never skipped). The token whitelist is
audited against every LightGBM release from 2.1 through 4.6 — the complete
vocabulary those versions can write is sqrt, sigmoid:, and num_class:
— so a token refusal can only occur for a model written by a future LightGBM
version.
Each tree's structure is validated at load — including that the child
pointers form an actual tree, so a corrupted file cannot send predict into
an infinite loop or a panic.
Testing
Every backend is tested against its reference implementation: the LightGBM
parity fixtures assert the pure-Rust prediction matches LightGBM 4.6 to
1e-9 (including missing-value, zero-as-missing, categorical, and
reg_sqrt models),
the CatBoost fixtures pin Output::Probability / Output::Raw against
CatBoost 1.2.10, and the ONNX fixture checks the exported graph end to end.
See tests/fixtures/README.md to regenerate
fixtures.
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.