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

Install the published wheel from PyPI:

python3 -m pip install metal-treeshap

To build the wheel from a source checkout instead:

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.1.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.1-cp314-cp314-macosx_13_0_arm64.whl (209.2 kB view details)

Uploaded CPython 3.14macOS 13.0+ ARM64

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

Uploaded CPython 3.13macOS 13.0+ ARM64

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

Uploaded CPython 3.12macOS 13.0+ ARM64

metal_treeshap-0.1.1-cp311-cp311-macosx_13_0_arm64.whl (210.2 kB view details)

Uploaded CPython 3.11macOS 13.0+ ARM64

metal_treeshap-0.1.1-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.1.tar.gz.

File metadata

  • Download URL: metal_treeshap-0.1.1.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.1.tar.gz
Algorithm Hash digest
SHA256 8714494dab1de0b8713285cfe47f22e03e320333ca47c652510f291441775075
MD5 5e10a1ca3d7434d6b73865aa366e1137
BLAKE2b-256 09091df3fb93159c395907ccc5746438116eefe969ee23c90b68c0ae83b578a0

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.1.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.1-cp314-cp314-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.1-cp314-cp314-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 f57ae2ba2f5ce788067f30ea6409576780e902c2759168bba11fc3e688d531e3
MD5 c4d474907b6686e3383f9c4495d88d48
BLAKE2b-256 eb85ead9df3f743443eb71e50e13ffd7202185fe29e874f4ee294bb5f827d98c

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.1-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.1-cp313-cp313-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.1-cp313-cp313-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 e053cdb9747c17a6cef765fb6462c47be9ffbf9691daca15652bbe9ce48a9ee0
MD5 8260a7d37a115a5bc64390b3d4a6b8a1
BLAKE2b-256 bc6455ad1c045bbe625976f0aaf76f18e059f5f1c6788b33b6631ecf3a519ca1

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.1-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.1-cp312-cp312-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.1-cp312-cp312-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 e0bacc22d3068f74f0155bb7d04bd512df3c4ddb06fbe7e90d1a2a028b1d3c0d
MD5 5e1549bce721a0703dc2c86b097edb7f
BLAKE2b-256 d926f9115ba8834e0f08f60556598f97c75815a2f704795d622db7fec6c7eb5d

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.1-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.1-cp311-cp311-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.1-cp311-cp311-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 d9aa03153017c22e95eb66d4a3626402044dd3bd3aabf8081d34072c3b8c6ce0
MD5 69dfbe418ec1eedbcda30da58080dc88
BLAKE2b-256 9c3b14faec88b447d6111573a39dc77f6f82d811d223e87c2ca912df67d99958

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.1-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.1-cp310-cp310-macosx_13_0_arm64.whl.

File metadata

File hashes

Hashes for metal_treeshap-0.1.1-cp310-cp310-macosx_13_0_arm64.whl
Algorithm Hash digest
SHA256 52f8ef0461c4de7aa1c4ce1397c56319a4f22a618f33d4060cb3a821f122d4ca
MD5 c3868fdc30d6c5bad185197b72d9a64d
BLAKE2b-256 d494ab740eeb13b3c1f785412c019493faa1373d3264a7119b2bf8cd6871db7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for metal_treeshap-0.1.1-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