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

kernel 2205.14135
attention-kernelio-awarenesstilingmemory-efficientgpu-optimization

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

§1 TL;DR #

通过 tiling + recomputation 将 attention 融合为单个 GPU kernel,避免 $N \times N$ 中间矩阵的 HBM 读写,IO 复杂度从 $\Theta(Nd + N^2)$ 降至最优的 $\Theta(N^2 d^2 / M)$,实现 2–4× 加速和线性内存。

§2 痛点 / 方法 / 结果 #

Q1 痛点 #

标准 attention 实现将 $\mathbf{S} = \mathbf{Q}\mathbf{K}^\top$ 和 $\mathbf{P} = \text{softmax}(\mathbf{S})$ 两个 $N \times N$ 矩阵完整写入 HBM,产生 $O(N^2)$ 内存占用和大量 HBM 读写。在 A100 上,HBM 带宽(1.5–2.0 TB/s)远低于 on-chip SRAM 带宽(~19 TB/s),使 attention 成为 memory-bound 操作。

近似 attention 方法(Reformer、Performer、Linformer 等)降低了 FLOP 复杂度,但未实现 wall-clock 加速,根因是忽略了 IO 开销。

Q2 方法 #

核心原理——IO-Awareness:将 attention 视为 memory-bound 操作,优化目标从 FLOP 减少转向 HBM 读写减少。

技术 1——Tiling(在线 softmax)

将 $\mathbf{Q}, \mathbf{K}, \mathbf{V}$ 分成大小为 $B_r \times d$ 和 $B_c \times d$ 的 block,外层循环遍历 K/V block(加载至 SRAM),内层循环遍历 Q block。关键是 softmax 可以增量计算:

$$m(x) = \max_i x_i, \quad f(x) = [e^{x_1 - m(x)}, \ldots, e^{x_B - m(x)}], \quad \ell(x) = \sum_i f(x)_i$$

对拼接向量 $x = [x^{(1)}, x^{(2)}]$:

$$m(x) = \max(m(x^{(1)}), m(x^{(2)}))$$

$$\ell(x) = e^{m(x^{(1)}) - m(x)} \ell(x^{(1)}) + e^{m(x^{(2)}) - m(x)} \ell(x^{(2)})$$

维护运行统计量 $(m, \ell)$ 即可逐 block 计算 softmax,无需物化完整 $N \times N$ 矩阵。

技术 2——Recomputation(反向传播)

前向传播仅存储 $\mathbf{O}$ 和 softmax 统计量 $(m, \ell)$——$O(N)$ 额外内存。反向传播时从 $\mathbf{Q}, \mathbf{K}, \mathbf{V}$ block 在 SRAM 中重新计算 $\mathbf{S}, \mathbf{P}$。虽然增加 FLOP,但因减少 HBM 读写反而更快。

关键中间量 $D_i = do_i^\top o_i$ 替代了需要 $O(N)$ 向量的 $P_{i:}^\top dP_{i:}$,使反向传播也可 block-wise 进行。

Block-Sparse FlashAttention:在 FlashAttention 基础上增加 block-level mask $\mathbf{M}$,跳过零 block 的计算,IO 复杂度降至 $\Theta(Nd + N^2 d^2 M^{-1} s)$($s$ 为非零 block 比例)。

核心技术壁垒:在保持 exact attention 输出的前提下,将 softmax 的全局归一化分解为可增量更新的局部统计量——这是一个数学非平凡的观察(algebraic aggregation),它使得整个 attention(matmul + softmax + matmul + dropout + mask)可融合为单个 kernel,消除所有中间 HBM 读写。

Q3 结果 #

§3 架构 / 方法图 #

flowchart LR subgraph HBM ["GPU HBM (slow, large)"] Q["Q ∈ ℝ^{N×d}"] K["K ∈ ℝ^{N×d}"] V["V ∈ ℝ^{N×d}"] O["O ∈ ℝ^{N×d}"] stats["ℓ, m ∈ ℝ^N"] end subgraph SRAM ["On-chip SRAM (fast, small ~192KB/SM)"] Qb["Q_i block"] Kb["K_j block"] Vb["V_j block"] Sb["S_ij = Q_i K_j^T"] Pb["P̃_ij = exp(S_ij - m̃)"] Ob["O_i (accumulator)"] end Q -->|"load block i"| Qb K -->|"outer loop: load block j"| Kb V -->|"outer loop: load block j"| Vb Qb --> Sb Kb --> Sb Sb --> Pb Pb -->|"× V_j"| Ob Ob -->|"write back (rescaled)"| O Ob -->|"update stats"| stats

