The Nightly Build.
The Paper

The Attention Matrix You Never Write Down

Attention was never compute-bound. FlashAttention makes it exact and fast by never writing the N-by-N score matrix to GPU memory, keeping the whole computation on-chip through tiling and a running-softmax recurrence.

FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness

Tri Dao, Daniel Y. Fu, Stefano Ermon, Atri Rudra, Christopher Ré · arXiv:2205.14135 (NeurIPS 2022) · 2022

Read the paper
Transformers are slow and memory-hungry on long sequences, since the time and memory complexity of self-attention are quadratic in sequence length. Approximate attention methods have attempted to address this problem by trading off model quality to reduce the compute complexity, but often do not achieve wall-clock speedup. We argue that a missing principle is making attention algorithms IO-aware -- accounting for reads and writes between levels of GPU memory. We propose FlashAttention, an IO-aware exact attention algorithm that uses tiling to reduce the number of memory reads/writes between GPU high bandwidth memory (HBM) and GPU on-chip SRAM. We analyze the IO complexity of FlashAttention, showing that it requires fewer HBM accesses than standard attention, and is optimal for a range of SRAM sizes. We also extend FlashAttention to block-sparse attention, yielding an approximate attention algorithm that is faster than any existing approximate attention method. FlashAttention trains Transformers faster than existing baselines: 15% end-to-end wall-clock speedup on BERT-large (seq. length 512) compared to the MLPerf 1.1 training speed record, 3× speedup on GPT-2 (seq. length 1K), and 2.4× speedup on long-range arena (seq. length 1K-4K). FlashAttention and block-sparse FlashAttention enable longer context in Transformers, yielding higher quality models (0.7 better perplexity on GPT-2 and 6.4 points of lift on long-document classification) and entirely new capabilities: the first Transformers to achieve better-than-chance performance on the Path-X challenge (seq. length 16K, 61.4% accuracy) and Path-256 (seq. length 64K, 63.1% accuracy).1

Before you read

The paper assumes you can read pseudocode for a GPU kernel and that you hold two facts about hardware that machine-learning courses rarely teach. First, a modern accelerator has a memory hierarchy: a large, slow pool of high-bandwidth memory (HBM, the number on the spec sheet) and a tiny, fast scratchpad of on-chip SRAM local to each compute unit. Second, an operation's wall-clock time is often set not by how many arithmetic operations it does but by how many bytes it moves between those two pools. If both are familiar, the paper's contribution will land the first time. If not, the next section builds them from the ground up before the algorithm needs them.

The bottleneck was never the multiply

Self-attention scales quadratically in sequence length: for N tokens and head dimension d, the scores S = QK⊤ form an N×N matrix, and both the arithmetic and the memory grow as N2. For years the field read that quadratic as a compute problem and answered it with approximations: sparse patterns, low-rank factorizations, kernelized attention, each cutting the number of floating-point operations. FlashAttention starts from a different reading of the same fact. On current hardware the quadratic matrix is expensive mostly because it is written to and read from slow memory, not because the multiplications are hard. The fix is therefore not to do less arithmetic but to move fewer bytes, and to do it without changing the answer.1

The paper names the missing design principle directly, and it is the sentence the rest of the work exists to cash out.1

We argue that a missing principle is making attention algorithms IO-aware -- carefully accounting for reads and writes to different levels of fast and slow memory.1
Introduction States the thesis: the target of optimization is memory traffic between HBM and SRAM, not FLOP count. It claims exactness is kept, and does not claim a new attention formula.
IO-aware An algorithm designed around the cost of reads and writes between levels of the memory hierarchy, counting bytes moved rather than arithmetic performed.

Why the score matrix is the tax

Start with the hardware asymmetry the whole idea turns on. On an A100, the paper's reference GPU, arithmetic throughput has outrun memory bandwidth by a wide margin, and most Transformer operations feel that gap.1

On modern GPUs, compute speed has out-paced memory speed, and most operations in Transformers are bottlenecked by memory accesses.1
Introduction The empirical premise. It asserts a bottleneck for the common case, not that every operation is memory-bound; matrix multiplies with large inner dimensions remain compute-bound.

The numbers make the asymmetry concrete. The A100's high-bandwidth memory delivers roughly 1.5 to 2.0 terabytes per second, while the on-chip SRAM local to each of its 108 compute units runs at an estimated 19 terabytes per second, about an order of magnitude faster. That SRAM is also small: 192 kilobytes per unit.1 The same asymmetry drives every well-tuned GPU kernel; the standard matrix-multiply playbook is to stage small tiles of the operands into SRAM and reuse them there before touching slow memory again.2

