Quadratic Attention Bottleneck › Memory Analysis: The Attention Matrix
Language AI HandbookAll chapters Quadratic Attention Bottleneck › Memory Analysis: The Attention MatrixOne section · Sections in this chapter3 / 13 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Memory is often the first constraint that prevents you from extending sequence lengths, and the source of that constraint is the attention score matrix. To understand why, consider what must be stored during a single forward pass of a transformer with self-attention.
For every attention head, the model must compute and store an matrix of attention scores before applying softmax. This matrix is not just used once: it drives the final weighted aggregation of value vectors, and during training it must be retained for the backward pass so that gradients can flow back through the softmax operation. The result is that the attention matrix lives in GPU memory for the entire duration of the forward and backward pass, consuming resources proportional to the square of the sequence length.
Think of the attention matrix as a large lookup table. For a sequence of 1,024 tokens, the table has 1,024 rows and 1,024 columns, totaling roughly one million entries. For 8,192 tokens, the table grows to 67 million entries. For 32,768 tokens, it reaches one billion entries. At two bytes per entry (fp16), that single table consumes roughly 2 gigabytes for the 32K case, and that's just one head of one layer.
The total memory required to store attention matrices across all heads and all layers in a transformer can be expressed concisely. For a model with attention heads and layers, with each layer computing an attention matrix per head at precision bytes per element:
where:
- : total memory in bytes for all attention matrices
- : number of attention heads (each head computes an independent attention pattern)
- : sequence length (number of tokens)
- : the number of entries in each attention matrix, one score per query-key pair
- : bytes per element (4 for fp32, 2 for fp16/bf16, often 2 in modern practice)
- : number of transformer layers (each layer adds another full set of attention matrices)
Notice that this formula has as its only non-linear term. Every other factor (, , ) is a constant that scales linearly with model size. The sequence length is unique in appearing squared, which is why attention memory grows so much faster than model size as context lengths increase.
Worked Example: A Concrete Memory Calculation
Let's make this concrete with a real calculation. Consider a LLaMA 7B-style model with 32 attention heads, 32 layers, and fp16 precision ( bytes). At a sequence length of 8,192 tokens:
Working through the calculation step by step:
This is before counting model weights, activations, gradients, or optimizer states. A LLaMA 7B model at 8,192 tokens already needs 128 GB for attention matrices alone, far exceeding the 80 GB capacity of an H100 GPU. This is the memory wall in concrete form.
def attention_matrix_memory_gb(n, n_heads, n_layers=1, dtype_bytes=2):
"""
Calculate memory for attention matrices.
Args:
n: Sequence length
n_heads: Number of attention heads
n_layers: Number of transformer layers
dtype_bytes: Bytes per element (2 for fp16, 4 for fp32)
Returns:
Memory in gigabytes
"""
# Each layer stores n_heads attention matrices of size n x n
bytes_per_layer = n_heads * n * n * dtype_bytes
total_bytes = bytes_per_layer * n_layers
return total_bytes / (1024**3)
# Model configurations
configs = [
{"name": "GPT-2 Small", "heads": 12, "layers": 12},
{"name": "GPT-2 Medium", "heads": 16, "layers": 24},
{"name": "LLaMA 7B", "heads": 32, "layers": 32},
]
sequence_lengths = [512, 2048, 8192, 32768]Attention Matrix Memory (fp16): GPT-2 Small (12 heads, 12 layers): n= 512: 0.07 GB n= 2,048: 1.12 GB n= 8,192: 18.00 GB n=32,768: 288.00 GB GPT-2 Medium (16 heads, 24 layers): n= 512: 0.19 GB n= 2,048: 3.00 GB n= 8,192: 48.00 GB n=32,768: 768.00 GB LLaMA 7B (32 heads, 32 layers): n= 512: 0.50 GB n= 2,048: 8.00 GB n= 8,192: 128.00 GB n=32,768: 2048.00 GB
The memory requirements reveal why long-context models are challenging. A GPT-2 Small model at 512 tokens uses only about 0.07 GB for attention matrices, which is negligible at that length. At 8,192 tokens, this grows to nearly 18 GB. At 32K tokens, a modest 12-layer model requires over 280 GB just for attention, exceeding the memory of any single GPU. Larger models with more heads and layers face even steeper memory walls at shorter sequence lengths.
The progression across model sizes is particularly telling. GPT-2 Small (a relatively tiny model by today's standards) exhausts a 24 GB GPU around 16K tokens. LLaMA 7B hits the same limit much earlier. This is why production long-context models universally rely on memory-efficient attention implementations like FlashAttention: standard attention is simply not practical for the sequence lengths that modern applications require.

The plot shows that even the smallest model configuration exceeds a 24 GB GPU around 16K tokens, and an 80 GB GPU around 32K tokens. Larger models hit these limits much sooner. This memory wall is often the first constraint encountered when extending context length, and it explains why the earliest long-context research focused on memory reduction rather than computational speedup. Saving memory, as FlashAttention famously demonstrated, can be a more impactful contribution than saving compute.