Skip to main content

Adaptive KV cache compression for transformer models

Project description

KV-Codec

Adaptive KV cache compression for transformer models. Automatically detects which compression axes are viable for a given model, selects the best codec, and reports quality vs. compression tradeoffs.

How It Works

Transformer KV caches are redundant along two axes:

  • Sequence axis — adjacent token positions have similar keys/values (temporal locality)
  • Layer axis — adjacent layers produce correlated KV representations (depth locality)

KV-Codec measures both axes at runtime, then routes to the best strategy:

Strategy When selected Typical ratio
SEQ_ONLY Sequence axis compressible, layer axis not 2–8×
LAYER_ONLY Layer axis compressible, sequence axis not 2–4×
JOINT_2D Both axes compressible 4–16×
NONE Neither axis compressible

All codecs use I-frame/P-frame style compression: anchor positions store full vectors, non-anchors store INT8 quantized residuals from the nearest anchor.

Installation

pip install .

Or for development:

pip install -e ".[dev]"

Requirements: Python ≥ 3.9, PyTorch ≥ 2.0, Transformers ≥ 4.35

Quick Start

from transformers import AutoModelForCausalLM, AutoTokenizer
from kvcodec import KVSystem

model     = AutoModelForCausalLM.from_pretrained("facebook/opt-125m")
tokenizer = AutoTokenizer.from_pretrained("facebook/opt-125m")

system  = KVSystem(model, tokenizer, device="cpu")
profile = system.detect()        # measure both axes
results = system.benchmark()     # sweep all viable strategies
system.print_report()            # print full summary + recommendation

Use a specific codec directly

from kvcodec import SeqCodec, SeqCodecConfig

codec      = SeqCodec(SeqCodecConfig(anchor_stride=8))
compressed = codec.compress(keys, values)   # keys/values: [H, T, D] tensors
k_rec, v_rec = codec.decompress(compressed)
metrics    = codec.metrics(keys, values, compressed)
# {'cosine_sim_k': 0.9973, 'compression_ratio': 4.2, 'bytes_saved_pct': 76.2, ...}

Benchmark throughput impact

python benchmark_throughput.py
python benchmark_throughput.py --model facebook/opt-350m --max-new-tokens 200
python benchmark_throughput.py --model meta-llama/Llama-2-7b-hf --kv-seq-len 1024

Codecs

SeqCodec — Sequence axis

Anchors placed every anchor_stride tokens. Non-anchor positions store INT8 quantized residuals from the nearest anchor. Optional L2 normalization before residual computation.

from kvcodec import SeqCodec, SeqCodecConfig

codec = SeqCodec(SeqCodecConfig(
    anchor_stride=16,       # 1 anchor per 16 tokens
    quantize_bits=8,
    normalize_residuals=True,
))

LayerCodec — Layer axis

Anchor layers store full KV tensors. Non-anchor layers store residuals from the nearest anchor layer.

from kvcodec import LayerCodec, LayerCodecConfig

codec = LayerCodec(LayerCodecConfig(
    anchor_layer_stride=4,  # 1 anchor per 4 layers
    quantize_bits=8,
))

JointCodec — 2D joint (best compression)

Operates on both axes simultaneously. Anchors placed at (anchor_layer, anchor_position) grid intersections. Residuals computed from the nearest 2D anchor, giving smaller residuals and better quantization.

from kvcodec import JointCodec, JointCodecConfig

codec = JointCodec(JointCodecConfig(
    seq_anchor_stride=16,
    layer_anchor_stride=4,
    quantize_bits=8,
))

KVPredictor — Optional MLP predictor

A lightweight MLP (15–50K params) that predicts KV vectors from anchor + positional delta, reducing residuals before quantization. Train it on your target domain for best results.

from kvcodec import KVPredictor, PredictorTrainer

predictor = KVPredictor(head_dim=64)
trainer   = PredictorTrainer(predictor, mode='joint')
trainer.train(all_keys, all_values, epochs=10)
trainer.save("predictor.pt")

Adaptive Selection

from kvcodec import KVDetector, select_codec

detector = KVDetector(max_seq_len=128)
profile  = detector.detect(model, tokenizer)

print(profile.strategy)           # CodecStrategy.JOINT_2D
print(profile.layer_sim_adj)      # 0.842
print(profile.seq_sim_adj)        # 0.671
print(profile.estimated_compression_ratio())  # 6.3

codec = select_codec(profile)     # returns the right codec, pre-configured

Configuration Reference

Parameter Default Description
anchor_stride 8 Token positions between seq anchors
layer_anchor_stride 4 Layers between layer anchors
quantize_bits 8 Residual quantization bits
normalize_residuals True L2-normalize before residual computation
use_predictor False Use MLP predictor to reduce residuals

Global thresholds (in kvcodec/config.py):

Constant Value Description
LAYER_AXIS_THRESHOLD 0.70 Min layer similarity to enable layer compression
SEQ_AXIS_THRESHOLD 0.50 Min seq similarity to enable seq compression
JOINT_BONUS_THRESHOLD 0.05 Min joint bonus to prefer JOINT_2D over single-axis

Testing

# Fast unit tests (no model required, ~seconds)
pytest tests/

# Include integration tests (downloads opt-125m, ~minutes)
pytest tests/ -m slow

# Full standalone test script
python test_system.py

Project Structure

kvcodec/
├── config.py        # thresholds, enums, codec config dataclasses
├── detector.py      # adaptive axis detection
├── codec_seq.py     # sequence-axis codec
├── codec_layer.py   # layer-axis codec
├── codec_joint.py   # 2D joint codec
├── predictor.py     # MLP motion predictor + trainer
├── selector.py      # codec routing and Pareto sweep
└── system.py        # top-level orchestrator
benchmark_throughput.py   # wall-clock + memory impact benchmark
test_system.py            # full pipeline integration test
tests/                    # pytest suite
examples/                 # usage examples

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

kvcodec-0.1.0.tar.gz (30.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

kvcodec-0.1.0-py3-none-any.whl (34.5 kB view details)

Uploaded Python 3

File details

Details for the file kvcodec-0.1.0.tar.gz.

File metadata

  • Download URL: kvcodec-0.1.0.tar.gz
  • Upload date:
  • Size: 30.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for kvcodec-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fb92ea1e3b0ade34ef64df931f64ae78f39664d1697e761ab2cc4557430a8d76
MD5 29a53939d9e309cc7008b53c57f5600c
BLAKE2b-256 2712b19c7c9b6af63743dc22eb56e06a2751d76968d2a04defdde2c3e9189a97

See more details on using hashes here.

File details

Details for the file kvcodec-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: kvcodec-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 34.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for kvcodec-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e86e6ed27edfc6d8a5de279299b7666348aa9040774c126ae09ab1078c4430b6
MD5 9bea1a9d3c2dc9dd5280eecf61688b4c
BLAKE2b-256 757d3c1bac49501ddb70d31991fd9ddbb12d1c52d47fa60d95e7851be23b5523

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page