FlashAttention

How IO-awareness and tiling make exact attention fast and memory-efficient.

This article explains the paper FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness by Dao et al. (2022), which introduced an algorithm that makes transformer attention 2-4x faster without any approximation.

One idea runs through this whole article: on a modern GPU, the memory hierarchy is the algorithm. FlashAttention computes the exact same softmax attention as the textbook version. It is faster only because it moves less data. Keep that framing in mind and every design choice below follows from it.

The Problem: Attention is Memory-Bound

Standard self-attention scales quadratically with sequence length. For a sequence of length $N$, we compute and store an $N \times N$ attention matrix.

$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right) V$$

Read this as: score every query against every key ($QK^T$), squash the scores into a probability distribution per row (softmax), then take a weighted average of the value vectors. The $N \times N$ score matrix in the middle is the expensive object — it grows with the square of the sequence.

Here is the twist. The bottleneck is not the arithmetic — it is the memory access. An NVIDIA A100 can do 312 TFLOPS of matrix math, but its main memory delivers data far slower than the tensor cores can consume it. So the chip spends most of its time waiting for numbers to arrive, not multiplying them.

Standard attention is IO-bound, not compute-bound. We spend more wall-clock time shuttling the score matrix between memory tiers than doing the actual multiplications. Cutting data movement — not FLOPs — is what makes it fast.

GPU Memory Hierarchy

To understand FlashAttention, we need to understand how GPU memory works.

HBM
40-80 GB
Main memory
(Q, K, V, O)
1.5 TB/s bottleneck
SRAM
~20 MB
On-chip cache
19 TB/s 10× faster
Compute
312 TFLOPS
Tensor cores
GPU memory hierarchy on A100. Data must flow through SRAM to reach compute. The HBM→SRAM transfer is the bottleneck—not the computation itself.

GPUs have two main memory types:

HBM (High Bandwidth Memory)

SRAM (On-chip Cache)

The key numbers: SRAM is ~10x faster but ~1000x smaller than HBM.

The size-speed trade-off is the whole game. SRAM is fast enough to keep the tensor cores fed, but at ~20 MB it cannot hold a large attention matrix. HBM is big enough for anything, but at 1.5 TB/s it starves the cores. FlashAttention's job is to do as much work as possible while the data is still in SRAM, and touch HBM as rarely as possible.

To make the gap concrete: a 4K-token attention matrix in fp16 is $4096 \times 4096 \times 2 \approx 34$ MB per head. Writing it to HBM and reading it back is ~68 MB of traffic at 1.5 TB/s ≈ 45 microseconds of pure data movement — before a single useful multiply. Multiply that by many heads and layers and the copies, not the math, set the runtime.

Standard Attention: The Memory Problem

Let’s trace what standard attention does:

1
Load Q, K from HBM HBM → SRAM
2
Compute S = QKT Compute
3
Write S to HBM (N×N matrix!) SRAM → HBM
4
Read S from HBM HBM → SRAM
5
Compute P = softmax(S) Compute
6
Write P to HBM (N×N matrix!) SRAM → HBM
7
Read P, V from HBM HBM → SRAM
8
Compute O = PV Compute

The red steps are the waste: we write the $N \times N$ matrix to HBM and read it straight back, twice. The score matrix never needed to leave the chip — the standard implementation evicts it only because it computes softmax in separate passes. For long sequences, these round-trips dominate runtime.

$$\text{HBM accesses} = \Theta(Nd + N^2)$$

The $N^2$ term is the killer. Loading $Q, K, V$ costs $\Theta(Nd)$, but materializing and re-reading the score matrix costs $\Theta(N^2)$ — and for long sequences $N^2 \gg Nd$. Every byte of that term is optional.

FlashAttention: The Solution

FlashAttention’s key idea: never materialize the full attention matrix. Instead, compute attention in tiles that fit in SRAM.

FlashAttention tiling diagram
FlashAttention tiling and softmax rescaling. By operating on blocks and using online softmax to rescale partial results, we avoid writing the large N×N attention matrix to HBM. Image credit: Stanford CRFM
Interactive: Standard attention materializes the full N×N matrix in HBM (red). FlashAttention processes blocks in SRAM (green), discarding each after use.

The Tiling Strategy

Instead of computing the full attention matrix at once:

  1. Divide Q, K, V into blocks that fit in SRAM
  2. Compute attention for each block pair
  3. Accumulate results with proper normalization

