Skip to main content

TreeSHAP inference accelerated by Apple GPUs through Metal

Project description

metal-treeshap

Exact SHAP values for XGBoost models, computed on Apple GPUs.

metal-treeshap runs the TreeSHAP algorithm — the same exact attribution method behind XGBoost's pred_contribs and the shap package's tree explainer — as Metal compute kernels on Apple Silicon. Compile a model once, then explain batches of rows at GPU speed: on an M4 Max, paired benchmarks measure 10–100× over 16-thread XGBoost CPU depending on model shape and batch size, on the same models and inputs, with elementwise agreement to ~1e-5.

from metal_treeshap import MetalTreeExplainer

explainer = MetalTreeExplainer.from_xgboost("model.json")  # compile once
phis = explainer.shap_values(X)                            # explain many, fast

The output is a NumPy array with the standard contract: one column per feature plus a final bias column, and each row sums to the model's margin prediction (local accuracy). Single-output models return (rows, features + 1); multiclass models return (rows, classes, features + 1).

Why this exists

Exact TreeSHAP is expensive — its cost grows with rows × trees × depth², so explaining a large ensemble over a real dataset can take minutes on a CPU. NVIDIA solved this for CUDA with GPUTreeShap (Mitchell, Frank & Holmes, arXiv:2010.13972), which decomposes trees into root-to-leaf paths and evaluates them cooperatively across GPU warps. That acceleration never reached Macs, because CUDA doesn't run there.

metal-treeshap is a from-scratch Metal port of that algorithm for Apple GPUs. It keeps GPUTreeShap's path decomposition and cooperative evaluation strategy, adapts them to Metal's SIMD-groups and unified memory, and adds an accuracy-focused execution mode that Apple's fp32-only GPUs make necessary. The portable core is continuously verified against XGBoost's own attribution output. See docs/how-it-works.md for the design.

Requirements

  • Apple Silicon Mac (M1 or newer), macOS 13+
  • Python 3.10+ and NumPy (pandas optional)
  • Xcode Command Line Tools for building the wheel — the offline Metal shader toolchain is not required; kernels compile at runtime

Installation

The package is not on PyPI yet. Build the wheel from a source checkout:

git clone https://github.com/tabulai/metal-treeshap.git
cd metal-treeshap
python3 -m pip install build
python3 -m build --wheel
python3 -m pip install dist/metal_treeshap-*.whl

Usage

from_xgboost accepts a live xgboost.Booster, an sklearn-style wrapper, a saved JSON model path, raw JSON text/bytes (booster.save_raw("json")), or a parsed dict. Loading a saved model does not require xgboost to be installed.

import xgboost as xgb
from metal_treeshap import MetalTreeExplainer

booster = xgb.train(params, dtrain, num_boost_round=500)
explainer = MetalTreeExplainer.from_xgboost(booster)

phis = explainer.shap_values(X_test)     # also: explainer.explain(X), explainer(X)
assert phis.shape == (len(X_test), X_test.shape[1] + 1)

Inputs. NumPy arrays and pandas DataFrames are accepted; any numeric dtype and memory layout is converted as needed. DataFrame columns are consumed by position — pass them in training order. NaN means missing and routes exactly as XGBoost routes it; pandas nullable values (pd.NA) and masked arrays convert to NaN. Complex input is rejected rather than silently truncated.

Works with the shap package. Wrap the output in a shap.Explanation and every standard plot works, drawn from GPU-computed values:

import shap

explanation = shap.Explanation(
    values=phis[:, :-1], base_values=phis[:, -1], data=X_test,
    feature_names=feature_names,
)
shap.plots.beeswarm(explanation)

Supported models. XGBoost gbtree and dart boosters (both weight-drop layouts), num_parallel_tree ≥ 1, missing values, and exactly these objectives — each link verified end-to-end against pred_contribs: reg:squarederror, reg:squaredlogerror, reg:absoluteerror, reg:quantileerror, reg:pseudohubererror, binary:logitraw, binary:hinge, multi:softmax, multi:softprob, binary:logistic, reg:logistic, count:poisson, reg:gamma, reg:tweedie. Anything else — survival, ranking, multi-target, categorical splits — is rejected with a clear error rather than silently mis-attributed. Verified against xgboost 2.0.3, 3.1.2, and 3.3.0.

Introspection. explainer.last_timings reports what the most recent call did (GPU time, zero-copy state, dispatch shape); explainer.trim_buffers() releases the persistent buffers a long-lived explainer retains after a peak batch.

Execution modes

mode behavior when to use
atomic (default) fastest; float atomics make reruns differ at ~1e-6 throughput
deterministic fixed-order Kahan reduction; bit-identical reruns, tighter accuracy; ~1.8× the default mode's time reproducible pipelines, caching, audits
simdgroup SIMD pre-aggregation experiment exploring other GPUs/models
explainer = MetalTreeExplainer.from_xgboost(model, accumulation="deterministic")

Advanced knobs (rows_per_simdgroup, threads_per_threadgroup, deterministic_scratch_mib, atomic_tile_rows, model_storage) are keyword arguments on the constructors; the defaults were tuned on M4 Max. The from_paths constructor accepts pre-extracted path elements for non-XGBoost sources.

Performance

Sustained, paired, randomized A/B measurements on an Apple M4 Max against 16-thread XGBoost 3.1.2 pred_contribs, identical models and inputs:

workload model speedup
stress 500 trees × depth 8, 12 features, 8,192 rows 18.5×
wide 256 features 14.4×
multiclass 8 classes 15.6×

Figures are device- and workload-specific, not guarantees; smaller models at batch volume can measure considerably higher (see the executed examples/ notebooks). Methodology, caveats, and reproduction commands live in docs/performance.md; the raw archived artifacts are under benchmarks/results/.

