This project has been archived by its maintainers, and is no longer receiving any updates.
nlp-shap
Shapley-value attributions for conversational language models.
Explicit estimands (Shapley vs Banzhaf), reproducible run archives, pluggable backends (Hugging Face, LM Studio, OpenAI-compatible APIs).
Installation
pip install nlp-shap
Optional backends and visualization:
pip install "nlp-shap[transformers]" # Hugging Face text backend
pip install "nlp-shap[lmstudio]" # LM Studio SDK
pip install "nlp-shap[api]" # OpenAI-compatible HTTP API
pip install "nlp-shap[viz]" # matplotlib token charts
The core package does not install PyTorch. Python 3.12 or newer; uv for development.
Why nlp-shap
- Honest estimands. Shapley and Banzhaf are separate, labelled aggregators; every result and archive records which one produced it, and results report
base_valueandgrand_valueso efficiency (sum(values) == v(N) - v(empty)) can be verified; axiom tests enforce it. - Reproducible runs. One validated configuration, a run id derived from it, and an archive of every model generation, so attributions can be recomputed with another value function without calling the model again.
- Pluggable everything. Partitions, absence policies, estimators, value functions, backends and renderers are entry-point plugins; exact, Monte Carlo, complementary and Neyman estimators ship built in.
Quickstart
import math
from nlp_shap import (
ConversationSnapshot,
ExplainConfig,
ExplainRunner,
Message,
Role,
Turn,
)
snapshot = ConversationSnapshot.from_turns((
Turn(messages=(Message(role=Role.USER, text="refund my order"),)),
))
config = ExplainConfig.model_validate({
"backend": {"kind": "mock", "model_id": "stub"},
"explanation": {"estimator": "exact", "value_fn": "tfidf_cosine"},
})
result = ExplainRunner(config).explain_sync(snapshot).result
print(result.values) # one attribution per token
print(result.base_value) # v(empty): payoff of the fully masked prompt
print(result.grand_value) # v(N): payoff of the full prompt
# Efficiency: Shapley values sum to v(N) - v(empty).
assert math.isclose(sum(result.values), result.grand_value - result.base_value)
The mock backend needs no model; swap backend.kind for transformers, lmstudio or api to explain a real model. Runs are archived under ./runs/{run_id}; running the same configuration twice raises ArchiveExistsError unless explanation.archive.on_exists is overwrite (or archive.path is "").
Command line
The same run without Python: write a snapshot as JSON, start from the commented config skeleton, and get the result as JSON (--render token_bar --png out.png also saves a chart).
echo '{"turns": [{"messages": [{"role": "user", "text": "refund my order"}]}]}' > snapshot.json
nlp-shap config --example > config.yaml
nlp-shap explain --config config.yaml --snapshot snapshot.json --out result.json
nlp-shap reanalyze --config config.yaml --archive runs/<run_id> # rescore, no model calls
nlp-shap plugins
See the command-line guide.
Documentation
Full documentation: pawlo77.github.io/nlp-shap
- Getting started
- How a run works
- Configuration
- Choosing an estimator
- Backends
- Extending
- Theory
- API reference
Examples, vault and development
- Runnable notebooks:
examples/, also embedded in the docs. - Architecture notes, decisions, known issues and papers: the Obsidian vault in
knowledge/. - Development setup, checks and pull requests:
CONTRIBUTING.md; coding-agent rules:AGENTS.md.
Citing
If you use nlp-shap in research, please cite it (CITATION.cff; GitHub's "Cite this repository" button renders it as APA or BibTeX):
cff-version: 1.2.0
title: "nlp-shap: Shapley-value explainability for conversational language models"
type: software
authors:
- family-names: Pozorski
given-names: Paweł
repository-code: "https://github.com/Pawlo77/nlp-shap"
license: Apache-2.0
License
Apache License 2.0. See LICENSE.
Copyright 2026 Paweł Pozorski.
Metadata
Release files for nlp-shap 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nlp_shap-0.2.0.tar.gz | 102.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nlp_shap-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 250.7 kB
Release files / nlp_shap-0.2.0.tar.gz
| Download URL | nlp_shap-0.2.0.tar.gz |
|---|---|
| Size | 102.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
57602445aa4e6799d474be7fd30e0243c50539047300e3d135e94b4d95713f67
|
|
BLAKE2b-256 checksum How to use checksums |
ffc3e8f6c4c1a726e9fab1e75b10fd57799e66259e8a8283771078bb28d51cf3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / nlp_shap-0.2.0-py3-none-any.whl
| Download URL | nlp_shap-0.2.0-py3-none-any.whl |
|---|---|
| Size | 148.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e2cc8af8333ad7343071f0fedc0e849babcb2e087d98a9fd1c3889cfdd728909
|
|
BLAKE2b-256 checksum How to use checksums |
56bd6a1276d7886ed9c58bdb76f13e733010a1bdc5bd0c19ea2f3f010027896b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|