数据流:外层循环遍历 K/V block(红色路径),内层遍历 Q block(蓝色路径)。每次在 SRAM 内完成 $\mathbf{S}_{ij}$ 计算 → 在线 softmax → $\tilde{\mathbf{P}}_{ij} \mathbf{V}_j$ → 累加到 $\mathbf{O}_i$ 并更新 $(m, \ell)$。$N \times N$ 矩阵从不被物化到 HBM。

Target operation #

Hardware model #

参数A100 值
HBM 容量 / 带宽40–80 GB / 1.5–2.0 TB/s
SRAM 容量 / 带宽192 KB/SM × 108 SMs / ~19 TB/s
Tensor Core peak (FP16)312 TFLOP/s
Block sizes$B_c = \lceil M/(4d) \rceil$, $B_r = \min(\lceil M/(4d) \rceil, d)$

§4 作者证明 #

符号表 #

符号含义
$N$序列长度
$d$Head dimension
$M$On-chip SRAM 大小
$B_r, B_c$Q 行 block 和 K/V 列 block 大小
$T_r, T_c$Block 数量 $\lceil N/B_r \rceil$, $\lceil N/B_c \rceil$
$m, \ell$在线 softmax 的 running max 和 running sum
$\mathbf{S}, \mathbf{P}$Score matrix 和 attention weight matrix

方程物理意义 #

Theorem 1(正确性):FlashAttention 输出 $\mathbf{O} = \text{softmax}(\mathbf{Q}\mathbf{K}^\top)\mathbf{V}$,FLOPs $O(N^2 d)$,额外内存 $O(N)$。通过对外层循环变量 $j$ 的归纳证明:每步后 $m^{(j)} = \text{rowmax}(\mathbf{S}_{:,:j})$,$\ell^{(j)} = \text{rowsum}(\exp(\mathbf{S}_{:,:j} - m^{(j)}))$,$\mathbf{O}^{(j)} = \mathbf{P}_{:,:j}\mathbf{V}_{:j}$。

Theorem 2(IO 复杂度)

$$\text{标准 attention IO} = \Theta(Nd + N^2)$$

$$\text{FlashAttention IO} = \Theta(N^2 d^2 / M)$$

推导:每次加载大小 $\Theta(M)$ 的 K/V block,需要 $T_c = \Theta(Nd/M)$ 次遍历 Q。每次遍历加载 $\Theta(Nd)$,总计 $\Theta(N^2 d^2 / M)$。

对于典型 $d = 64$, $M \approx 100$ KB:$d^2/M \approx 4096/10^5 \approx 0.04 \ll 1$,FlashAttention IO 比标准 attention 少约 $9\times$。

Proposition 3(下界/最优性):不存在精确 attention 算法在所有 $M \in [d, Nd]$ 上实现 $o(N^2 d^2 / M)$ IO 复杂度。证明:若存在则在 $M = \Theta(Nd)$ 时实现 $o(Nd)$ IO,但输入输出大小为 $Nd$,矛盾。

Roofline 分析 #

标准 attention 的 arithmetic intensity = $O(N^2 d) / O(Nd + N^2) \approx O(d)$(当 $N \gg d$),位于 memory-bound 区域。FlashAttention 通过减少 IO 提升 arithmetic intensity 至 $O(M/d)$,推向 compute-bound 边界。

实测数据(A100, GPT-2 medium, seq 1024):

GFLOPsHBM R/W (GB)Runtime (ms)
Standard66.640.341.7
FlashAttention75.24.47.3

FlashAttention FLOPs 更高(75.2 vs 66.6,因 recomputation)但 HBM 读写少 9.2×,运行快 5.7×——直观证明 FLOPs 是误导性指标。