Examples

Three executed notebooks in examples/: a quickstart, a paired CPU-vs-GPU benchmark, and a tour of the execution modes and tuning knobs.

Development

cmake -B build && cmake --build build     # portable core + Metal targets
ctest --test-dir build --output-on-failure
python3 tests/test_vs_xgboost.py build/reference_cli   # golden tests vs xgboost

The portable C++ core (path preprocessing, CPU reference oracle) builds and tests on any platform; the Metal targets and differential fixture tests require Apple Silicon. python -m pytest runs the importable suites; script-style suites print their own invocation instructions. See docs/how-it-works.md for the architecture and RELEASING.md for the release process.

License and attribution

Apache-2.0. This project is a port of NVIDIA's GPUTreeShap and retains its algorithmic structure (see NOTICE). The TreeSHAP algorithm is due to Lundberg, Erion & Lee (arXiv:1802.03888); the GPU formulation to Mitchell, Frank & Holmes (arXiv:2010.13972). Apple's metal-cpp headers are vendored under third_party/.

Trademarks

Metal is a trademark of Apple Inc., registered in the U.S. and other countries and regions. Other names and marks (including XGBoost) are the property of their respective owners. These names are used solely to describe interoperability. This project is an independent open-source work and is not affiliated with, sponsored, or endorsed by Apple Inc. or any other trademark owner.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

metal_treeshap-0.1.0.tar.gz (1.0 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

metal_treeshap-0.1.0-cp314-cp314-macosx_13_0_arm64.whl (209.2 kB view details)

Uploaded CPython 3.14macOS 13.0+ ARM64

metal_treeshap-0.1.0-cp313-cp313-macosx_13_0_arm64.whl (209.1 kB view details)

Uploaded CPython 3.13macOS 13.0+ ARM64

metal_treeshap-0.1.0-cp312-cp312-macosx_13_0_arm64.whl (209.1 kB view details)

Uploaded CPython 3.12macOS 13.0+ ARM64

metal_treeshap-0.1.0-cp311-cp311-macosx_13_0_arm64.whl (210.1 kB view details)

Uploaded CPython 3.11macOS 13.0+ ARM64

metal_treeshap-0.1.0-cp310-cp310-macosx_13_0_arm64.whl (210.6 kB view details)

Uploaded CPython 3.10macOS 13.0+ ARM64

File details

Details for the file metal_treeshap-0.1.0.tar.gz.

File metadata

  • Download URL: metal_treeshap-0.1.0.tar.gz
  • Upload date:
  • Size: 1.0 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for metal_treeshap-0.1.0.tar.gz
Algorithm Hash digest
SHA256 75511ac3ea9c579ee303f6f1d830a57ad8da8901a206e007592866c6b0bd505d
MD5 f02c8ad01022c922f444998f9407a99f
BLAKE2b-256 318f3b0d457ae38deaef36d32ee4774033ba4d4e6271dd131c28afe9edb69202

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.0.tar.gz:

Publisher: release.yml on tabulai/metal-treeshap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file metal_treeshap-0.1.0-cp314-cp314-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.0-cp314-cp314-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 e0e6ab721202135f4f9dfad812c97554187ca5e1de074942b929e0fcedeb8fb9
MD5 c74abe2cee847bbfd52cd290426fec48
BLAKE2b-256 a038d4d295bacfe81be756413fa0a74cbe6f95c8b861cd82a80d273e695e9c43

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.0-cp314-cp314-macosx_13_0_arm64.whl:

Publisher: release.yml on tabulai/metal-treeshap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file metal_treeshap-0.1.0-cp313-cp313-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.0-cp313-cp313-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 e923ac2c4ce78ed9ca9beb2420f4e8b6cbbae349ebe76e7c920382692333c96b
MD5 49785a5cabcc457beb4c397b02131494
BLAKE2b-256 5c0e5035bb1d2b3ec4b31249df62648f1f45e692f31081a1c33c0392aea510b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.0-cp313-cp313-macosx_13_0_arm64.whl:

Publisher: release.yml on tabulai/metal-treeshap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file metal_treeshap-0.1.0-cp312-cp312-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.0-cp312-cp312-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 8fafbb1348fc1fb52ca5564399ccaefc0eaf1545c61c89784c5ad025c9753c0c
MD5 3d0a2f38fda04ddf810de80a75cb57d7
BLAKE2b-256 982403c67a374b57c9d36abd2673d4946a3bd9ded5fd705793022698b8fa5e29

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.0-cp312-cp312-macosx_13_0_arm64.whl:

Publisher: release.yml on tabulai/metal-treeshap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file metal_treeshap-0.1.0-cp311-cp311-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.0-cp311-cp311-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 82e89683661983996cd0cf62681002fcc29773f7662099cfb5692da04861d032
MD5 07bc98ddbccf16d7381454af49043f7c
BLAKE2b-256 70aabd609cac4a19bba435d9118c75fd33e968b95705b684ffbd54df66ff7ff8

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.0-cp311-cp311-macosx_13_0_arm64.whl:

Publisher: release.yml on tabulai/metal-treeshap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file metal_treeshap-0.1.0-cp310-cp310-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.0-cp310-cp310-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 f5e4ccde91b7b78b3e67ea5be364fee5195ef99624cce2785ebda052da5716e1
MD5 bf981a4b071ca91e2bf0d3308775ab35
BLAKE2b-256 4935d8ab4dc5322ab4f0752fa7222f66fd45e029c1b4743835c5183193175b77

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.0-cp310-cp310-macosx_13_0_arm64.whl:

Publisher: release.yml on tabulai/metal-treeshap

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page