1.5–2 TB/sA100 HBM bandwidth
~19 TB/sOn-chip SRAM bandwidth
192 KBSRAM per compute unit

Now trace what a textbook attention kernel does with that hierarchy. It computes the full scores S = QK⊤ and writes all N2 of them to HBM. It reads them back to apply the softmax row by row, producing probabilities P, and writes P back. It reads P again to multiply by V. The arithmetic is a pair of matrix multiplies and an elementwise exponential; the expensive part is the round trips of an N-by-N object across the slow bus. When d is a hundred or so and N is in the thousands, that traffic, not the multiplies, sets the clock. This is the same lesson practitioners learn when they profile a model and find it starved for bandwidth rather than compute: fusing operations to avoid materializing intermediates is the single highest-leverage move.3 FlashAttention is that move carried out for the attention block, all the way.1

The obstacle: softmax refuses to be split

The obvious fix is fusion: never write S or P to HBM at all. Load a block of queries and a block of keys into SRAM, compute their scores there, turn them into the corresponding slice of output, and keep only the small output block. Matrix multiply tiles this way without trouble. Softmax does not, and understanding exactly why is the crux of the paper.

Softmax over a row of scores is not a local operation. To normalize even the first entry you need the sum of exponentials over the entire row, and to compute those exponentials safely you first subtract the row's maximum so that ex never overflows. Both the maximum and the sum are reductions over all N keys. If you only ever hold one block of keys in SRAM at a time, you cannot know the global maximum or the global denominator when you process the first block. The naive tiled kernel would have to make a full pass to find the maximum, another to accumulate the denominator, and a third to form the output, which puts the N-by-N scores back on the slow bus and defeats the purpose. The quadratic memory traffic the paper wants to eliminate is, at first glance, forced by softmax's global dependency.1

The running-statistics trick

The escape is a recurrence that computes softmax in a single streaming pass, correcting itself as it goes. It predates FlashAttention: NVIDIA researchers introduced the online-softmax formulation precisely to cut softmax's memory accesses, computing the normalizer while scanning the scores rather than in a separate pass.4 FlashAttention's contribution is to fold the value-weighted sum into the same recurrence, so the output itself is produced online.1