6 项检查 #

  1. 正确性归纳:Theorem 1 通过对 $j$ 归纳证明每步 $(m, \ell, \mathbf{O})$ 正确。✔
  2. IO 下界:Proposition 3 证明 FlashAttention IO 渐近最优。✔
  3. Block size 约束:$B_c = \lceil M/(4d) \rceil$ 确保 $\mathbf{K}_j, \mathbf{V}_j, \mathbf{Q}_i, \mathbf{O}_i$ 同时放入 SRAM。✔
  4. 反向传播内存:仅存 $\mathbf{O}, m, \ell$($O(N)$),反向时重新计算 $\mathbf{S}, \mathbf{P}$。✔
  5. Dropout 重放:保存 PRNG state 而非 $O(N^2)$ mask,反向时重新生成。✔
  6. Block-sparse IO 缩放:Proposition 4 证明 IO 正比于非零 block 比例 $s$。✔
  7. §5 实验与数据 #

    训练速度 #

    模型基线FlashAttention加速
    BERT-large (seq 512)20.0 ± 1.5 min (MLPerf)17.4 ± 1.4 min15%
    GPT-2 small (seq 1K)9.5 days (HF)2.7 days3.5×
    GPT-2 medium (seq 1K)21.0 days (HF)6.9 days3.0×
    LRA (seq 1K–4K)2.4×

    长上下文质量 #

    GPT-2 smallContextPerplexityTime
    Megatron-LM1K18.24.7 days
    FlashAttention1K18.22.7 days
    FlashAttention4K17.53.6 days

    4K 上下文:比 Megatron 1K 快 30% 且 perplexity 低 0.7。

    Path-X / Path-256 #

    FlashAttention 是首个在 Path-X(seq 16K)上达到 61.4% 准确率的 Transformer(所有其他方法均为随机水平)。Block-sparse FlashAttention 在 Path-256(seq 64K)上达到 63.1%。

    不同 GPU 上的加速 #

    GPU典型加速范围
    A100 (hdim 64)2–4×
    A100 (hdim 128)略低(block 更大,SRAM 压力更高)
    RTX 30902.5–4.5×(内存带宽更低,IO 优化收益更大)
    T4加速较低(SRAM 更小 → block 更小)

    论文承认的弱项 #

    1. FlashAttention 反向传播在 seq 128 时比 Apex FMHA 略慢(0.20 vs 0.17 ms),因 recomputation 开销在短序列时占比更高。
    2. seq ≥ 1K 时 Linformer 前向传播更快(近似方法在极长序列时 FLOP 优势开始体现)。
    3. §6 论证链 #

      步骤论点证据
      1标准 attention 是 memory-bound:FLOPs 不是瓶颈,HBM IO 才是§2.1 A100 HBM vs SRAM 带宽差 10×;Fig. 2 table(75.2 vs 66.6 GFLOPs 但 9.2× fewer HBM R/W → 5.7× faster)
      2IO-awareness 原则:优化 HBM 读写次数而非 FLOP 数§1 引用 IO complexity 文献 [1];§3.2 Theorem 2 推导 FlashAttention IO = $\Theta(N^2 d^2/M)$
      3Tiling + online softmax 使 attention 可逐 block 计算§3.1 softmax 增量分解公式;Theorem 1 归纳证明正确性
      4Recomputation 以少量额外 FLOP 换取大量 HBM IO 节省§3.1 反向传播仅存 $(m, \ell)$;Fig. 2 证明 IO 减少主导 runtime
      5IO 复杂度渐近最优Proposition 3 下界证明
      6实验验证速度和质量双赢§4 BERT/GPT-2/LRA 加速 + Path-X 首次解决 + GPT-2 perplexity 提升

      §7 实现 cross-reference #

      代码仓库flash-attention

      • Kernel entry:CUDA kernel 实现 FlashAttention 前向/反向传播,融合 matmul + softmax + dropout + masking
      • Block size 选择:$B_c = \lceil M/(4d) \rceil$, $B_r = \min(B_c, d)$,根据 SRAM 容量和 head dim 自动确定
      • 支持范围:head dim 16/32/64/128,seq 长达 64K,FP16,Turing + Ampere GPU
      • 与 Apex FMHA 关系:FlashAttention 扩展 FMHA 增加 tiling + recomputation,解除 seq ≤ 512 / hdim = 64 / A100-only 的限制

      关键实现细节 #

      1. Online softmax 的数值稳定性:每个 block 计算时先减去 block-local max $\tilde{m}_{ij}$,再与全局 running max $m_i$ 合并时乘以 $e^{m_i^{\text{old}} - m_i^{\text{new}}}$ 校正因子——两级 max-subtraction 确保 exp 不溢出。
      2. Dropout PRNG state 复用:前向传播保存 PRNG state(而非 $O(N^2)$ mask),反向传播从相同 state 重新生成 mask。这将 dropout 的内存占用从 $O(N^2)$ 降至 $O(1)$。
      3. 可移植性 #

        论文承认 CUDA kernel 方法不可跨 GPU 架构移植(§5),呼吁类似 Halide 的编译器框架。当前仅支持 NVIDIA Turing/Ampere。

        部署上下文 #

        • Serving stack:可替代 PyTorch 标准 attention / Megatron-LM attention / Apex FMHA
        • Regime:prefill(大 batch × $N^2$,compute-intensive)和 training;推理 decode 场景不是本文重点
        • Fusion scope:softmax + matmul + dropout + masking,不含 RoPE / QKV projection / O projection

        Software → Hardware 启示 #

        • 更大 SRAM:FlashAttention 的 tile size 直接受限于 SRAM 容量;更大 SRAM 意味着更大 block → 更少 HBM trip → 更高性能
        • Halide-like attention compiler:当前每种 attention 变体需手写 CUDA kernel,编译器自动生成 IO-aware kernel 将大幅降低工程成本
        • Multi-GPU IO 优化:论文仅处理单 GPU,multi-GPU attention(如 Ring Attention)引入 GPU 间通信层,需要新的 IO 分析