thinformer / kvpress
CLAUDE.md9 starsChanged 36 days agoMITView on GitHub
kvpress is a library for efficiently compressing the key-value (KV) cache of pretrained transformers during long-context inference. It implements multiple training-free KV cache compression methods and provides benchmarking tools using π€ transformers. The repository contains: - kvpress/ - Core library implementing compression methods ("presses") - evaluation/ - Benchmarking framework and datasets - tests/ - Unit and integration tests - notebooks/ - Example notebooks and tutorials All compression methods inherit from BasePress (kvpress/presses/base_press.py): KVPressTextGenerationPipeline (kvpress/pipeline.py) is the main interface: runtime.py ([evaluation/runtime.py](evaluation/run
In this repositoryOne other file it gives its agents.
- examples/decoding/kvpress/CLAUDE.mdCLAUDE.md
The file
We split this CLAUDE.md into the rules it gives an agent
11 rules. About 0 are common, 4 are distinctive, and 7 are very specific to this project.
β0
Common Β· estimate
Many files like this have a rule of this kind.
β4
Distinctive Β· estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 76
All compression methods inherit from BasePress (kvpress/presses/base_press.py):
- Very specific: line 107
After each question, the answer is removed from cache via _remove_answer_from_cache()
- Very specific: line 120
Default values from EvaluationConfig dataclass
- Very specific: line 159
Add SPDX header: # SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES.
- Very specific: line 161
Add tests in tests/presses/
- Very specific: line 190
Remove answer from cache using _remove_answer_from_cache()
- Distinctive: line 195
SPDX headers: All Python files must include SPDX copyright header
- Distinctive: line 197
Import order: Use isort with 3-line mode
- Distinctive: line 199
Commit sign-off: All commits must be signed off (git commit -s)
- Distinctive: line 206
All tests must pass - skipped tests fail CI
- Very specific: line 227
Use SLURM for multi-node evaluation.
β βCommonβ is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. βVery specificβ is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
kvpress is a library for efficiently compressing the key-value (KV) cache of pretrained transformers during long-context inference. It implements multiple training-free KV cache compression methods and provides benchmarking tools using π€ transformers.
The repository contains:
kvpress/- Core library implementing compression methods ("presses")evaluation/- Benchmarking framework and datasetstests/- Unit and integration testsnotebooks/- Example notebooks and tutorials
Development Commands
Environment Setup
# Install with all dev dependencies using uv
uv sync --all-groups
# Install with optional dependencies
uv sync --extra flash-attn # For flash attention support
uv sync --extra eval # For evaluation benchmarksCode Quality
# Format code (runs isort + black)
make format
# Run style checks (flake8, mypy, SPDX headers)
make style
# Individual formatters
make isort # Sort imports
make black # Format codeTesting
# Run all tests
make test
# Run specific test file
uv run pytest tests/test_pipeline.py -v
# Run with coverage
uv run pytest --cov=kvpress/ tests/
# Run single test
uv run pytest tests/test_pipeline.py::test_name -vEvaluation
# Navigate to evaluation directory first
cd evaluation
# Run evaluation with config file
python runtime.py --config_file evaluate_config.yaml
# Override config via command line
python runtime.py --dataset loogle --data_dir shortdep_qa \
--model meta-llama/Meta-Llama-3.1-8B-Instruct \
--press_name expected_attention --compression_ratio 0.5
# Multi-GPU evaluation
bash evaluate.shArchitecture
Press System (Core Abstraction)
All compression methods inherit from BasePress (kvpress/presses/base_press.py):
- BasePress - Abstract base class
compress()- Core compression logic (must be implemented by subclasses)forward_hook()- Hook registered to attention layers during prefilling__call__()- Context manager that registers/unregisters hooksreset()- Reset internal state between different contexts/questions
- ScorerPress - Subclass for score-based pruning methods
- Implements
score()method that assigns importance to each KV pair - Common base for methods like SnapKV, KnormPress, ExpectedAttentionPress, etc.
- Implements
- Wrapper Presses - Compose or modify other presses
ComposedPress- Chain multiple presses togetherAdaKVPress- Apply head-wise compression to any ScorerPressDecodingPress- Compress during token generation (not just prefilling)PrefillDecodingPress- Compress in both prefilling and decoding phases
Pipeline Architecture
KVPressTextGenerationPipeline (kvpress/pipeline.py) is the main interface:
- Three-phase execution:
preprocess()- Apply chat template, tokenize context and questions_forward()- Compress context, then generate answers for each questionpostprocess()- Return formatted results
- Key design decisions:
- Context compression is shared across all questions (one prefill pass)
- Each question gets its own generation phase
- Compression is NOT applied to question tokens (for fair benchmarking)
- After each question, the answer is removed from cache via
_remove_answer_from_cache()
- Timing infrastructure:
query_events- Track CUDA timing for decoding (list of dicts, one per question)prefill_context_events- Track context prefilling time (single dict, shared)prefill_question_events- Track question prefilling time (list of dicts, one per question)cache_sizes_tracking- Track cache size evolution during decoding
Evaluation Framework
runtime.py (evaluation/runtime.py) orchestrates benchmarking:
- Configuration hierarchy:
- Default values from
EvaluationConfigdataclass - Override with YAML config file (
evaluate_config.yaml) - Override with command-line arguments (highest priority)
- Default values from
- Execution flow:
_setup_model_pipeline() β _setup_press() β _load_and_prepare_dataset() β _run_inference() β _save_results() β _calculate_and_save_metrics() - Warmup + Timed runs:
NUM_WARMUPiterations to warm up GPU before timing- Separate tracking for warmup vs. timed runs
- Records: query times, compression times, prefill times (context + question)
- Output structure:
results/ βββ {dataset}__{model}__{press}__{target_size}/ βββ predictions.parquet # Per-sample predictions and timings βββ metrics.json # Aggregate metrics βββ config.yaml # Full configuration βββ times/ βββ times.json # Detailed timing breakdown
Registry System
evaluate_registry.py defines three registries:
PRESS_REGISTRY- Maps press names to press instancesDATASET_REGISTRY- Maps dataset names to HuggingFace dataset pathsSCORER_REGISTRY- Maps dataset names to scoring functions
Important Patterns
Adding a New Press
- Inherit from
BasePressorScorerPress - Implement
compress()method (orscore()for ScorerPress) - Add SPDX header:
# SPDX-FileCopyrightText: Copyright (c) 1993-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - Register in
evaluate_registry.pyfor benchmarking - Add tests in
tests/presses/ - See notebooks/new_press.ipynb for step-by-step guide
Context Manager Pattern
Presses use context managers to temporarily register hooks:
with press(model):
# Compression is active during this block
outputs = model(inputs)
# Hooks are automatically unregisteredCUDA Event Timing
The codebase uses CUDA events for GPU timing:
events = defaultdict(list) # layer_idx -> [(start_event, end_event), ...]
outputs = model(..., query_events=events)
torch.cuda.synchronize()
elapsed_ms = start.elapsed_time(end)Multi-Question Handling
- Context is prefilled once with compression
- For each question:
- Forward pass with question tokens (tracked separately)
- Autoregressive decoding
- Remove answer from cache using
_remove_answer_from_cache() - Cache is restored to post-context state for next question
Code Style Requirements
- SPDX headers: All Python files must include SPDX copyright header
- Line length: 120 characters (enforced by black)
- Import order: Use isort with 3-line mode
- Type hints: Encouraged but not strictly enforced (mypy runs with
ignore_missing_imports) - Commit sign-off: All commits must be signed off (
git commit -s)
Testing Philosophy
- Unit tests for individual presses in
tests/presses/ - Integration tests for pipeline behavior in
tests/integration/ - Decoding compression tests in
tests/test_decoding_compression.py - All tests must pass - skipped tests fail CI
- Coverage reports generated in
reports/coverage.xml
Special Considerations
Model Support
Tested with: LlamaForCausalLM, MistralForCausalLM, Phi3ForCausalLM, Qwen2ForCausalLM, Qwen3ForCausalLM, Gemma3ForConditionalGeneration. Other models may work if they follow similar architectures in transformers.
Flash Attention
Some presses (e.g., ObservedAttentionPress) require eager attention implementation. Flash Attention 2 is auto-detected and used when available, except when explicitly disabled.
Quantization
Supports transformers QuantizedCache (requires additional deps like optimum-quanto). Pass cache object to pipeline.
Timing vs. Compression Trade-offs
- Prefill compression reduces decoding time (smaller cache β faster attention)
- Some presses (e.g., KVzipPress) require multiple forward passes for compression
- Decoding compression adds overhead during generation but controls memory growth
Distributed Evaluation
Use SLURM for multi-node evaluation. Scripts in evaluation/:
- Activate venv in script:
source ../.venv/bin/activate - SLURM jobs start with clean environment (no inherited venv)
- Example:
launch-longbench-e.sh,launch-math500.sh
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

