Backward Pass Implementation
PremiumImplement Flash Attention gradient computation, achieving memory-efficient training through recomputation.
Get code accessIn the previous chapters, we implemented a complete Flash Attention forward pass, supporting arbitrary sequence lengths, causal masking, and GQA. But this is not enough: to use Flash Attention in training, we need to implement the backward pass to compute gradients.
This chapter explores how to compute , , and while preserving IO efficiency.
Why Do We Need a Custom Backward Pass?
Limitations of PyTorch Autograd
PyTorch's autograd can automatically generate backward code for most operations, but for a fused kernel like Flash Attention, automatic differentiation runs into problems:
# Standard attention forward pass
def standard_attention(Q, K, V):
S = Q @ K.T / sqrt(d) # (1) compute scores
P = softmax(S, dim=-1) # (2) softmax
O = P @ V # (3) weighted sum
return OAutograd's behavior:
- PyTorch saves the intermediate results and (the attention matrix)
- It uses these intermediates to compute gradients during the backward pass
- Memory cost: to store the attention matrix
But the core advantage of Flash Attention is precisely that it does not materialize the attention matrix!
If we rely on automatic differentiation, we would:
- Forward pass: do not save the attention matrix, memory ✅
- Backward pass: need the attention matrix, forced to recompute it, losing the advantage ❌
The Recomputation Strategy
Flash Attention adopts a clever tradeoff: recomputation.
Core idea:
- During the forward pass: save only a small number of intermediate statistics ( and )
- During the backward pass: use these statistics to recompute the attention scores, rather than loading them from HBM
Traditional approach (materialization):
Forward: compute S, P → save to HBM (O(N²) memory)
Backward: read S, P from HBM → compute gradients
Flash Attention (recomputation):
Forward: compute S, P → save only L, M (O(N) memory)
Backward: recompute S, P → compute gradientsTradeoff analysis:
- ✅ Memory savings:
- ⚠️ Extra computation: need to recompute attention (about 1.5x FLOPS)
- ✅ IO efficiency: still faster than the standard implementation, because it avoids HBM round trips
Why is recomputation still faster?
Although it increases FLOPS, modern GPUs are IO-bound rather than compute-bound. The FLOPS cost of recomputing attention is smaller than the IO cost of loading the matrix from HBM.
This is why Flash Attention can preserve its performance advantage even in the backward pass.
Log in to continue reading
This is premium content. Please log in to access the full article.
CookLLM Docs