But there’s a catch: softmax isn’t block-decomposable. The denominator is a sum over the whole row, so you seem to need every key before you can normalize any of them. How do you normalize a row you’ve only seen part of?

The Online Softmax Trick

This is the algorithmic insight that makes tiling possible.

Standard softmax needs two passes over each row:

  1. Find the maximum (subtracted for numerical stability, so $e^{x}$ never overflows).
  2. Compute every $e^{x_i - \max}$ and sum them into the denominator.

Online softmax fuses both into a single pass by carrying two running numbers per row — the max seen so far ($m$) and the running denominator ($\ell$) — and correcting them each time a new block arrives.

Online Softmax Update Rule
$$m^{(new)} = \max(m^{(old)}, \tilde{m})$$ $$\ell^{(new)} = e^{m^{(old)} - m^{(new)}} \ell^{(old)} + e^{\tilde{m} - m^{(new)}} \tilde{\ell}$$ $$O^{(new)} = \frac{\ell^{(old)} e^{m^{(old)} - m^{(new)}} O^{(old)} + e^{\tilde{m} - m^{(new)}} \tilde{P}V}{\ell^{(new)}}$$
$m$: running maximum for numerical stability
$\ell$: running sum of exponentials (softmax denominator)
$O$: running output, rescaled as we see more blocks

Line by line: the first equation just updates the running max. The second re-expresses the old denominator in terms of the new max (the $e^{m^{old}-m^{new}}$ factor shrinks the old sum to match the new, larger baseline) and adds the new block’s contribution. The third does the same correction to the running output before folding in the new block’s $\tilde{P}V$.

The trick is the correction factor $e^{m^{old}-m^{new}}$. When a later block reveals a larger maximum, we retroactively rescale everything computed so far — as if we had known the true max all along. Because the fix-up is exact, the block-by-block result equals the single-shot softmax to the last bit.

Concrete example. Suppose block 1 gives scores with max 2.0, and we accumulate a partial sum $\ell = 5.0$. Block 2 then shows a score of 4.0. Instead of restarting, we multiply the old sum by $e^{2.0 - 4.0} = e^{-2} \approx 0.135$, getting $0.68$, then add block 2's exponentials on the new baseline of 4.0. The running output is scaled by the same factor. No pass over block 1 is repeated.

The Algorithm

FlashAttention algorithm loop structure
FlashAttention loop structure. The outer loop (orange) iterates over K,V blocks, loading them to SRAM. The inner loop (blue) iterates over Q blocks, computing attention in SRAM and writing output to HBM.
Interactive: Step through the algorithm to see data flow between HBM and SRAM. Press Play or use Step to advance.

Here’s the FlashAttention forward pass:

FlashAttention Forward Pass

Input: Matrices $Q, K, V \in \mathbb{R}^{N \times d}$ in HBM, block sizes $B_r, B_c$

Output: $O \in \mathbb{R}^{N \times d}$

  1. Divide $Q$ into $T_r = \lceil N/B_r \rceil$ blocks, $K, V$ into $T_c = \lceil N/B_c \rceil$ blocks

  2. Initialize $O = 0$, $\ell = 0$, $m = -\infty$ in HBM

  3. For $j = 1, \ldots, T_c$ (outer loop over K, V):

    • Load $K_j, V_j$ from HBM to SRAM
  4. For $i = 1, \ldots, T_r$ (inner loop over Q):

    • Load $Q_i, O_i, \ell_i, m_i$ from HBM to SRAM
    • On chip, compute $S_{ij} = Q_i K_j^T \in \mathbb{R}^{B_r \times B_c}$
    • On chip, compute:
      • $\tilde{m}_{ij} = \text{rowmax}(S_{ij}) \in \mathbb{R}^{B_r}$
      • $\tilde{P}_{ij} = \exp(S_{ij} - \tilde{m}_{ij}) \in \mathbb{R}^{B_r \times B_c}$
      • $\tilde{\ell}_{ij} = \text{rowsum}(\tilde{P}_{ij}) \in \mathbb{R}^{B_r}$
    • Update $m_i^{\text{new}}, \ell_i^{\text{new}}, O_i$ using online softmax
    • Write $O_i, \ell_i, m_i$ to HBM
  5. Return $O$

The critical property: the $N \times N$ attention matrix $S$ is never fully materialized in HBM. Each block $S_{ij}$ exists only briefly in SRAM.

