
Quantizing the KV Cache Without Wrecking Quality
Explore techniques for quantizing the KV cache to reduce memory usage and improve throughput for long context windows in LLMs.
In large language model (LLM) inference, the Key-Value (KV) cache is the primary bottleneck for long-context performance. As the sequence length grows, the memory required to store past token representations scales linearly, often exceeding GPU memory limits before compute becomes the constraint. Quantizing the KV cache—reducing the bit-width of stored key and value tensors—offers a direct path to higher throughput and longer context windows. However, naive quantization can degrade generation quality because the KV cache contains activation values prone to outliers that are difficult to compress without information loss.
The KV Cache Bottleneck
During autoregressive generation, an LLM computes attention over all previous tokens. The attention mechanism requires access to the keys () and values () for every token in the sequence history. These are stored in the KV cache, a buffer that grows by one row per token generated. For a model with dimensions, transformer layers, and a batch size of , the memory footprint is approximately:
Where is the sequence length. In a typical 7B parameter model with 4096 hidden dimensions and 32 layers, storing the KV cache in float16 (2 bytes) for a sequence of 8,000 tokens and batch size 1 consumes roughly 4 GB. While this seems manageable, batch sizes increase with shorter sequences, and context lengths in production often exceed 32K tokens. At 32K tokens, the same model requires ~16 GB just for the KV cache, leaving little room for additional batches or larger models. The pursuit of memory savings becomes critical when scaling to long context scenarios where every megabyte counts.
The problem is not just capacity; it’s bandwidth. Reading the KV cache during each decoding step consumes significant memory bandwidth. Reducing the bit-width directly lowers both the storage requirement and the bandwidth needed to fetch these tensors, enabling higher effective batch sizes or longer contexts.
Quantization Techniques: INT8, FP8, and INT4
Quantizing the KV cache involves mapping high-precision floating-point values to lower-bit integers or reduced-precision floats. For kv cache quantization, two main approaches dominate the landscape of optimization strategies.
INT8 Quantization
INT8 quantization represents each tensor element using 8-bit integers. To do this, the system applies a scale factor and zero-point to map the original float range to the integer domain:
Where is the original float value and is the quantized integer. During inference, the quantized values are dequantized on-the-fly or used in specialized INT8 matmul kernels that avoid full dequantization. Per-tensor scaling (a single scale for the entire tensor) is simple but often insufficient for the KV cache due to its wide dynamic range. Per-token or per-head scaling, where each token or attention head has its own scale factor, preserves more detail at the cost of metadata overhead.
FP8 Quantization
FP8 (E4M3 or E5M2 formats) offers a middle ground between INT8 and float16. FP8 provides 3 bits of mantissa (E4M3) or 2 bits (E5M2), along with exponent bits. This allows it to represent a wider range of values than INT8 while still using less memory than float16. NVIDIA’s Hopper architecture and newer AMD GPUs support native FP8 tensor cores, making fp8 kv cache quantization highly efficient on modern hardware. The key advantage is that FP8 retains some precision for small values, which is critical for attention scores that can be very small.
INT4 and Beyond
INT4 quantization reduces memory further but introduces significant quantization error. For the KV cache, INT4 is rarely used without additional techniques like grouped quantization or mixed precision, because the loss of precision can lead to noticeable degradation in text coherence. However, for extremely long contexts where memory is the absolute constraint, INT4 may be viable if combined with other compression methods like pruning or eviction policies.
Why KV Cache Quantization Is Harder Than Weight Quantization
Quantizing model weights is well-studied because weights are static and trained to be robust to perturbations. The KV cache, however, consists of activations that change dynamically during inference. Activations often exhibit "outliers"—values that are significantly larger than the mean—which dominate the quantization scale. If the scale is determined by the maximum value, most values are quantized to near-zero, losing critical information.
For example, in a self-attention layer, the key vectors might have a few tokens with unusually large norms due to rare vocabulary or complex syntactic structures. A uniform scale factor would compress these outliers into a narrow range, distorting the attention distribution. This distortion can cause the model to attend to the wrong tokens, leading to incoherent generations.
Preserving Quality: Outlier-Aware and Mixed Precision
To mitigate quality loss, several techniques have been developed:
Outlier-Aware Quantization
This approach identifies and protects outlier values. Instead of applying a single scale factor, the system detects values that fall outside a certain percentile (e.g., top 1%) and handles them separately. For instance, outliers might be stored in float16 while the rest are quantized to INT8. This mixed-precision approach preserves the most critical information while still achieving significant memory savings.
Per-Token Scaling
Rather than using a single scale for the entire KV cache, per-token scaling assigns a unique scale factor to each token. This allows the quantization to adapt to the local dynamic range of each token’s key and value vectors. While this increases metadata overhead (one scale factor per token per head), it significantly improves accuracy compared to per-tensor scaling.
Grouped Quantization
Grouped quantization divides the KV cache into smaller groups (e.g., by head or by layer) and applies separate scale factors to each group. This reduces the impact of outliers by isolating them within a group, allowing the rest of the values to be quantized more precisely.
Post-Training Calibration
Before deploying a quantized model, engineers perform calibration by running a small dataset through the model and collecting statistics on the KV cache values. These statistics inform the choice of scale factors and zero-points. Calibration ensures that the quantization ranges are aligned with the actual distribution of values encountered during inference, rather than relying on theoretical bounds.
Practical Implementation Considerations
When implementing kv cache quantization, engineers must consider several factors related to llm optimization and memory efficiency:
-
Hardware Support: Not all GPUs support efficient INT8 or FP8 inference. Check your hardware’s capabilities before choosing a quantization format. NVIDIA H100, AMD MI300, and newer NVIDIA GPUs support native FP8 tensor cores. For INT8 support, older architectures like A100 are still relevant, but FP8 requires Hopper or newer.
-
Framework Support: Libraries like Hugging Face Transformers, vLLM, and TensorRT-LLM offer built-in support for KV cache quantization. For example, vLLM supports FP8 KV cache quantization out of the box, while TensorRT-LLM provides tools for calibrating and deploying quantized models.
-
Latency vs. Throughput: Quantization reduces memory bandwidth, which can improve throughput. However, the overhead of quantizing and dequantizing values can add latency. Benchmark both metrics to determine the optimal trade-off for your use case.
-
Quality Evaluation: Always evaluate the impact of quantization on generation quality. Use metrics like perplexity, BLEU, or human evaluation to ensure that the compressed KV cache does not degrade output coherence. Pay special attention to long-context tasks, where the KV cache is most critical for inference stability.
Common Pitfalls
When adopting KV cache quantization, engineers often encounter specific traps that undermine performance:
- Ignoring Outlier Distribution: Assuming a uniform distribution of activation values leads to catastrophic precision loss. Outliers often carry semantic importance; failing to isolate them results in incoherent outputs.
- Using Per-Tensor Scaling for High-Variance Models: Global scale factors are too coarse for models with high activation variance. This leads to significant quantization error, particularly in attention heads that exhibit distinct dynamic ranges.
- Overlooking Framework Support: Attempting to implement custom quantization logic without leveraging existing framework optimizations (like vLLM’s PagedAttention) can introduce subtle bugs and performance regressions.
Practical Takeaways
For engineers looking to implement these optimizations, consider these key actions:
- Start with FP8 on Supported Hardware: If your GPU supports FP8 tensor cores, prioritize FP8 over INT8 for better precision retention with minimal overhead.
- Implement Outlier Protection: Use mixed-precision schemes where outliers are stored in higher precision (e.g., float16) while the bulk of the cache uses lower precision (e.g., INT8).
- Benchmark Rigorously: Always measure both throughput (tokens/sec) and latency (TTFT, ITL) alongside quality metrics like perplexity to ensure the trade-offs are justified.
FAQ
Q: Does KV cache quantization affect training? A: No, KV cache quantization is strictly an inference-time optimization. Training involves backpropagation and gradient computation, which require full precision.
Q: How much memory can I save with INT8 vs. Float16? A: INT8 quantization reduces the memory footprint by approximately 50% compared to Float16, as each element uses 8 bits instead of 16 bits.
Q: Is FP8 KV cache quantization widely supported? A: Support is growing rapidly. Major frameworks like vLLM and TensorRT-LLM support it, but it requires hardware with FP8 tensor cores (e.g., NVIDIA H100, H200, or Blackwell).
Conclusion
Quantizing the KV cache is an effective method for improving LLM inference efficiency, especially for long-context applications. By reducing the bit-width of stored key and value tensors, engineers can significantly lower memory usage and increase throughput. However, the dynamic nature of activations and the presence of outliers make KV cache quantization more challenging than weight quantization. Techniques like outlier-aware quantization, per-token scaling, and mixed precision are essential for preserving generation quality.
Audit your current KV cache memory usage and benchmark FP8 vs INT8 on your specific hardware to determine the optimal configuration for your deployment.
Related posts
SGLang's RadixAttention, Explained
An examination of SGLang's RadixAttention mechanism, focusing on prefix caching, radix trees, and throughput optimization for ML infrastructure.
PagedAttention vs RadixAttention: Solving KV Cache Fragmentation and Redundancy
Compare PagedAttention and RadixAttention for LLM inference. Learn how these techniques optimize KV cache memory fragmentation and improve sharing efficiency.
Multi-Head, Grouped-Query, and Multi-Head Latent Attention
An examination of Multi-Head Attention, Grouped-Query Attention, and Multi-Head Latent Attention variants, focusing on KV cache size optimization and inference speed.