Navigation
🏋️ Training Systems· 12 min read

Activation Memory Analysis

What is saved for backward, per-layer cost formulas, attention's O(s²) contribution, and strategies to reduce activation memory.

activationsmemorybackwardcheckpointingsequence-lengthtransformer

Activations are the intermediate tensors saved during forward pass for backward computation. Unlike static memory (parameters + optimizer), activation memory scales with batch size and sequence length — it’s the “variable cost” that determines your maximum batch size and sequence length.


1. What Gets Saved and Why

PyTorch’s autograd saves tensors needed for gradient computation. For each operation y=f(x)y = f(x), the backward pass needs either xx, yy, or both:

OperationSaved for backwardWhy
Linear (y=Wxy = Wx)Input xx∂L∂W=δ⋅xT\frac{\partial L}{\partial W} = \delta \cdot x^T, ∂L∂x=WT⋅δ\frac{\partial L}{\partial x} = W^T \cdot \delta
ReLU (y=max⁡(0,x)y = \max(0, x))Boolean mask (x>0x > 0)Gradient is 0 or pass-through
SiLU/GELUInput xxNon-trivial derivative
SoftmaxOutput yy∂yi∂zj=yi(δij−yj)\frac{\partial y_i}{\partial z_j} = y_i(\delta_{ij} - y_j)
LayerNormInput xx, mean, varianceNeeds original statistics
DropoutBinary maskSame mask applied in backward
Attention (softmax(QKT/d)V\text{softmax}(QK^T/\sqrt{d})V)Q, K, V, attention weightsFull chain rule through softmax + matmul

2. Per-Layer Activation Memory

Detailed Breakdown for One Transformer Layer

With hidden dim hh, sequence length ss, batch size bb, attention heads aa, FFN dim dffd_{ff}, all in BF16 (2 bytes per element unless noted):

TensorShapeBytes70B example
Self-Attention
LayerNorm 1 inputb×s×hb \times s \times h2bsh2bsh67 MB
QKV projection inputb×s×hb \times s \times h2bsh2bsh67 MB
Q, K, V tensors3×b×s×h3 \times b \times s \times h6bsh6bsh201 MB
Attention weights (softmax output)b×a×s×sb \times a \times s \times s2bas22bas^22,147 MB
Attention dropout maskb×a×s×sb \times a \times s \times sbas2bas^2 (1 byte/elem)1,074 MB
Output projection inputb×s×hb \times s \times h2bsh2bsh67 MB
FFN
LayerNorm 2 inputb×s×hb \times s \times h2bsh2bsh67 MB
FFN gate+up inputb×s×hb \times s \times h2bsh2bsh67 MB
Gate output (for SwiGLU backward)b×s×dffb \times s \times d_{ff}2bs⋅dff2bs \cdot d_{ff}235 MB
Up projection outputb×s×dffb \times s \times d_{ff}2bs⋅dff2bs \cdot d_{ff}235 MB
Down projection inputb×s×dffb \times s \times d_{ff}2bs⋅dff2bs \cdot d_{ff}235 MB
Per-layer total~4.5 GB

70B: b=1b=1, s=4096s=4096, h=8192h=8192, a=64a=64, dff=28672d_{ff}=28672

Note: The exact tensors saved depend on the autograd implementation. The table above is the standard set for a pre-norm Transformer with SwiGLU. FlashAttention changes this significantly — see below.

Per-Layer Formula

Mact/layer=14⋅bsh+6⋅bs⋅dff⏟linear in s+3⋅bas2⏟quadratic in sM_{\text{act/layer}} = \underbrace{14 \cdot bsh + 6 \cdot bs \cdot d_{ff}}_{\text{linear in } s} + \underbrace{3 \cdot bas^2}_{\text{quadratic in } s}

The first two terms scale linearly with sequence length. The third term — attention weights plus dropout mask — scales quadratically.

The Attention Quadratic Term

The attention scores tensor has shape b×a×s×sb \times a \times s \times s. This quadratic scaling is the dominant memory cost for long sequences:

Sequence lengthAttention + mask per layer (64 heads)80 layers
2,0480.8 GB64 GB
4,0963.2 GB258 GB
8,19212.9 GB1,030 GB
32,768206 GB16,500 GB
131,0723,300 GB264,000 GB

This is why long-context training is impossible without FlashAttention — attention activations alone would exceed entire cluster memory.

FlashAttention eliminates the O(s2)O(s^2) activation storage by recomputing attention during backward. See Flash Attention.


3. Total Activation Memory

General Formula