Here is the mechanism, worth re-deriving once by hand. Process the keys in blocks. Carry three running quantities for each query: the maximum score seen so far m, the running denominator ℓ (a sum of exponentials, all measured relative to the current m), and the running output accumulator o. When a new block arrives, compute its local scores and local maximum, then set the new global maximum m' = max(m, local max). The old running sums were exponentiated against the old, smaller maximum, so they are now too large by exactly a factor of e(m − m'). Multiply both the old ℓ and the old o by that single correction factor, then add the new block's contribution, exponentiated against m'. After the last block, divide o by ℓ. The result is bit-for-bit the same softmax attention you would have computed with the whole row in hand.

  1. Score the block in SRAM

    With a query block and a key block resident on-chip, compute their scores and the block's local maximum. Nothing touches HBM.1

  2. Update the running maximum

    Set m' = max(m, local max). Every quantity you already accumulated was normalized against the old m, so it now carries a known, correctable error.

  3. Rescale, then accumulate

    Multiply the running denominator and the running output by e(m − m'), then add this block's exponentiated scores and its value-weighted sum. The old and new contributions are now on the same footing.

  4. Normalize at the end

    After the final block, divide the accumulated output by the accumulated denominator. Exactness is preserved throughout; no approximation enters.1

The paper states the property that makes this legal in one line, and it is the load-bearing sentence of the method.1

By scaling the output of each block by the right normalization factor before adding them up, we get the correct result at the end.1
Section 3.1 · tiling The exactness claim. The block-wise rescaling is algebraically identical to a single global softmax; it is not an approximation that happens to be close.

Tiling forward, recomputing backward

With the recurrence in hand, the forward pass is a doubly nested loop over blocks. The algorithm splits the queries, keys, and values into blocks sized to fit in SRAM, streams them on-chip, and runs the running-statistics update, writing only the final output and a small per-row normalization statistic back to HBM. The N-by-N score matrix is never materialized in slow memory at all.1

The main idea is that we split the inputs 𝐐,𝐊,𝐕 into blocks, load them from slow HBM to fast SRAM, then compute the attention output with respect to those blocks.1
Section 3.1 The forward algorithm in one sentence. It is a fused kernel: the entire attention block is one pass over on-chip tiles, not three passes over HBM.

The backward pass poses the mirror-image problem. Gradients through attention need the probabilities P, and a conventional implementation would have stashed that N-by-N matrix during the forward pass to reuse it now. FlashAttention refuses to store it, so it does the arithmetic twice instead. Having kept the output and the softmax normalization statistics, it reconstructs the needed blocks of S and P on-chip during the backward pass, trading extra floating-point work for memory it never has to touch.1

We store the softmax normalization factor from the forward pass to quickly recompute attention on-chip in the backward pass, which is faster than the standard approach of reading the intermediate attention matrix from HBM.1
Introduction Recomputation as a deliberate trade. It claims recompute-from-SRAM beats read-from-HBM on wall-clock time; it does not claim fewer total FLOPs.

The recomputation is a form of gradient checkpointing, the technique that trades an extra forward pass for the memory of stored activations.5 Here that trade has a sharper justification than usual. Ordinary checkpointing recomputes to save memory and accepts a speed penalty. Here the recomputation is often faster in wall-clock terms, because the redone arithmetic runs against fast SRAM while the alternative would stall on HBM. The same insight that self-attention need not store its quadratic intermediate appeared in closely related work reducing attention's memory to sublinear in sequence length; FlashAttention pairs that memory argument with an IO-aware kernel that also wins on speed.6

What it buys, and where the analysis bites

The payoff is stated as a theorem about memory traffic, which is the honest currency here rather than a raw speedup on one benchmark.1

Standard attention requires Θ(Nd + N²) HBM accesses, while FlashAttention requires Θ(N²d²M⁻¹) HBM accesses.1
Section 3.2 · Theorem 2 M is the SRAM size. Since d2 is typically much smaller than M, the factor d2/M is well below one, so FlashAttention moves many times fewer bytes than the N2 term of standard attention.

Fewer HBM accesses translate into the wall-clock results, which is the point the approximate-attention literature kept missing: the paper reports a 7.6× speedup on the attention computation itself on GPT-2, and end-to-end, a 15% training speedup on BERT-large against the MLPerf 1.1 record, 3× on GPT-2, and 2.4× on Long Range Arena,1 the benchmark suite built to test efficient Transformers on sequences of a thousand to sixteen thousand tokens.7 Because memory now grows linearly in sequence length rather than quadratically, longer contexts become reachable, and the block-sparse variant is the first attention to clear better-than-chance on the 16K-token Path-X and 64K-token Path-256 tasks.1

Read as a reviewer, the strengths and the caveats are both specific. The result is exact, which is the quiet triumph: unlike the sparse and low-rank methods it displaces, FlashAttention changes the runtime profile without changing the model, so there is no accuracy tax to weigh against the speed. The IO-complexity analysis gives the speedup a principled account instead of leaving it to a benchmark. The costs are equally concrete. The whole argument assumes the head dimension d is small enough that a d-wide block of queries, keys, and values fits in a 192-kilobyte scratchpad; at very large head dimensions the tiling loosens and the advantage narrows. The kernel is hand-written CUDA against a specific memory hierarchy, so its benefit is hardware-shaped, not a free property of the math. And the original release under-uses the GPU's arithmetic units: the follow-up, FlashAttention-2, reworks the work partitioning and parallelism to reach 50–73% of the A100's theoretical peak and roughly double the throughput, evidence that the first version left real performance on the table even as it proved the principle.8

Verdict A load-bearing paper whose contribution is a reframing as much as a kernel: attention's quadratic was a memory problem wearing a compute costume, and treating it as such buys large exact speedups on today's hardware. The specific block sizes and CUDA will date; the IO-aware principle, and the online-softmax recurrence that makes exactness survive tiling, are what to carry forward.1

Read it yourself

A full read adds the two things a reconstruction has to compress: the exact algorithm blocks with their index bookkeeping, and the IO-complexity proof that justifies every design choice.

One thing first-time readers miss: FlashAttention is not an approximation. The word “exact” in the title is the whole argument. Every rival it benchmarks against changes the outputs; this one changes only the order in which the same outputs are computed.

Sources

  1. arXiv · Tri Dao et al., "FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness" (2022)
  2. Simon Boehm · "How to Optimize a CUDA Matmul Kernel for cuBLAS-like Performance: a Worklog"
  3. Horace He · "Making Deep Learning Go Brrrr From First Principles"
  4. arXiv · Maxim Milakov, Natalia Gimelshein, "Online normalizer calculation for softmax" (2018)
  5. arXiv · Tianqi Chen, Bing Xu, Chiyuan Zhang, Carlos Guestrin, "Training Deep Nets with Sublinear Memory Cost" (2016)
  6. arXiv · Markus N. Rabe, Charles Staats, "Self-attention Does Not Need O(n²) Memory" (2021)
  7. arXiv · Yi Tay et al., "Long Range Arena: A Benchmark for Efficient Transformers" (2020)
  8. arXiv · Tri Dao, "FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning" (2023)