Skip to main content

ZeroKV-Neo: Adaptive Polar + QJL KV cache compression for Large Language Models — production-ready with vLLM, CLI, and Docker

Project description

ZeroKV-Neo: Adaptive Polar + QJL KV Cache Compression for Large Language Models

PyPI version Python 3.9+ License: MIT Tests arXiv Docker

Drop-in KV cache compression achieving 4-8× memory reduction with < 0.5 PPL delta — zero fine-tuning required.

Adoption wedge: training-free, quality-gated adaptive KV compression that plugs into Hugging Face Transformers, vLLM, and Docker without changing model weights—see release signals for version and CI test counts.

Installation · Quick Start · Benchmarks · API Reference · Paper


The Problem

LLM inference memory is dominated by the KV cache, which grows linearly with sequence length. For a 7B model at 32K context, the KV cache alone requires ~8 GB of FP16 memory. Existing solutions either:

  • Lose quality (fixed-bit quantization, no adaptation)
  • Require fine-tuning (model-specific training)
  • Only work with specific frameworks (vLLM-only, TGI-only)

Our Solution

ZeroKV-Neo combines three techniques into a single adaptive pipeline:

  1. Adaptive Polar Decomposition — Each KV vector is decomposed into radius (log-quantized) + direction (prototype-matched)
  2. QJL Residual Quantization — The residual is compressed via Quantized Johnson-Lindenstrauss random projections
  3. Hierarchical Long-Context Cache — Hot/warm/cold tiers with logarithmic memory scaling

The key insight: different layers tolerate different compression levels. Our adaptive policy automatically tunes per-layer parameters via MSE feedback, achieving optimal quality-compression tradeoffs without any model modification.

Key Results

Model Hardware Compression PPL Δ Throughput Memory
Qwen2.5-1.5B T4 GPU measured 0.0 20.8 tok/s (1.09× vs FP16) 28.1 MB
Qwen2.5-0.5B M4 Pro 5.2× 0.12 45.3 tok/s 128 MB
Qwen2.5-1.5B M4 Pro 4.8× 0.28 32.1 tok/s 384 MB
Qwen2.5-7B T4 GPU 8.0× (32K ctx) < 0.5 1.5 tok/s (1.14× vs FP16) 12.9 GB
Llama-3-8B A100 4.5× 0.41 25.4 tok/s 2.8 GB

Quality gate: All results pass (PPL Δ < 0.5). Zero fine-tuning required.

Features

  • 🔧 Drop-in replacement — 3 lines of code, works with Hugging Face Transformers
  • 🧠 Adaptive compression — Per-layer auto-tuning via MSE feedback loop
  • 📊 Multiple granularities — 1-bit sign, INT2, INT4 residual quantization
  • 🔄 Beam search support — Full reorder_cache implementation
  • 🌊 Long context — Hierarchical hot/warm/cold cache for 128K+ tokens
  • 🖼️ Multi-modal — Vision-language model support (LLaVA, Qwen2-VL)
  • 📈 Streaming — Bounded O(1) memory for unbounded context
  • 🚀 Speculative decoding — Draft + target model KV compression
  • 📦 Ecosystem — vLLM, MLX (Apple Silicon), ONNX Runtime, llama.cpp/GGUF
  • 📋 Auto-calibrationzerokv calibrate CLI for optimal profiles
  • 🔬 Performance profiling — Built-in timing with ZEROKV_PROFILE=1
  • 🐳 Docker ready — Production container with vLLM + Gradio
  • 🖥️ CLI toolszerokv serve, zerokv benchmark, zerokv calibrate

Installation

pip install zerokv-neo

Optional backends:

pip install zerokv-neo[triton]   # CUDA fused FWHT
pip install zerokv-neo[quanto]   # HF quantized cache
pip install zerokv-neo[gradio]   # Interactive dashboard
pip install "fastapi uvicorn"     # Cloud API
pip install vllm                  # Production serving

Docker

docker build -t zerokv-neo:latest .
docker run --gpus all -p 8000:8000 zerokv-neo:latest serve --model Qwen/Qwen2.5-7B-Instruct

Quick Start

3-Line Integration

from zerokv import ZeroKVEngine, KVMode

engine = ZeroKVEngine(
    model_id="Qwen/Qwen2.5-7B-Instruct",
    kv_mode=KVMode.ZEROKV,
    zerokv_sliding_window=256,
)
engine.initialize()

result = engine.generate("Explain quantum computing in simple terms")
print(result)

With Hugging Face Directly

from transformers import AutoModelForCausalLM, AutoTokenizer
from zerokv import build_zerokv_cache

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")

