Skip to content

SHAP explainer rebuilt from scratch for every mini-batch (background forwards repeated per chunk) #325

Description

@stanlrt

From /simplify codebase sweep (2026-06-10). Hottest path in a transparency run.

transparency/explainers/shap_explainer.py:339-379 (_compute_legacy), :436-446 (_compute_modern), driven by the batch loop in base_explainer.py:248-268: compute_attributions is called once per chunk by _compute_with_optional_batches, and each call constructs a fresh shap.GradientExplainer/DeepExplainer/KernelExplainer(model, background_data) (or a fresh masker + PartitionExplainer etc. on the modern path).

Cost: Deep/Kernel/Gradient explainer construction runs model forwards over the entire background set (expected-value computation, hook setup). background_data is in _NON_BATCHABLE_KWARGS, so it is byte-identical across chunks -- with raitap.batch_size: 8 over 64 samples the background forwards run 8x for zero benefit.

Fix: memoise the constructed SHAP explainer on the instance keyed by (algorithm, id(model), id(background_data), frozen init_kwargs); the per-batch invoker then only calls .shap_values()/__call__. Captum method construction is cheap (stores a model ref) -- scope the cache to SHAP, do not complicate the invoker seam (#266).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions