Multi-threaded explainability for LLMs: words, sentences, documents, images, and tools.
Project description
A multi-threaded explainability framework using Shapley values for LLM-based outputs.
Getting Started
Install the llmshap package (with all optional dependencies):
pip install "llmshap[all]"
Install in editable mode with all optional dependencies (after cloning the repository):
pip install -e ".[all]"
Documentation is available at llmSHAP Docs and a hands-on tutorial can be found here.
Example Usage
from llmSHAP import DataHandler, BasicPromptCodec, ShapleyAttribution
from llmSHAP.llm import OpenAIInterface
data = "In what city is the Eiffel Tower?"
handler = DataHandler(data, permanent_keys={0,3,4})
result = ShapleyAttribution(model=OpenAIInterface(model_name="gpt-4o-mini"),
data_handler=handler,
prompt_codec=BasicPromptCodec(system="Answer the question briefly."),
use_cache=True,
num_threads=16,
).attribution()
print("\n\n### OUTPUT ###")
print(result.output)
print("\n\n### ATTRIBUTION ###")
print(result.attribution)
print("\n\n### HEATMAP ###")
print(result.render())
Multimodal Example with Image:
The following example shows llmSHAP with images.
from llmSHAP import DataHandler, BasicPromptCodec, ShapleyAttribution, Image
from llmSHAP.llm import OpenAIInterface
data = {
"question": "Has our stockprice increased or decreased since the beginning?",
"Num employees" : "The company has about 450 employees.",
"[IMAGE] Stock chart" : Image(image_path="./docs/_static/demo-stock-price.png"),
"Report release date" : "Quarterly reports are released on the 15th.",
"Headquarter Location" : "The headquarters is located in a mid-sized city.",
"Num countries" : "It has offices in three countries."
}
result = ShapleyAttribution(model=OpenAIInterface(model_name="gpt-5-mini", reasoning="low"),
data_handler=DataHandler(data, permanent_keys={"question"}),
prompt_codec=BasicPromptCodec(system="Answer the question briefly."),
use_cache=True,
num_threads=35,
).attribution()
print("\n\n### OUTPUT ###")
print(result.output)
print("\n\n### HEATMAP ###")
print(result.render(abs_values=True, render_labels=True))
Embedding-Based Output Scoring
EmbeddingCosineSimilarity measures semantic similarity between outputs using embeddings.
It supports two backends:
- API — any OpenAI-compatible embeddings endpoint via
api_url_endpoint. - Local — a
sentence-transformersmodel downloaded on first use.
For the local backend, install the embeddings extra:
pip install "llmshap[embeddings]"
The example below uses the OpenAI API backend, which is already included in [all].
from llmSHAP import DataHandler, BasicPromptCodec, ShapleyAttribution, EmbeddingCosineSimilarity
from llmSHAP.llm import OpenAIInterface
data = "In what city is the Eiffel Tower?"
handler = DataHandler(data)
result = ShapleyAttribution(model=OpenAIInterface(model_name="gpt-4o-mini"),
data_handler=handler,
prompt_codec=BasicPromptCodec(system="Answer the question briefly."),
use_cache=True,
num_threads=16,
value_function=EmbeddingCosineSimilarity(
model_name = "text-embedding-3-small",
api_url_endpoint = "https://api.openai.com/v1")
).attribution()
print("\n\n### OUTPUT ###")
print(result.output)
print("\n\n### HEATMAP ###")
print(result.render(abs_values=True, render_labels=True))
Example data
You can pass either a string or a dictionary:
from llmSHAP import DataHandler
# String input
data = "The quick brown fox jumps over the lazy dog"
handler = DataHandler(data)
# Dictionary input
data = {"a": "The", "b": "quick", "c": "brown", "d": "fox"}
handler = DataHandler(data)
To exclude certain keys from the computations, use permanent_keys:
from llmSHAP import DataHandler
data = {"a": "The", "b": "quick", "c": "brown", "d": "fox"}
handler = DataHandler(data, permanent_keys={"a", "d"})
# Get data with index 1 WITHOUT the permanent features.
print(handler.get_data({1}, exclude_permanent_keys=True, mask=False))
# Output: {'b': 'quick'}
# Get data with index 1 AND the permanent features.
print(handler.get_data({1}, exclude_permanent_keys=False, mask=False))
# Output: {'a': 'The', 'b': 'quick', 'd': 'fox'}
Comparison with TokenSHAP
| Capability | llmSHAP | TokenSHAP |
|---|---|---|
| Threaded | ✅ (optional num_threads) |
❌ |
| Modular architecture | ✅ | ❌ |
| Heuristics | SlidingWindow • Monte Carlo • Counterfactual | Monte Carlo |
| Caching across coalitions | ✅ | ❌ |
| Sentence-/chunk-level attribution | ✅ | ✅ |
| Permanent context pinning (always-included features) | ✅ | ❌ |
| Pluggable similarity metric | ✅ TF-IDF, embeddings | ✅ TF-IDF, embeddings |
| Docs & tutorial | ✅ Docs + tutorial | ✅ README only |
| Unit tests & CI | ✅ Pytest + GitHub Actions | ❌ |
| Image attribution | ✅ | ✅ PixelSHAP |
| In-image attribution | ❌ | ✅ PixelSHAP |
Stars ⭐️
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llmshap-1.5.2.tar.gz.
File metadata
- Download URL: llmshap-1.5.2.tar.gz
- Upload date:
- Size: 20.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80c65dc4d6dffec99389ee38c48ba641ce7750df9a6791adce1bfa98e7ed6e73
|
|
| MD5 |
74afef83415596ed053f324110306091
|
|
| BLAKE2b-256 |
8b64ab71bbae95e48ebd3c999aec2a10c02b195f41990486d8908b4591aa69aa
|
File details
Details for the file llmshap-1.5.2-py3-none-any.whl.
File metadata
- Download URL: llmshap-1.5.2-py3-none-any.whl
- Upload date:
- Size: 22.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4dddc3d823f4faa271344177eb42e0f953e67fc34c3be1b5a24da22c202e609e
|
|
| MD5 |
3289e2ce15e94edf734fcfce1c08795e
|
|
| BLAKE2b-256 |
842e8bc5a376c97500d1718909ae55f66fe047f42902da336f4a6508a21b64f6
|