Recommended resources
The freely available resources this lesson will direct you to.
- KV Cache Crash Coursewww.youtube.com
- Transformers Key-Value Caching Explainedneptune.ai
- The KV Cache: Memory Usage in Transformerswww.youtube.com
- LLM inference optimization: Architecture, KV cache and Flash attentionwww.youtube.com
- Understanding and Coding the KV Cache in LLMs from Scratchmagazine.sebastianraschka.com
- How LLM Inference Works - Arpit Bhayaniarpitbhayani.me
Welcome to the third lesson in our series on LLM inference fundamentals. In the last session, we established that large language models generate text one token at a time, a process called autoregressive generation. We also noted a major inefficiency: to generate each new token, the model seems to re-process the entire history of the conversation.
Today, we'll investigate why this reprocessing is necessary by looking at the self-attention mechanism. Then, we'll introduce the elegant solution that makes modern LLMs practical: the KV cache. Understanding the interplay between attention and the KV cache is non-negotiable for an LLM Ops Engineer, as it is the primary driver of inference performance and GPU memory consumption.
By the end of this lesson, you will be able to identify the role of the attention mechanism and how the KV cache is used to optimize the token generation process during inference.
1. The Need for Context: Self-Attention
Why does a model need to look at all previous tokens just to predict the next one? It's because the meaning of a word depends on its context. The mechanism that allows an LLM to weigh the importance of different tokens in the input sequence is called self-attention.
At a high level, for each token in the sequence, self-attention generates three vectors:
- Query (Q): Represents the current token asking, "What context is relevant to me?"
- Key (K): Represents each token in the sequence announcing, "This is the kind of information I hold."
- Value (V): Represents the actual content or meaning of each token.
The model computes "attention scores" by matching the current token's Query vector with the Key vectors of all other tokens in the sequence. These scores determine how much "attention" the current token should pay to every other token. The scores are then used as weights to create a weighted average of all the Value vectors. The result is a new, context-rich representation for the current token.
The following video provides an excellent whiteboard explanation of this process and breaks down the famous attention formula.
The video "KV Cache Crash Course" from the AI Anytime channel offers a detailed recap of the self-attention mechanism.
Watch the section that provides a recap of self-attention. Don't worry about memorizing the exact formula. Instead, focus on understanding the conceptual roles of the Query, Key, and Value vectors and how they interact to calculate a context-aware representation for a token.
2. The Inefficiency of Naive Generation
In our last lesson, we saw that autoregressive generation happens in a loop. Now, combining that with the concept of self-attention, we can see the source of the inefficiency.
- To generate token #5, the model needs to compute attention scores. This involves the Query of token #4 interacting with the Keys and Values of tokens #1, #2, #3, and #4.
- To generate token #6, the model needs the Query of token #5 to interact with the Keys and Values of tokens #1, #2, #3, #4, and #5.
Notice the problem? The Key and Value vectors for tokens #1 through #4 are computed in the first step, and then recomputed again in the second step. This redundant computation gets worse with every new token, leading to a quadratic increase in workload () as the sequence grows.
The following article uses excellent diagrams to illustrate this exact problem.
Understanding and Coding the KV Cache in LLMs from Scratch
This article by Sebastian Raschka provides exceptionally clear diagrams that visualize the redundancy in the attention mechanism during text generation.
Read the first section of the article, titled "What Is a KV Cache?". Pay close attention to the series of diagrams that show how the key (k) and value (v) vectors are repeatedly recomputed for the same tokens at each generation step. This will give you a strong visual intuition for the problem we need to solve.
3. The Solution: The Key-Value (KV) Cache
The solution to this massive redundancy is conceptually simple but incredibly effective: caching. The KV cache is a memory buffer that stores the Key and Value vectors for each token once they are computed.
Hereās how it works in the two phases of inference:
-
Prefill Phase: The model processes the entire input prompt. For each token in the prompt, it calculates the K and V vectors and stores them in the KV cache. This "fills" the cache with the initial context.
-
Decode Phase: For each subsequent token generation step:
- The model only needs to compute the Q, K, and V vectors for the single, most recently generated token.
- It appends the new K and V vectors to the existing cache.
- The new token's Q vector is then compared against all the K vectors in the now-updated cache to calculate attention.
- A new token is generated, and the loop continues.
This caching mechanism transforms the computationally expensive decode step. Instead of recomputing everything, the model performs a small, constant amount of work for each new token, plus the work of attending to the growing cache. This reduces the complexity from quadratic to linear ().
The following video explains this process and its direct impact on memory and latency.
The KV Cache: Memory Usage in Transformers
This video, "The KV Cache: Memory Usage in Transformers" by Efficient NLP, clearly explains how the KV cache works and why it's so important for performance.
Please watch the following segments: First, a quick review of self-attention to solidify the concept. Next, watch the section explaining the inefficiency of recomputation. Then, see how the KV cache solves this problem. Finally, understand the difference in latency between processing the initial prompt (prefill) and generating subsequent tokens (decode).
This animated diagram beautifully illustrates a single step in the decode phase with the KV cache in action.

4. The Trade-Off: Speed vs. Memory
The KV cache is the key reason why the decode phase is memory-bandwidth bound. While each step is computationally light, it requires reading the entire, ever-growing K and V matrices from high-bandwidth GPU memory (HBM).
As an LLM Ops engineer, the size of this cache is a critical factor in capacity planning and cost modeling. The memory required for the KV cache grows linearly with the sequence length and the batch size.
The Efficient NLP video you just watched introduced the formula for calculating the cache size. Let's look at it again:
Cache Size = 2 * (precision) * (num_layers) * (d_model) * (sequence_length) * (batch_size)
Let's break that down:
- 2: Because we cache two matrices, K and V.
- precision: The number of bytes per parameter (e.g., 2 bytes for FP16).
- num_layers: The number of transformer blocks in the model.
- d_model: The dimension of the model's hidden state.
- sequence_length: The number of tokens in the context.
- batch_size: The number of sequences being processed in parallel.
You can see that for large models with long context windows and high batch sizes, the KV cache can consume a massive amount of GPU memory, often more than the model weights themselves! We will dive deeper into these calculations in the next lesson.
Summary
In this lesson, we demystified one of the most important optimizations in LLM inference. The performance of modern LLMs would be untenable without the KV cache.
Here are your key takeaways:
- The self-attention mechanism allows a model to understand context by computing relationships between tokens using Query, Key, and Value vectors.
- Without caching, this process is highly inefficient, recomputing Key and Value vectors for the entire context at every single step of token generation.
- The KV cache solves this by storing these vectors, turning a quadratically complex operation into a linear one and dramatically speeding up the
decodephase. - This optimization comes at a cost: the KV cache is a significant consumer of GPU memory, and its size grows with sequence length and batch size.
- The presence of the KV cache is what makes the initial prefill phase (compute-bound) computationally distinct from the subsequent decode phase (memory-bandwidth-bound).
Now that you understand that both model weights and the KV cache are major consumers of GPU memory, our next lesson will focus on how to perform the essential calculations for both. You will learn how to estimate the total memory footprint of a model, a fundamental skill for infrastructure provisioning and performance tuning.