A Deep Dive into KV Caching: The Key to LLM Inference Efficiency and Cost

When users interact with Large Language Models (LLMs) like ChatGPT or Claude, a common experience is a noticeable delay of several seconds from submitting a prompt to receiving the first token. Once generation begins, however, subsequent text appears rapidly. This phenomenon isn’t due to network latency but is determined by the autoregressive nature of the Transformer architecture and its core optimization mechanism: KV Caching.
1. Autoregressive Generation: The Token-by-Token Nature of LLMs
The text generation process of LLMs is autoregressive, meaning they predict one token at a time. To predict the (N+1)-th token, the model must take all previous 1 to N tokens as input for a full forward pass. During this process, although all input tokens are part of the computation, only the output at the very last token’s position—its hidden state—is used to predict the next token.
This mechanism introduces a significant computational redundancy issue: to generate the (N+2)-th token, the model needs to re-process all tokens from 1 to N+1, even though the computations for tokens 1 to N were already completed in the previous step. Without optimization, the computational load would grow quadratically with the sequence length, making real-time interaction impossible.
2. The Computational Bottleneck and Redundancy of the Attention Mechanism
To understand the source of this computational redundancy, we must delve into the core of the Transformer model: the self-attention mechanism. In each Transformer layer, every input token is mapped to three key vectors: Query (Q), Key (K), and Value (V).
When calculating the attention output for a specific token, its Q vector is used to perform a dot-product operation with the K vectors of all input tokens, yielding attention weights. These weights are then used to compute a weighted sum of the V vectors of all tokens, ultimately forming the context-aware representation for that token.
The bottleneck becomes apparent here: when generating the 51st token, the model needs to use the Q vector of the 51st token to compute against the K and V vectors of all 50 preceding tokens. However, in the previous step of generating the 50th token, the K and V vectors for tokens 1 to 49 had already been calculated and used. A naive autoregressive generation process would repeatedly recalculate these immutable K and V vectors, resulting in O(n²) computational waste.
3. KV Caching: A Space-for-Time Inference Accelerator
The idea behind KV Caching is straightforward: store the already computed K and V vectors to avoid recalculation. This mechanism divides the LLM inference process into two distinct phases:
Prefill Phase: When the model receives the user’s complete prompt, it performs a single, large-scale parallel computation, processing all input tokens at once. During this process, it calculates and stores the K and V vectors for the entire input sequence across every layer. This is a computationally intensive and time-consuming step, directly determining the user-perceived “Time To First Token” (TTFT).
Decoding Phase: Building on the KV cache generated in the prefill phase, the model begins generating new tokens one by one. For each new token, it only needs to compute its own Q, K, and V vectors. The new K and V vectors are then appended to the cache, and the new token’s Q vector is used to perform attention calculations with all historical K and V vectors in the cache. This process is computationally light and extremely fast, resulting in the rapid “streaming” of subsequent content.
By introducing KV Caching, the complexity of LLM inference is optimized from growing quadratically with sequence length to growing linearly, drastically improving generation efficiency. This seemingly simple optimization has become a cornerstone of all modern LLM inference frameworks, such as vLLM, TensorRT-LLM, and Text Generation Inference (TGI).
4. The VRAM Challenge and Advanced Optimization Solutions
While KV Caching saves computational time, it comes at the cost of significant VRAM overhead. The size of the cache is proportional to the batch size, sequence length, number of model layers, and head dimension. For example, with a 72B parameter model (like Qwen2 72B) that has 80 Transformer layers, each with potentially 64 attention heads and a head dimension of 128, the KV cache for just one token across all layers can be about 2.5MB at FP16 precision. For a context window of 4096 tokens, the KV cache for a single request would occupy nearly 10GB of VRAM.
As concurrent requests increase, the VRAM consumed by the KV cache can even exceed that of the model weights themselves, becoming the primary bottleneck for scaling inference services. To address this challenge, the industry has developed a series of advanced optimization techniques:
Grouped-Query Attention (GQA & MQA): Grouped-Query Attention (GQA) and Multi-Query Attention (MQA) significantly reduce the number of K/V vectors by allowing multiple Q heads to share the same set of K/V heads, thereby directly shrinking the KV cache size. The Llama 3 models, for instance, use GQA.
PagedAttention: Pioneered by the vLLM framework, this technique borrows the concept of virtual memory paging from operating systems. It divides the KV cache into non-contiguous blocks that are allocated and managed on demand, effectively solving memory fragmentation and improving VRAM utilization.
KV Cache Quantization: By reducing the data type of the KV cache from FP16 or FP32 to INT8 or even INT4, memory usage can be reduced several-fold. This method trades a small amount of precision for the ability to support longer contexts and higher concurrency.