Advanced

FlashAttention & IO-awareness

FlashAttention computes exact attention in tiles sized to on-chip memory, which is what makes Qwen3.8-27B's 262,144-token context physically possible.

Updated

01 · Concept

Concept

Qwen3.8-27B accepts a native context of 262,144 tokens, and 16 of its 64 layers run full softmax attention over that entire span. Feed the model a maximal prompt and each of those layers must, in principle, compare every query with every key. The attention formula is one line; the question is whether the intermediate objects it implies can physically exist.

Run the arithmetic. With N=262,144=218N = 262{,}144 = 2^{18}, the score matrix QKQK^\top has 218×218=2366.9×10102^{18} \times 2^{18} = 2^{36} \approx 6.9 \times 10^{10} entries per head. At two bytes each in bf16, that is 2372^{37} bytes, or 128 GiB, for one head of one layer. Qwen3.8-27B has 24 query heads per full-attention layer, so materializing one layer’s scores would take about 3 TiB, and its 16 full-attention layers together roughly 48 TiB — written to high-bandwidth memory (HBM), read back for softmax, written again as probabilities, and read once more to multiply VV. An 80 GB-class accelerator cannot hold even a single head’s matrix. Naive attention at this context length is not slow; it is impossible without changing the memory plan.

Accelerators have a memory hierarchy: a small pool of on-chip SRAM measured in tens of megabytes that is very fast, and HBM that is orders of magnitude larger but far slower to reach. Arithmetic units idle while tensors travel between the two. IO-awareness means designing the algorithm around bytes moved through this hierarchy rather than only counting floating-point operations. FlashAttention’s observation is that attention can be computed in tiles that fit SRAM, so the score matrix never needs to exist as a whole.

Split queries into row blocks and keys and values into column blocks, and size the tiles to the head dimension. Qwen’s full-attention heads use head dimension 256, so a 128-row key tile occupies 128×256×2=65,536128 \times 256 \times 2 = 65{,}536 bytes, 64 KiB, and its value twin another 64 KiB. That is twice the footprint of the 128-dimensional heads many early kernels were tuned for, which forces smaller row blocks or more passes within the same SRAM budget — and it means kernel support for d=256d = 256 must be verified for the exact library version, not assumed from an API flag.

The obstacle to tiling is softmax: normalizing a row of scores appears to require seeing the whole row at once. The classic wrong turn is to softmax each tile locally and concatenate the results. Try it on one query row whose scores arrive as a block [1.0, 3.0][1.0,\ 3.0] followed by a block [5.0][5.0]. A local softmax of the first block gives the score 3.0 a weight of e3/(e1+e3)0.881e^{3}/(e^{1}+e^{3}) \approx 0.881 — but the true weight, once the dominant 5.0 arrives, is only about 0.117. Local normalization bakes in a denominator that later tiles invalidate.

Online softmax corrects this by carrying two running statistics per row: the maximum mm and the exponential sum \ell. After the first block, m1=3m_1 = 3 and 1=e13+e33=0.135+1=1.135\ell_1 = e^{1-3} + e^{3-3} = 0.135 + 1 = 1.135. The second block raises the maximum to mnew=5m_{new} = 5, so the old sum is rescaled by em1mnew=e2e^{m_1 - m_{new}} = e^{-2}: 1.135×0.135=0.154\ell \leftarrow 1.135 \times 0.135 = 0.154, then the new term adds e55=1e^{5-5} = 1, giving =1.154\ell = 1.154. Computing directly, e4+e2+e0=0.018+0.135+1=1.154e^{-4} + e^{-2} + e^{0} = 0.018 + 0.135 + 1 = 1.154 — identical. Partial output accumulators are rescaled by the same factor, so after the last tile the division by \ell yields exact attention. The operation order changes, so the last floating-point bits may differ, but nothing is approximated, sparsified, or truncated.

Recomputation extends the same logic to training: the backward pass can recompute local scores inside tiles instead of reading a stored N2N^2 matrix, trading cheap arithmetic for expensive HBM traffic.

The benefit is phase-specific. Prefill processes many query rows and is exactly the regime the tiling targets. Single-token decode has one query row; as lesson 7.3 established, it is dominated by reading weights and the KV cache (lesson 7.2 derives Qwen’s per-token cache cost), and specialized decode kernels are cousins rather than beneficiaries of the same headline speedup.

The durable lesson outlives one kernel. When arithmetic is cheap and memory movement is not, algorithm design must count bytes through the hierarchy. FlashAttention is exact attention rearranged around that physical reality — and it is the reason a quarter-million-token context is a product feature rather than a thought experiment.

02 · Analogy

Analogy

A baker must combine every item in two long ingredient lists, but the worktable holds only a few bowls. The naive method writes every pairwise mixture onto trays, carries all trays to a distant warehouse, then retrieves them for normalization. An IO-aware baker works in tiles that fit the table, maintains running totals, and sends only the final loaves out. FlashAttention similarly recomputes cheap local quantities to avoid transporting a gigantic attention matrix.

03 · Teach it back

Teach it back

Explain why materializing attention scores at Qwen3.8-27B's native context is infeasible, and how tiled online softmax computes the same result without storing the score matrix.

Minimum: 80 characters and 15 words. Your writing stays only in this browser.

Waiting for your explanation.

Compare with a model answer

At 262,144 tokens the score matrix has two to the thirty-sixth entries per head, about 128 GiB in bf16 — more than an entire accelerator's memory for a single head of a single layer, before counting Qwen's 24 query heads and 16 full-attention layers. FlashAttention loads query and key/value tiles into fast on-chip SRAM, computes local scores there, and maintains a running row maximum and normalization sum, rescaling earlier partial outputs by the exponential of the old-minus-new maximum whenever a later tile raises it. The final output equals standard softmax attention up to floating-point reordering; only the tile statistics ever exist, so memory traffic scales with the inputs and outputs rather than with the squared sequence length.

04 · Check your understanding

Check your understanding

01What is the main object FlashAttention avoids materializing in device memory?
Answer and explanation

The full attention score/probability matrix — Tiling streams through score blocks and keeps only the running maximum and normalization statistics needed to combine them exactly.

02Using lesson 7.3, why does FlashAttention's headline win apply to prefill more than to single-token decode?
Answer and explanation

Prefill processes many query rows at once and is dominated by score traffic, while decode has one query row and is dominated by reading weights and KV cache — Prefill is the phase with a large query block and a potentially enormous score matrix; decode's single row makes weight and KV-cache bandwidth the binding constraint.

Complete the teach-back and answer the quiz correctly to finish this lesson.

◎ · Evidence marker

Sources

  1. Tri Dao et al. (2022). FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness.
  2. Qwen Team (2026). Qwen3.8-27B Model Card.