Leaves Project Evolution Plan (Draft v1.0)
> Status: Draft v1.0 · Date: 2026-06-13 · Reference projects: XGBoost, GoMLX · Current version: v0.8.0 (pure-Go GBRT prediction library)
*Note: this is a structured English summary of a long Chinese-language design document; section numbering follows the original.*
Key points
- Core question: How to evolve leaves from a pure prediction library (loading LightGBM, XGBoost, and scikit-learn models) into a full GBRT framework with training, GPU acceleration, and interpretability — using GoMLX as the compute base — without breaking ecosystem compatibility?
- Design principles: progressive enhancement (each phase ships a usable release), stable public
EnsembleAPI with replaceable internals, GoMLX-first with native fallback, learn from XGBoost without cloning it, and test-driven evolution. - leaves today loads LightGBM (text/JSON), XGBoost (binary), and scikit-learn (pickle) models; supports gbtree, dart, gblinear, random forest; dense and CSR inputs; transforms (Raw, Logistic, Softmax, Exponential, LeafIndex); NaN routing via
default_left; LightGBM categorical one-hot rules; and multithreaded batch prediction via goroutines. - Gaps vs. XGBoost (prioritized): model formats and dump (high), Tree SHAP (high), GPU inference (high), feature importance, evaluation metrics, native categorical features, multi-output trees, JSON serialization, training (long-term), survival analysis, distributed training.
- Performance: single-threaded inference is within ~20% of the C API; the bottleneck is scalar per-node tree traversal, which cannot use SIMD or GPUs.
- GoMLX uses symbolic graph building + JIT compilation (XLA to CPU/GPU/TPU) similar to JAX/TF2. Key primitives for tree inference:
LessThan,Where,Gather,While,If,Const,Reshape,ReduceSum,IsNaN. - Backends: XLA (fastest, CPU/GPU/TPU), SimpleGo (WASM/edge portable), go-coreml (Apple Metal).
- Limitations and mitigations: fixed shapes at build time (use Exec shape cache, 32 slots); dynamic shapes still in progress (one subgraph per tree); While-loop overhead (fully unroll loops for max_depth ≤ 8); no direct CSR gather (support Dense first).
- Add GoMLX dependency (requires Go ≥ 1.25; upgrade Go in two steps from the current Go 1.12 baseline).
- Split the monolithic root package into
model/,tree/,io/,ensemble/,transform/,mat/,internal/,util/; root keeps type aliases (e.g.,type Ensemble = model.Ensemble) for zero-breakage compilation; aliases removed at v1.0.0. - Define a pluggable
tree.Engineinterface withPredictDense,PredictCSR,PredictSingle,NOutputGroups,Close, plus aFactoryfor backend creation. - Introduce a framework-agnostic intermediate representation (
ForestIRwithNumFeatures,NumOutputGroups,BaseScore,Trees), whereTreeIRstores arrays ofSplitFeature,SplitThreshold,DefaultLeft,LeftChild,RightChild,LeafValue, and LightGBM categorical fields (CatBoundaries,CatThresholds). - Approach A (recommended start): fully unroll the traversal loop for fixed-depth trees (typical XGBoost max_depth = 6, 63 internal nodes) into a static graph of
Gather/LessThan/Whereops. - Approach B:
Whileloop for variable-depth trees (e.g., LightGBM's num_leaves-growth trees), looping while the node index is non-negative (leaves encoded as negative). - Approach C: LightGBM categorical nodes via vectorized equality checks reduced with OR.
- Parallelize all trees into a
[batch, numTrees]tensor and sum withReduceSum. - Missing values: insert
IsNaNchecks before comparisons, routing todefaultLeft. - Transforms reuse GoMLX built-ins (
Logistic, fusedSoftmaxwith numerical stability,Exp). - Backend switching via
WithBackend(...):BackendAuto(GoMLX/XLA with native fallback),BackendGoMLX,BackendNative,BackendSimpleGo(WASM). - Performance expectations: native path remains best for small batches (1–16); GoMLX/XLA GPU wins at medium (100–1K) and large (10K+) batches; SimpleGo is the only WASM option.
- XGBoost JSON model loader (
XGEnsembleFromJSON): parsegbtree_model_param, thetrees[]array (split_indices,split_conditions,left_children,right_children,base_weights), andtrain_param(base_score, num_class), converting toForestIR. - Metrics package: a
Metricinterface (Name,Evaluate,EvaluatePerGroup,HigherIsBetter) implementing a core subset of XGBoost's 24+ metrics — RMSE, MAE, MAPE, RMSLE, LogLoss, AUC, Error, multi-class LogLoss/Error, NDCG@k, MAP. - Native categorical features (XGBoost 1.6+): parse the
ftypefield; categorical nodes use partition-based membership tests rather than numeric comparisons; extendTreeIRwithIsCategoricalandCategories. - Multi-output trees (XGBoost 3.x
MultiOutputTree): vector leaves stored asLeafValues[numLeaves * outputDim]; GoMLXReshape+Gatheryields[batch, outputDim]. - Tree SHAP: recursive path-weight algorithm (O(TLD²), T = trees, L = leaves, D = depth) using cover weights stored in
ForestIR; CPU-only path computation in pure Go, with GoMLX used for batch post-processing of SHAP matrices. API:TreeExplainer.ShapleyValues(output includes bias column) andInteractionValues. - Feature importance: five types (weight, gain, total_gain, cover, total_cover), computed from split-feature counts plus
loss_chg/sum_hessparsed from XGBoost binaries into newTreeIRfields (SplitGain,SumHess). - Visualization:
DumpText,DumpJSON,DumpDOT(Graphviz) exports fromForestIR. - Saabas approximate contributions: a lightweight SHAP alternative distributing prediction deltas along tree paths; 10x+ faster but assumes feature independence.
- Deliverables include consistency tests against XGBoost's Python SHAP output.
- Layered training architecture: Trainer (loop, CV, early stopping, callbacks) → GradientBooster (gbtree/dart/gblinear) → Objective + Metric → TreeBuilder (histogram building, best-split search) → GoMLX compute backend.
Boosterinterface (UpdateOneIter,Predict,Save/Load) and aDMatrixdata container (data, labels, weights, groups).- First six objectives with gradient/Hessian formulas:
reg:squarederror,reg:logistic,binary:logistic,reg:gamma,multi:softmax,rank:pairwise(LambdaRank). - Histogram-based tree building (XGBoost
histmethod) with GoMLX-accelerated histogram aggregation and split-gain computation; hyperparameters include max_depth, max_leaves, min_child_weight, L2 regularization, and column sampling.
Current state (Section 1)
GoMLX feasibility (Section 2)
Roadmap overview (Section 3)
| Phase | Version | Theme | |-------|---------|-------| | 0 | v0.9.0 | Architecture dual-track (compatibility) | | 1 | v1.0.0 | GoMLX inference engine (acceleration) | | 2 | v1.1.0 | Format & feature alignment | | 3 | v1.2.0 | Interpretability & advanced prediction | | 4 | v2.0.0 | Training capability | | 5 | v3.0.0 | High performance & distributed |
Phase 0 — Architecture dual-tracking (v0.9.0)
Phase 1 — GoMLX inference engine (v1.0.0)
Phase 2 — Format & feature alignment (v1.1.0)
Phase 3 — Interpretability (v1.2.0)
Phase 4 — Training capability (v2.0.0)
Phase 5 — High performance & distributed (v3.0.0)
Planned: GPU/distributed training and inference, quantized inference, ONNX interop, and WASM deployment.
Risks and milestones (Sections 10–11)
The document closes with risk/countermeasure analysis and a milestone timeline keyed to the six phase releases above (truncated in the source post), with per-phase checklists: package restructuring, engine interface, IR definitions, native engine wrapper, GoMLX engine with XLA and SimpleGo benchmarks, compatibility tests for XGBoost/LightGBM/sklearn, and backend usage documentation.