Mactivations=LPP×(14⋅bsh+6⋅bs⋅dff+3⋅bas2)M_{\text{activations}} = \frac{L}{\text{PP}} \times \left( 14 \cdot bsh + 6 \cdot bs \cdot d_{ff} + 3 \cdot bas^2 \right)

With FlashAttention, the 3bas23bas^2 term drops to approximately O(bsh)O(bsh) (only Q, K, V and small row-max/sum statistics are saved instead of the full s×ss \times s matrix).

Practical Numbers (with FlashAttention, no checkpointing)

Modelhhdffd_{ff}LayersPer-layer (b=1, s=4K)Total
7B (Llama-3.1)4,09614,33632~0.6 GB~19 GB
13B5,12013,82440~0.8 GB~33 GB
70B (Llama-3.1)8,19228,67280~1.2 GB~99 GB

Still large. 99 GB for 70B with FlashAttention and batch=1 — this is why activation checkpointing is essential at scale.

Without FlashAttention (Standard Attention)

ModelPer-layer (b=1, s=4K)TotalRatio vs FlashAttention
7B~1.4 GB~46 GB2.4×
70B~4.5 GB~357 GB3.6×

4. Reducing Activation Memory

Strategy 1: Activation Checkpointing (Recomputation)

Activation Checkpointing

Instead of saving all intermediate tensors, save only the input to each layer and recompute everything during backward:

ApproachSaved per layerMemoryExtra compute
No checkpointingAll tensorsL×4.5L \times 4.5 GB (70B, standard)0%
Full checkpointingLayer input only (2bsh2bsh)L×67L \times 67 MB (70B)~33%
Selective checkpointingCheap tensors only~40-60% of full~10-15%

Full checkpointing for 70B: 80×67 MB=5.480 \times 67\text{ MB} = 5.4 GB — down from 357 GB (standard) or 99 GB (FlashAttention). A 66× or 18× reduction at the cost of 33% extra compute.

from torch.utils.checkpoint import checkpoint

class TransformerLayer(nn.Module):
    def forward(self, x):
        # Checkpoint this layer — only input x is saved
        return checkpoint(self._forward, x, use_reentrant=False)
    
    def _forward(self, x):
        # Everything here is recomputed during backward
        h = self.attention(self.norm1(x)) + x
        return self.ffn(self.norm2(h)) + h

Strategy 2: FlashAttention

Eliminates the O(s2)O(s^2) attention activation:

Standard attentionFlashAttention
Saved for backwardFull s×ss \times s attention matrix + dropout maskOnly Q, K, V + row-max/sum stats
Memory per layer (70B, s=4K)3.2 GB (attention only)~0.2 GB (Q,K,V stats)
ImpactDominant cost at long sequencesRemoves the quadratic term

For details on how FlashAttention achieves this, see FlashAttention v1 and v2.

Strategy 3: Sequence Parallelism

Split the sequence dimension across TP ranks for LayerNorm and Dropout regions:

Mact,SP=Mact/SP degreeM_{\text{act,SP}} = M_{\text{act}} / \text{SP degree}

Each TP rank handles s/TPs / \text{TP} tokens for non-attention operations. Combined with TP, this reduces activation memory proportionally.

See Sequence Parallelism for details.

Strategy 4: Reduce Batch Size + Gradient Accumulation

Activation memory scales linearly with micro-batch size:

Mact∝bμM_{\text{act}} \propto b_\mu

Use micro-batch bμ=1b_\mu = 1 with KK gradient accumulation steps to achieve effective batch b=bμ×Kb = b_\mu \times K. Same training semantics, but K×K\times less activation memory.


5. Activation Memory Budget in Practice

For 70B, TP=8, FSDP, FlashAttention enabled:

ConfigParametersOptimizerActivationsTotal per GPU
No checkpointing, b=117.5 GB13.1 GB~12 GB~46 GB
Full checkpointing, b=117.5 GB13.1 GB~0.7 GB~34 GB
Full checkpointing, b=417.5 GB13.1 GB~2.7 GB~36 GB
Selective checkpointing, b=217.5 GB13.1 GB~5 GB~39 GB

Activation values are approximate — TP=8 reduces some activations (FFN) but not all (LayerNorm is replicated without SP).

Checkpointing buys you either more batch size or more sequence length within the same GPU memory.


Self-Check

  • Name the tensors saved for backward in a Transformer layer and why each is needed
  • Calculate per-layer activation memory for a given architecture (with and without FlashAttention)
  • Explain the O(s2)O(s^2) attention activation problem and how FlashAttention solves it
  • Calculate activation memory with full checkpointing vs none
  • Determine max batch size given a fixed memory budget after accounting for activations
  • Combine checkpointing + FlashAttention + sequence parallelism for a complete activation strategy

References