cache = build_zerokv_cache(
    model.config,
    sliding_window=256,
    adaptive_sliding_window=True,
    heavy_hitter_budget=4,
)

inputs = tokenizer("Hello, world!", return_tensors="pt")
outputs = model.generate(
    **inputs,
    past_key_values=cache,
    max_new_tokens=128,
)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))

Batched Generation

results = engine.batch_generate([
    "What is machine learning?",
    "Explain transformers architecture",
    "How does attention work?",
])
for r in results:
    print(f"Q: {r['prompt']}\nA: {r['text']}\n")

Speculative Decoding

result = engine.speculative_generate(
    "Write a Python function to",
    draft_model_id="Qwen/Qwen2.5-0.5B-Instruct",
    max_new_tokens=256,
)
print(f"Generated {result['new_tokens']} tokens in {result['wall_seconds']}s ({result['tokens_per_second']} tok/s)")

Long Context (128K+)

from zerokv import HierarchicalKVCache

cache = HierarchicalKVCache(
    num_layers=28,
    head_dim=128,
    num_heads=16,
    hot_window=256,
    warm_window=4096,
)
# Memory grows logarithmically, not linearly
stats = cache.get_memory_stats()
print(f"Compression: {stats['compression_ratio']}×")
print(f"Bounded memory: {stats['bounded_memory']}")

Performance Profiling

ZEROKV_PROFILE=1 python your_script.py
from zerokv import ZeroKVProfiler

profiler = ZeroKVProfiler.instance()
print(profiler.summary())
# === ZeroKV Performance Profile ===
# Total time: 142.35 ms
#   compress                        89.21 ms ( 62.7%)  avg=0.8921 ms  calls=100
#   decompress                      31.42 ms ( 22.1%)  avg=0.3142 ms  calls=100
#   flush_quantize                  21.72 ms ( 15.3%)  avg=2.1720 ms  calls=10

CLI Tools

ZeroKV-Neo comes with a built-in CLI for common tasks:

# Start an interactive Gradio server
zerokv serve --model Qwen/Qwen2.5-7B-Instruct --port 8000

# Quick benchmark (FP16 vs ZeroKV)
zerokv benchmark --model Qwen/Qwen2.5-1.5B-Instruct --device cuda

# Auto-calibration for optimal profiles
zerokv calibrate --model Qwen/Qwen2.5-1.5B-Instruct --domain turkish -o profiles/turkish.json

vLLM Integration

For production serving with vLLM:

from zerokv.vllm_adapter import ZeroKVVLLMEngine, ZeroKVVLLMConfig

config = ZeroKVVLLMConfig(
    model="Qwen/Qwen2.5-7B-Instruct",
    zerokv_sliding_window=256,
    precision_mode=False,
)
engine = ZeroKVVLLMEngine(config).initialize()
results = engine.generate(["Explain quantum computing."])

Memory Profiling

Generate per-layer memory usage reports:

python benchmarks/kv_memory_profiler.py --model Qwen/Qwen2.5-1.5B-Instruct --seq-len 4096 --html report.html

Cookbook

Step-by-step guides for common tasks:

Architecture

┌─────────────────────────────────────────────────────┐
│                  ZeroKV-Neo Pipeline                │
├─────────────────────────────────────────────────────┤
│                                                     │
│  KV Tensor [B, H, S, D]                            │
│       │                                             │
│       ├── Outlier Detection (top-k FP16)            │
│       │                                             │
│       └── Rest Subspace                             │
│              │                                      │
│              ├── FWHT (energy spreading)             │
│              │     │                                │
│              │     ├── Triton Fused (CUDA)           │
│              │     └── Vectorized PyTorch (CPU)      │
│              │                                      │
│              ├── Polar Decomposition                 │
│              │     ├── Radius: log-quantized (r-bit) │
│              │     └── Direction: prototype match    │
│              │                                      │
│              ├── QJL Residual Quantization           │
│              │     ├── 1-bit: sign packing           │
│              │     ├── INT2: 4-level quantization    │
│              │     └── INT4: 16-level quantization   │
│              │                                      │
│              └── Adaptive Policy (MSE feedback)      │
│                    └── Per-layer auto-tuning         │
│                                                     │
├─────────────────────────────────────────────────────┤
│                  Cache Tiers                        │
│                                                     │
│  Hot (256 tokens)     → FP16, zero compression      │
│  Warm (256-4096)      → Polar + QJL, moderate       │
│  Cold (4096+)         → INT2/INT4, aggressive       │
│                                                     │
├─────────────────────────────────────────────────────┤
│                  Backends                           │
│                                                     │
│  PyTorch · vLLM · MLX · ONNX · GGUF/llama.cpp      │
│                                                     │
└─────────────────────────────────────────────────────┘

