S = QK^T (N × N)
P = softmax(S) (N × N)
O = PV (N × d)
In standard attention, you have to initialize an matrix. For N=8K, that’d be 67M entires that you have to write to GPU memory, read back for softmax, and then read again for the PV multiply. Each of those would require a full trip to HBM. So the self-attention operation here is memory-bandwith bound.
FlashAttention solves this by never materializing the full matrix and instead does:
- Tiling: Splits Q,K,V into blocks that fit in SRAM
- Fusing the matmul→softmax→matmul pipeline into one GPU kernel so that the intermediate results stay in SRAM the whole time
- Online Softmax: compute softmax incrementally block by clock, without seeing the whole erow at once.
Online Softmax
Softmax equation:
To calculate this you would need the global max of the vector x, and the sum of the exponentials of the vector x. FlashAttention instead processes blocks of K/V one at a time, and calculates the max and sum of the block.
It keeps two running values per query row:
- : The maximum value of the current block
- : The sum of the exponentials of the current block
When a new block arrives with a new local max, everything computed so far is rescaled and the new block’s contribution gets folded in.