$$\text{HBM accesses} = O\left(\frac{N^2 d^2}{M}\right)$$

Where $M$ is SRAM size. The $N^2$ term from standard attention is gone — replaced by a term that shrinks as SRAM grows. Bigger fast cache means bigger tiles, means fewer trips to HBM. For typical values ($d = 64$, $M = 100$KB), this is 5-20x fewer HBM accesses, and the exact same output.

Why It Works: Arithmetic Intensity

Arithmetic intensity = FLOPs / bytes moved

Standard attention has low arithmetic intensity: we move lots of data for relatively little compute. FlashAttention increases arithmetic intensity by reusing data in SRAM.

Method HBM Reads/Writes Arithmetic Intensity
Standard Attention $\Theta(Nd + N^2)$ Low — cores starve
FlashAttention $O(N^2d^2/M)$ High — cores stay fed

Results

FlashAttention achieves significant speedups across different models and sequence lengths:

FlashAttention-2 A100 benchmark
FlashAttention-2 benchmark on A100 GPU. Forward and backward pass speedup compared to baseline attention across different sequence lengths and head dimensions. Image credit: Stanford CRFM
Model Sequence Length Speedup
BERT-large 512 15% faster end-to-end
GPT-2 1K 3× faster
Long-range arena 1K-4K 2.4× faster

More importantly, FlashAttention enables much longer sequences. Because memory now grows linearly with $N$ instead of quadratically, sequences that once ran out of memory become feasible. The paper shows the first Transformer to reach better-than-random accuracy on Path-X (16K tokens) and Path-256 (64K tokens). This is the through-line paying off: respecting the memory hierarchy did not just speed up attention — it changed what lengths are trainable at all.

Memory savings in concrete terms. For a 2K sequence with 16 heads and head dimension 64, standard attention needs ~1GB for the attention matrix. FlashAttention needs only the block currently in SRAM (~MB) — a reduction of ~1000×.

What does FlashAttention give up? It trades extra FLOPs for fewer memory accesses. The backward pass recomputes attention blocks on the fly rather than reading a stored matrix, so total arithmetic goes up — and it still wins, because on a memory-bound workload FLOPs are nearly free. The real costs are engineering ones: a hand-tuned fused kernel per hardware generation, and none of the composability of stock framework ops.

Extensions: FlashAttention-2 and 3

The original algorithm fixed the memory problem. The follow-ups chase the remaining hardware inefficiencies — the same through-line, one hardware generation at a time.

FlashAttention-2 (2023) improves parallelism:

FlashAttention-2 work partitioning
Work partitioning improvement in FlashAttention-2. The original "sliced-K" approach (left) requires synchronization between warps. FlashAttention-2 (right) partitions work to reduce synchronization overhead. Image credit: Stanford CRFM

FlashAttention-3 (2024) leverages new hardware features:

Why the lineage matters for long context. Every modern long-context model — 128K tokens and beyond — depends on this family. Without IO-aware attention, a 128K-token attention matrix would need hundreds of gigabytes of HBM traffic per layer. FlashAttention is the reason "long context" is an engineering feature and not a research fantasy. It ships inside PyTorch (scaled_dot_product_attention), vLLM, and essentially every production serving stack.

Key Takeaways

1
IO-awareness matters. Modern GPUs are compute-rich but memory-bandwidth-limited. Algorithm design must account for the memory hierarchy.
2
Tiling enables efficiency. By processing data in blocks that fit in fast cache, we can dramatically reduce slow memory access.
3
Online algorithms unlock parallelism. The online softmax trick makes softmax block-decomposable, enabling the tiled computation.
4
Exact beats approximate. FlashAttention is faster than approximate attention methods while computing the exact same result.

References

  1. Dao, T., Fu, D. Y., Ermon, S., Rudra, A., & Ré, C. (2022). FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. NeurIPS 2022.

  2. Dao, T. (2023). FlashAttention-2: Faster Attention with Better Parallelism and Work Partitioning.

  3. Shah, J., Bikshandi, G., Zhang, Y., Thakkar, V., Ramani, P., & Dao, T. (2024). FlashAttention-3: Fast and Accurate Attention with Asynchrony and Low-precision.

  4. Milakov, M., & Gimelshein, N. (2018). Online Normalizer Calculation for Softmax. arXiv:1805.02867.