saccade 👁️⚡
"Don't explain the black box after the crime was committed. Physically blindfold the model."
saccade is an open-source Python library for Intrinsically Interpretable Vision Transformers (ViTs) and LLM Prompt Token Compression. Instead of relying on post-hoc saliency heuristics (like Grad-CAM) that generate plausible-looking "interpretability illusions", saccade introduces an explicit hard attention bottleneck that physically discards uninformative tokens.
- 📖 Deep Dive Essay: I Deleted 94% of an Image and 70% of an LLM Prompt
- 🎮 Live Interactive Demo: Scrub ViT Layers & LLM Tokens in Browser
- 📦 PyPI Package:
pip install saccade-ai
- Vision ViT Saccading: Discard up to 94% of image patches while preserving full diagnostic accuracy. Downstream predictions are causally bound only to the preserved $K$ coordinates ($\partial \hat{y} / \partial x_m \equiv 0$).
- LLM Prompt Saccading: Prune 60% to 75% of input prompt tokens by discarding syntactic fluff and conversational padding ("breaking grammar"), slashing API costs, prefill latency, and KV-cache footprint while maintaining reasoning fidelity.
⚡ Quickstart
Install via pip:
pip install saccade-ai
Or clone for local development:
git clone https://github.com/helloitsdaksh/saccade.git
cd saccade
pip install -e .
1. Vision ViT Saccade (3 Lines)
import torch
from saccade import SaccadeViT, export_interactive_html
# 1. Instantiate ViT with intrinsic attention bottleneck
# Only 12 out of 196 patches (6.1% budget) reach downstream layers
model = SaccadeViT.from_pretrained(
"vit_tiny_patch16_224",
num_classes=1000,
top_k_patches=12,
bottleneck_layer=6
)
# 2. Forward pass returns class predictions and exact spatial metadata
image = torch.randn(1, 3, 224, 224)
logits, meta = model(image, return_saccades=True)
print("Preserved Patch Indices:", meta.patch_indices)
print("Bounding Boxes [ymin, xmin, ymax, xmax]:", meta.bounding_boxes)
# 3. Export standalone interactive web visualizer (zero dependencies)
export_interactive_html(model=model, image=image, output_path="saccade_viewer.html")
2. LLM Prompt Token Saccade (3 Lines)
from saccade import PromptSaccade
# 1. Instantiate the prompt compressor
compressor = PromptSaccade(model_name="distilgpt2", device="cpu")
# 2. Compress prompt by 70% (strips syntactic fluff, retains semantic hubs)
prompt = (
"Please carefully review and analyze the following quarterly report and "
"summarize whether enterprise cloud software revenue grew year-over-year: "
"'The company reported enterprise cloud revenue surged 34% to $6.8 billion.' "
"What was the growth rate?"
)
result = compressor.compress(prompt, compression_ratio=0.30)
print(result.compressed_text)
# => "quarterly report summarize enterprise cloud software revenue grew: enterprise cloud revenue surged 34% $6.8 billion. What growth rate?"
print(f"Token reduction: {result.token_savings_pct:.1f}% ({result.original_tokens} -> {result.compressed_tokens} tokens)")
🔬 Core Mechanics: ViT Spatial Bottleneck
In standard ViTs, downstream classification heads observe all $N$ tokens across the full image sequence. saccade intercepts the self-attention affinity matrix $A$ at an intermediate probing layer $L_b$:
Input Image [B, C, H, W]
│
▼
Patch Tokenizer & ViT Blocks 0 .. L_b [B, N, D]
│
▼
Self-Attention Matrix A ∈ R^{N × N} (Layer L_b)
│
▼
Patch Importance Voting: p_j = ∑_{i=1}^N A_{i, j}
│
▼
Hard Top-K Bottleneck (Discard all but K tokens)
│
▼
Sparse Downstream Predictor Blocks (L_b + 1 .. L_end)
│
▼
Class Prediction ŷ (Causally derived ONLY from K patches)
1. Patch Importance Voting ($p$)
For an input sequence of $N$ spatial patches, let $A \in \mathbb{R}^{N \times N}$ denote the attention affinity matrix from probing layer $L_b$. The column sum represents the total "votes" cast for patch $j$ by all other spatial querying locations:
$$p_j = \sum_{i=1}^N A_{i, j}$$
2. Hard Top-$K$ Spatial Saccade
The model sorts $p$ and routes only the top-$K$ patches (e.g., $K=12$ out of $196$ patches, representing $< 7%$ of the visual scene) into subsequent transformer layers:
$$\mathcal{J}_K = \text{TopK}(p, K)$$
$$\mathbf{Z}{\text{downstream}} = [\mathbf{z}{\text{cls}}, ; \mathbf{z}_{\mathcal{J}_K}]$$
3. Guaranteed Causal Faithfulness
Downstream predictions are causally bound to only those $K$ patches. All non-selected patches are physically removed from the compute graph:
$$\frac{\partial \hat{y}}{\partial x_m} \equiv 0 \quad \forall m \notin \mathcal{J}_K$$
💬 LLM Prompt Token Saccading ("Breaking Grammar")
Large Language Models do not read like humans. Conversational politeness ("Could you please assist me by...", "It should be noted that in accordance with...") consumes up to 70% of prompt token budgets and bloats the KV cache with low-information syntactic glue.
PromptSaccade runs a fast single-pass attention probe over the prompt to calculate:
- Self-Attention In-Degree: Identifies semantic anchor tokens that subsequent clauses heavily attend to.
- Shannon Entropy Sieve: Filters out predictable, high-probability syntactic padding.
Empirical Prompt Compression Benchmark
Run the benchmark locally:
python examples/llm_prompt_saccade.py
| Task Category | Original Tokens | Saccaded Tokens | Tokens Saved | Token Reduction | Estimated Prefill Speedup |
|---|---|---|---|---|---|
| Pathology / Medical Report | 124 | 39 | 85 | 68.5% | ~3.2× |
| Financial SEC 10-Q Analysis | 116 | 34 | 82 | 70.7% | ~3.4× |
| Python Bug Diagnostic | 91 | 30 | 61 | 67.0% | ~3.0× |
| Average Across Workloads | 110 | 34 | 76 | 68.9% | ~3.2× |
Estimated API savings: $2,280 saved per 1M queries (at $10/M tokens).
🌐 Standalone Interactive Web Artifacts
saccade includes a built-in exporter that compiles interactive scientific visualizers into a single, zero-dependency, self-contained HTML file with embedded base64 assets and client-side canvas rendering:
🚀 Live Interactive Demo: dakshpatel.dev/demos/saccade-ai.html — scrub ViT probing layers ($L_0$ to $L_{11}$), adjust token budgets ($K$), and inspect LLM prompt compression live in your browser.
- 🎚️ Real-Time Sparsity Slider: Vary $K$ dynamically from $1$ to $N$, observing how confidence shifts as visual context is revealed.
- 🎯 Interactive Patch Ablation: Click individual active patches to manually disable them, instantly viewing the counterfactual logit penalty: $$\Delta \text{logit} = \text{logit}{\text{base}} - \text{logit}{\text{ablated}}$$
- 👁️ Scanpath Arcs: Visualizes the model's saccadic fixation order with sleek vector lines and rank tags (
#1,#2, ...). - 🚀 Zero Backend Required: Pure client-side HTML5 Canvas + vanilla JS. No node servers, no Python backends, instant sharing on GitHub Pages or static hosts.
📊 Faithfulness Benchmark: Intrinsic vs Post-Hoc
| Property | Post-Hoc Saliency (Grad-CAM / IG) | Saccade Intrinsic Bottleneck |
|---|---|---|
| Causal Bound | ❌ Heuristic approximation | ✅ 100% Causal Guarantee |
| Gradient Leakage on Discarded Pixels | ⚠️ Non-zero everywhere ($|\nabla_x| > 0$) | ✅ Identically 0.000000 |
| Pruning Capability | ❌ None (observes full image) | ✅ Prunes 94% of input tokens |
| AUC-Deletion (Steeper drop is better) | ~0.35 | 0.166 |
| Interactive Perturbation in Browser | ❌ Requires live Python backend | ✅ Zero-dependency standalone HTML |
Run the quantitative benchmark:
python examples/benchmark_faithfulness.py
📁 Repository Structure
saccade/
├── saccade/
│ ├── __init__.py # Public API exports
│ ├── bottleneck.py # AttentionBottleneck & column-sum voting
│ ├── models.py # SaccadeViT wrapper & CleanViT native
│ ├── visualization.py # Overlays, scanpaths, & matplotlib breakdown
│ ├── exporter.py # Standalone interactive HTML generator
│ ├── benchmarks/
│ │ └── faithfulness.py # AUC-Del, AUC-Ins, & gradient leakage test
│ └── text/
│ └── token_saccade.py # LLM prompt token saccader & entropy compression
├── examples/
│ ├── quickstart.py # ViT end-to-end quickstart & HTML exporter
│ ├── llm_prompt_saccade.py # LLM prompt token pruning & cost benchmarks
│ ├── generate_layer_by_layer_inspector.py # Interactive layer visualizer generator
│ └── benchmark_faithfulness.py # Deletion & Insertion curve benchmarks
├── tests/
│ ├── test_bottleneck.py # Bottleneck & voting unit tests
│ ├── test_models.py # SaccadeViT & CleanViT tests
│ ├── test_exporter.py # HTML export verification tests
│ ├── test_faithfulness.py # Causal gradient isolation verification
│ └── test_text_saccade.py # LLM prompt token saccading tests
├── assets/
│ └── samples/ # Real evaluation scenes (Eagle, Panda, etc.)
├── CITATION.cff # Citation metadata for GitHub 1-click cite
├── LICENSE # MIT License
└── pyproject.toml # Modern PEP 621 packaging
🧪 Running Tests
pytest tests/ -v
All 15 test suites verify:
- Column-sum patch importance voting correctness
- Normalized bounding box conversions
- Dynamic top-$K$ budget switching
- Standalone HTML generation with embedded base64 data
- Exact 0.0 causal gradient isolation
- Text token saccading & Shannon entropy compression
🙏 Credits & Acknowledgements
- Inspiration: The intrinsic attention column-voting mechanism was inspired by David Ha (@hardmaru) and the foundational paper Neuroevolution of Self-Interpretable Agents (Tang, Nguyen, & Ha, 2020).
- Vision Backbones: Built with Ross Wightman's timm library (
vit_small_patch16_224.dino,deit_small_patch16_224). - Language Models: DistilGPT2 / Hugging Face Transformers for causal attention extraction and next-token perplexity entropy.
📜 Citation
If you use saccade in your research, experiments, or applications, please cite:
@misc{patel2026saccade,
author = {Patel, Daksh},
title = {saccade: Intrinsic Attention Bottlenecks for Vision Transformers and LLM Prompt Compression},
year = {2026},
month = {November},
howpublished = {\url{https://github.com/helloitsdaksh/saccade}},
note = {Version 0.1.1}
}
Or using BibLaTeX:
@software{patel2026saccade,
author = {Patel, Daksh},
title = {saccade: Intrinsic Attention Bottlenecks for Vision Transformers and LLM Prompt Compression},
year = {2026},
month = {11},
version = {0.1.1},
publisher = {GitHub},
url = {https://github.com/helloitsdaksh/saccade}
}
📄 License
MIT License. Free for academic research, open-source development, and commercial use.
Metadata
Release files for saccade-ai 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| saccade_ai-0.1.1.tar.gz | 1.1 MB | With provenance | Details for saccade_ai-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| saccade_ai-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for saccade_ai-0.1.1-py3-none-any.whl |
Total release size: 1.1 MB
Release files / saccade_ai-0.1.1.tar.gz
| Download URL | saccade_ai-0.1.1.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b18851b51d9d8e6104a94c772511fae09ac82c88054d3e14474de0a2f70572b0
|
|
BLAKE2b-256 checksum How to use checksums |
8ebd7b216f00d0bd2242abb4a35e590eb819f77c08b6f645ef76a23d8c551d02
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logRelease files / saccade_ai-0.1.1-py3-none-any.whl
| Download URL | saccade_ai-0.1.1-py3-none-any.whl |
|---|---|
| Size | 32.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5992fe517b9e98bfdfa473b3b58c4590083ca005a407ee9f86da346a172ed8d8
|
|
BLAKE2b-256 checksum How to use checksums |
24a96b228e20cfab444733492d5ef42bcf86b2ec2a44874c29ca7053135e3d72
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logSecurity for saccade-ai 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for saccade_ai-0.1.1.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.