We applied video compression to LLM inference. The result: 10,000x less quantization error at the same storage cost.
In video, you don't re-encode every pixel every frame. You store a keyframe, then just the differences. We do the same thing for the KV cache in LLM inference.
The Insight
During autoregressive decoding, consecutive tokens produce nearly identical KV cache values. The hidden state for "The cat sat on the mat" differs from "The cat sat on the rug" by only ~1% at most dimensions.
Standard KV cache quantization (Q4_0) compresses absolute values to 4 bits. Delta-KV compresses the tiny difference between tokens to 4 bits instead. Same bits, vastly less error.
Standard Q4_0: value=0.5432 -> quantize -> reconstruct=0.5100 | error=0.0332
Delta Q4_0: delta=0.0032 -> quantize -> reconstruct=0.0030 | error=0.0002
^^^^^^^^
166x less error
The quantization error is proportional to the range of values being quantized. Deltas have 100x smaller range than absolute values, so the same 4 bits preserve 10,000x more information.
Benchmark Results
All benchmarks run on 4x AMD MI50 GPUs (128GB HBM2 total) with ROCm 6.3.3.
Model 1: Llama 3.1 70B (Q4_K_M) — Dense Transformer
Perplexity (WikiText-2, 20 chunks, ctx=512) - lower is better
| KV Cache Config | Perplexity | vs F16 Baseline | Verdict |
|---|---|---|---|
| F16 (baseline) | 3.2840 | - | - |
| Q8_0 | 3.2777 | -0.19% | OK |
| Q4_0 | 3.4683 | +5.61% | Degraded |
| Delta-KV (kf=16) | 3.3002 | +0.49% | Near-lossless |
| Delta-KV (kf=32) | 3.2926 | +0.26% | Near-lossless |
| Delta-KV (kf=64) | 3.3027 | +0.57% | Near-lossless |
Q4_0 loses 5.6% quality. Delta-KV loses only 0.26%. Same 4-bit storage, 22x less degradation.
Long Context (WikiText-2, 5-10 chunks)
| Context | F16 | Q4_0 | Delta-KV (kf=32) | Q4_0 degradation | Delta-KV degradation |
|---|---|---|---|---|---|
| 512 | 3.2840 | 3.4683 | 3.2926 | +5.61% | +0.26% |
| 1024 | 3.0403 | 3.2232 | 3.0390 | +6.02% | -0.04% |
| 2048 | 2.9882 | 3.1318 | 2.9891 | +4.80% | +0.03% |
| 4096 | 3.4612 | 3.6128 | 3.4655 | +4.38% | +0.12% |
| 8192 | 3.3027 | 3.4549 | 3.3038 | +4.61% | +0.03% |
| 16384 | 3.1349 | 3.2461 | 3.1428 | +3.55% | +0.25% |
Q4_0 degradation stays at 3.5-6% across all context lengths. Delta-KV stays under 0.3% — no error accumulation blowup, even at 16K tokens with 512 delta frames between keyframes.
Coding (C/C++ source corpus, 10 chunks)
Code has highly repetitive structure (braces, keywords, patterns), making it an ideal test for delta compression since consecutive KV states are very similar.
| Context | F16 | Q4_0 | Delta-KV (kf=32) | Q4_0 degradation | Delta-KV degradation |
|---|---|---|---|---|---|
| 512 | 3.0602 | 3.0893 | 3.0617 | +0.95% | +0.05% |
| 1024 | 2.8424 | 2.8624 | 2.8445 | +0.70% | +0.07% |
| 2048 | 2.8385 | 2.8686 | 2.8403 | +1.06% | +0.06% |
| 4096 | 2.1956 | 2.2127 | 2.1982 | +0.78% | +0.12% |
On code, Q4_0 degradation is smaller (~1%) because code tokens are more predictable. Delta-KV still reduces it by another 10-20x to under 0.12%.
Model 2: MiniMax-M2.5 (Q3_K_S, 92GB) — MoE (230B total, 10B active)
MoE models route each token through a sparse subset of expert FFN blocks. This creates more varied KV cache patterns than dense models — a harder test for delta compression.
WikiText-2 (20 chunks)
| Context | F16 | Q4_0 | Delta-KV (kf=32) | Q4_0 degradation | Delta-KV degradation |
|---|---|---|---|---|---|
| 512 | 9.9506 | 10.1941 | 9.9476 | +2.45% | -0.03% |
| 1024 | 9.7667 | 9.9953 | 9.7544 | +2.34% | -0.13% |
| 2048 | 11.1490 | 11.3744 | 11.2088 | +2.02% | +0.54% |
Coding (C/C++ source corpus, 10 chunks)
| Context | F16 | Q4_0 | Delta-KV (kf=32) | Q4_0 degradation | Delta-KV degradation |
|---|---|---|---|---|---|
| 512 | 2.8235 | 2.8933 | 2.8303 | +2.47% | +0.24% |
| 1024 | 2.4757 | 2.5219 | 2.4632 | +1.87% | -0.51% |
| 2048 | 2.7446 | 2.7817 | 2.7477 | +1.35% | +0.11% |
| 4096 | 2.0893 | 2.1138 | 2.0899 | +1.17% | +0.03% |
MoE takeaway: Delta-KV works across architectures. On coding tasks, it reduces Q4_0's degradation by 10-40x even on a MoE model with expert routing. The benefit is strongest on code where token-to-token KV similarity is highest.
Synthetic MSE Analysis
| Drift Rate | Standard Q4_0 MSE | Delta-Q4_0 MSE | Improvement |
|---|---|---|---|
| 1% | 1.46e-03 | 1.36e-07 | 10,778x |
| 5% | 3.35e-03 | 3.38e-06 | 991x |
| 10% | 8.24e-03 | 1.35e-05 | 609x |
| 20% | 2.68e-02 | 5.41e-05 | 495x |
How It Works
Token 1 (keyframe): store full F16 values -> KV cache
Token 2 (delta): delta = token2_values - token1_values
quantize delta to Q4_0 (tiny range -> high precision)
reconstruct = token1_values + dequant(delta)
store reconstructed -> KV cache
Token 3 (delta): delta = token3_values - token2_reconstructed
... same process, rolling reference
Token 33 (keyframe): reset reference (every N tokens)
This is exactly how video codecs work: I-frames (keyframes) + P-frames (deltas).
Also Included: Weight-Skip Prediction
During decode, the MMVQ kernel reads ~40GB of weights per token. We added an inline skip check that reads 4 bytes (weight scale + activation scale) to decide whether to skip the full 400-byte dot product.
| Config | Decode Speed | Quality Loss |
|---|---|---|
| Baseline | 9.3 t/s | - |
| Weight-Skip (1e-6) | 10.2 t/s (+10%) | Zero (PPL identical) |
Quick Start
# Build (requires ROCm or CUDA) cmake -B build -DGGML_HIP=ON -DAMDGPU_TARGETS=gfx906 cmake --build build -j$(nproc) # Run with delta-KV ./build/bin/llama-cli -m model.gguf -ngl 99 \ --delta-kv --delta-kv-interval 32 # Run with delta-KV + weight skip LLAMA_WEIGHT_SKIP_THRESHOLD=1e-6 ./build/bin/llama-cli -m model.gguf -ngl 99 \ --delta-kv --delta-kv-interval 32 # Run the benchmark yourself ./build/bin/llama-delta-kv-bench ./build/bin/llama-weight-skip-bench ./build/bin/llama-weight-analysis -m model.gguf
Files Changed
This is a fork of llama.cpp with minimal, surgical modifications:
New files (core):
ggml/src/ggml-cuda/delta-kv.cu/.cuh- GPU kernels for delta encode/reconstructsrc/llama-kv-cache-delta.cpp/.h- Delta KV processor (CPU fallback + GPU dispatch)ggml/src/ggml-cuda/weight-skip.cu/.cuh- Weight-skip predictor kernels
New files (benchmarks):
tools/delta-kv-bench/- Synthetic quality benchmark (MSE comparison)tools/weight-skip-bench/- Weight scale analysis and skip rate estimation
Modified files (11 files, ~195 lines added):
ggml/src/ggml-cuda/mmvq.cu- Inline weight-skip check in MMVQ inner loopsrc/llama-kv-cache.h/.cpp- Delta processor integrationsrc/llama-context.cpp- Post-processing hook after graph computeinclude/llama.h- API parameters (delta_kv,delta_kv_interval)common/arg.cpp/common.h/common.cpp- CLI flags
Related Work
- CacheGen (SIGCOMM 2024) - Delta encoding for KV cache network streaming (different target: network, not HBM)
- DeltaKV (2026) - Residual-based compression using MLP projection (higher overhead)
- KVTC (2025) - Transform coding (PCA + entropy coding, different technique)
- NVIDIA kvpress - KV cache compression framework
Our approach is distinguished by minimal overhead (no learned components, no entropy coding, no extra model parameters) and direct kernel integration in llama.cpp.
Hardware
Developed and tested on:
- 4x AMD Instinct MI50 (32GB HBM2 each, gfx906)
- AMD Ryzen Threadripper PRO 3945WX
- ROCm 6.3.3
- Ubuntu 24.04
The delta-KV technique is hardware-agnostic and benefits any GPU where KV cache bandwidth is a bottleneck (A100, H100, etc.).
License
Same as llama.cpp (MIT).