Replay in reverse the 7-week path of an engineer who walked from vector_add to Flash Attention — and you start to see why the modern LLM evolved into exactly this shape, and how hardware and model co-evolved.
vector_add to Flash Attention. And one question kept circling. Why did GPGPU evolve into exactly this shape?Inside a GPU, adding one number is 1 ns. Fetching it from HBM is 100 ns. This single ratio governs every decision in GPU programming.
The vector_add kernel: 3.5 ms. The PCIe copy of the same data alone: 60 ms. The kernel is 17× shorter. Without pinned memory, end-to-end runs 5.6× slower.
If you have tens of thousands of threads, doing atomic adds together should be fast, right? No. 100× slower. That's why GPUs ship weird instructions like __shfl_down_sync.
atomicAdd on the same address. Guess how many ms?__shfl_down_sync didn't exist in 1.0. People used tree reductions so much we added it six years later. Now it's standard.Remove five of them and you get 29% back. In small kernels, a single sync is a third of runtime. That's why "last warp only shuffles, no sync" became an idiom.
Why Lesson 4 was the longest. Tiling and register blocking are software techniques that raise arithmetic intensity; the final breakthrough past the 8-TFLOPS ceiling came from a new unit called the Tensor Core.
"Bigger tiles raise AI, so they're faster" is only half true. You also need enough blocks to feed all the SMs. That's why decode kernels and prefill kernels look different.
# merging two partial softmax statistics
new_max = max(m1, m2)
new_sum = s1 * exp(m1 − new_max)
+ s2 * exp(m2 − new_max)
It never physically creates the N×N intermediate. All five earlier techniques — coalesced loads, HBM intuition, warp reduce, tiled matmul, online softmax — fit inside one kernel.
torch.ops.*.torch.ops.*.Placed the whole AttentionBlock inside torch.compile(..., fullgraph=True). Graph breaks: 0. eager vs compiled err = 0.00e+00 — bit-for-bit identical.
Running the engineer's 7-week path backward, you can see that Flash Attention was inevitable.
All numbers come from cudatraining lesson 1–9 handoff docs, measured on T4 sm_75 / L4 sm_89.