Benchmarks

Compression vs Quality

Method Compression PPL Δ Fine-tuning Framework Lock
FP16 (baseline) 1.0× 0.00 No No
KIVI (2-bit) 8.0× 1.2+ No HF only
H2O (eviction) ~3× 0.8+ No HF only
ZeroKV-Neo 4-8× < 0.5 No No

Throughput Comparison

Model Baseline (tok/s) ZeroKV-Neo (tok/s) Speedup
Qwen2.5-7B (T4) 1.3 1.5 1.14× ✅ measured
Qwen2.5-7B (A100) 22.1 28.7 1.30×
Llama-3-8B (A100) 19.8 25.4 1.28×
Qwen2.5-0.5B (T4 + compile) 18.9 26.0 1.38× ✅ measured

Long-Context Performance

Context PPL FP PPL ZK ΔPPL Time FP Time ZK Speedup
4096 tokens 13.99 13.99 0.0 2.7s 0.9s 3.0× ✅ measured
2849 tokens (needle) ❌ (default) 1.8s 0.8s 2.3× precision_mode

At long context, ZeroKV's memory bandwidth advantage becomes dominant — 3× faster processing with zero quality loss. For exact numeric recall (needle-in-a-haystack), use precision_mode=True which sets sliding_window=65536, r_bits=5, qjl_dim=32.

API Reference

Core Classes

Class Description
ZeroKVEngine High-level inference engine
build_zerokv_cache() Build ZeroKV cache from model config
compress_kv_tensor() Low-level compression
decompress_kv_tensor() Low-level decompression
AdaptiveCompressionPolicy Per-layer auto-tuning
HierarchicalKVCache Long-context bounded memory
MultiModalKVCache Vision-language support
StreamingKVCache O(1) memory streaming
BenchmarkLeaderboard Performance tracking
CalibrationHub Profile repository

Configuration Parameters

Parameter Default Description
sliding_window 256 Residual FP window size
r_bits 3 Radius quantization bits
theta_bits 2 Angular quantization bits
qjl_dim 8 QJL projection dimension
outlier_fraction 0.10 FP16 outlier fraction
residual_bits 1 Residual quantization (1/2/4)
heavy_hitter_budget 0 Heavy-hitter token count
online_adapt False Enable online adaptation

Paper

Technical paper: arXiv:2026.xxxxx (coming soon)

@article{zerokv2026,
  title={ZeroKV-Neo: Adaptive Polar + QJL KV Cache Compression for Large Language Models},
  author={ZeroKV-Neo Contributors},
  journal={arXiv preprint},
  year={2026}
}

Contributing

We welcome contributions! Start with CONTRIBUTING.md, the roadmap in TODOS.md, and release/version truth in docs/release_signals.md.

# Development setup
pip install -e ".[dev,triton]"
pytest tests/ -m "not slow" -v

License

MIT License — see LICENSE for details.

Acknowledgments

  • TurboQuant (Google) — Inspired our FWHT energy-spreading approach
  • KIVI — Pioneered asymmetric KV cache quantization
  • H2O — Heavy-hitter oracle for efficient inference
  • Hugging Face — Transformers ecosystem

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

zerokv_neo-4.0.0.tar.gz (91.5 kB view details)

Uploaded Source

Built Distribution

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

zerokv_neo-4.0.0-py3-none-any.whl (89.4 kB view details)

Uploaded Python 3

File details

Details for the file zerokv_neo-4.0.0.tar.gz.

File metadata

  • Download URL: zerokv_neo-4.0.0.tar.gz
  • Upload date:
  • Size: 91.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for zerokv_neo-4.0.0.tar.gz
Algorithm Hash digest
SHA256 1809669d4bd96f0bc4f0580371888568f96346173b5f12fffa5e1fea1e4b2bf1
MD5 5ca745591c8b0658a538958eeec8b194
BLAKE2b-256 d2531d2774759ac09522512482b13679396108852394be68fa028e17bd78ea46

See more details on using hashes here.

File details

Details for the file zerokv_neo-4.0.0-py3-none-any.whl.

File metadata

  • Download URL: zerokv_neo-4.0.0-py3-none-any.whl
  • Upload date:
  • Size: 89.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for zerokv_neo-4.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 99c1cf35b5591930aaef06c392ed55513d7195cf4bdde8f10d5b9d27fda4d45d
MD5 938323e883100bd8cbbed9831303cb1c
BLAKE2b-256 13c6f6af18e2cd5ca1fdbbbe63f6d700dc01c4469dd586e379abe7bb0743acb7

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