FlashDecoding 数学推导
参考网页:https://zhuanlan.zhihu.com/p/1988996116017086993
一、公式作用概述
FlashDecoding 是一种用于大语言模型(LLM)推理解码阶段(Decoding Stage) 的高效注意力计算算法。在 Decoding 阶段,模型每次只生成一个新 token,因此 Query 的长度为 1,这导致 GPU 的并行度严重不足(大量流式多处理器 SM 处于空闲状态)。FlashDecoding 的核心思想是:将 KV Cache(键值缓存)沿序列维度切分为多个 Tile(子块),分配到不同的 SM 上并行计算局部注意力结果,最后通过 Online Softmax 技术将各局部结果合并为全局正确的输出。这种方法在不改变计算结果精度的前提下,显著提升了长序列解码的 GPU 利用率,实现了高达 8 倍的加速。
二、完整推导过程
2.1 问题背景与动机
2.1.1 标准 Attention 的定义
给定单个 Query 向量 q∈R1×d(解码阶段 Query 序列长度为 1),以及 Key 矩阵 K∈RNkv×d 和 Value 矩阵 V∈RNkv×d,其中 Nkv 是 KV Cache 的序列长度(可能很长),d 是注意力头维度。标准的缩放点积注意力(Scaled Dot-Product Attention)定义为:
Attention(q,K,V)=softmax(dqK⊤)V
为什么要除以 d? 这是因为当维度 d 较大时,点积的数值会变得非常大,导致 softmax 函数的梯度变得非常小(梯度消失问题)。除以 d 可以将点积的方差缩放到约 1,保持数值稳定性。
【知识卡片:Softmax 函数】
- 定义:Softmax 函数将一个实数向量转换为概率分布,使得所有输出值在 (0,1) 之间且和为 1。
- 公式:对于向量 x=[x1,x2,…,xn],softmax(xi)=∑j=1nexp(xj)exp(xi)。
- 本步作用:将注意力分数转换为权重分布,使得所有位置的重要性之和为 1。
2.1.2 解码阶段的并行度瓶颈
在预填充阶段(Prefill Stage),输入序列长度 Nq 较大,Query 矩阵 Q∈RNq×d 有很多行。FlashAttention 的做法是:将 Q 沿行维度切分为多个 Tile,不同 Tile 分配给不同的 SM 并行计算。每个 SM 处理一部分 Query,但需要使用完整的 K 和 V。
然而,在解码阶段(Decoding Stage),模型正在自回归地生成新 token,每次只需要计算一个 Query(即新 token 的 Query),所以 q∈R1×d。这意味着:
- 无法通过切分 Query 来获得并行度(Query 只有一行)。
- 如果使用 FlashAttention 的原版策略,只有一个 SM(或少量 SM)在工作,大量 SM 空闲。
- 同时,KV Cache 的序列长度 Nkv 可能非常长(例如 32K、64K 甚至更长),读取 KV Cache 成为瓶颈。
2.1.3 FlashDecoding 的核心思想
FlashDecoding 的解决方案是反转并行策略:
-
不再切分 Query(因为 Query 只有一行)。
-
改为切分 KV Cache:将 K 和 V 沿序列维度切分为 B 个 Tile:
K=[K(1);K(2);…;K(B)],V=[V(1);V(2);…;V(B)]
其中每个 K(b),V(b)∈RNtile×d,Ntile=Nkv/B。
-
每个 SM 处理一个 KV Tile:SM b 计算 q 与 K(b),V(b) 的局部注意力结果。
-
使用 Online Softmax 合并局部结果:由于 softmax 涉及全局归一化(需要知道所有位置的 exp 之和),各 SM 的局部结果不能直接相加,需要通过 Online Softmax 技巧进行归一化合并。

2.2 分块 Attention 的局部计算
将 KV Cache 切分为 B 个 Tile 后,第 b 个 Tile(b=1,2,…,B)的局部注意力计算为:
s(b)=dqK(b)⊤∈R1×Ntile
其中 s(b) 是第 b 个 Tile 上的注意力分数向量。
2.3 Online Softmax:核心数学工具
FlashDecoding 的关键挑战在于:如何将各 SM 计算的局部 softmax 结果合并为全局正确的 softmax 输出?
2.3.1 标准 Softmax 的数值稳定版本
标准 softmax 定义:
softmax(xi)=∑j=1Nexp(xj)exp(xi)
在数值计算中,直接使用这个公式会有数值溢出的风险:如果某个 xi 很大,exp(xi) 会超出浮点数表示范围。数值稳定的 softmax 实现利用了以下恒等式:
softmax(xi)=∑j=1Nexp(xj)exp(xi)=∑j=1Nexp(xj−m)exp(xi−m)
分子分母同乘 exp(−m) 即可得该恒等式。其中 m=maxj=1Nxj 是输入向量的最大值。
2.3.2 Online Softmax 的递推公式
Online Softmax 的核心观察是:可以将 softmax 的计算分解为增量更新。假设我们已经处理了前 j−1 个元素,现在要加入第 j 个元素 xj,可以维护两个状态变量:
- mj:前 j 个元素中的最大值(running maximum)
- dj:前 j 个元素的 exp 之和(running sum of exponentials): dj=∑i=1jexp(xi−mj)
初始状态:m1=x1,d1=exp(x1−m1)=exp(0)=1。
递推更新(对于 j=2,3,…,N):
mj=max(mj−1,xj)
dj=dj−1⋅exp(mj−1−mj)+exp(xj−mj)
处理完全部 N 个元素后,状态为 (mN,dN)。对任意 xi:
softmax(xi)=dNexp(xi−mN)=∑j=1Nexp(xj−mN)exp(xi−mN)
即 Online Softmax 与 标准 Softmax 数学等价。
【Online Softmax 推导】
将 dj 拆分为历史项与新项:
dj=历史 j−1 项i=1∑j−1exp(xi−mj)+新项 xjexp(xj−mj)
对任意历史项 i≤j−1,做基准平移:
exp(xi−mj)=exp(xi−mj−1+mj−1−mj)=exp(xi−mj−1)⋅exp(mj−1−mj)
对 i=1,…,j−1 求和:
i=1∑j−1exp(xi−mj)=exp(mj−1−mj)⋅=dj−1i=1∑j−1exp(xi−mj−1)
合并得到递推式:
dj=dj−1⋅exp(mj−1−mj)+exp(xj−mj)
【小例子:Online Softmax 和标准 Softmax 数学等价】
设 x=[1.0,2.0,0.5]。
初始化(j=1):m1=1.0,d1=exp(1.0−1.0)=1.0。
第 2 步(j=2,x2=2.0):
- m2=max(1.0,2.0)=2.0
- d2=1.0⋅exp(1.0−2.0)+exp(2.0−2.0)=exp(−1.0)+exp(0)=0.368+1.0=1.368
第 3 步(j=3,x3=0.5):
- m3=max(2.0,0.5)=2.0
- d3=1.368⋅exp(2.0−2.0)+exp(0.5−2.0)=1.368⋅1.0+exp(−1.5)=1.368+0.223=1.591
最终结果:
- softmax(x1)=exp(1.0−2.0)/1.591=0.368/1.591=0.231
- softmax(x2)=exp(2.0−2.0)/1.591=1.0/1.591=0.629
- softmax(x3)=exp(0.5−2.0)/1.591=0.223/1.591=0.140
验证(直接计算):
exp(1.0)=2.718,exp(2.0)=7.389,exp(0.5)=1.649,和 = 11.756。
- softmax(x1)=2.718/11.756=0.231 ✓
- softmax(x2)=7.389/11.756=0.629 ✓
- softmax(x3)=1.649/11.756=0.140 ✓

2.4 FlashDecoding 的分块合并推导
2.4.0 关键符号约定
在深入推导之前,先明确三个核心符号的含义。这些符号是理解 FlashDecoding 分块合并机制的关键:
| 符号 |
名称 |
含义 |
在 Online Softmax 中的作用 |
| m(b) |
局部最大值 |
第 b 个 Tile 中所有注意力分数的最大值 |
用于数值稳定:计算 exp(sj−m(b)) 时避免指数溢出 |
| ℓ(b)(或写作 l(b)) |
局部指数和 |
第 b 个 Tile 中所有 exp(sj−m(b)) 的和 |
作为该 Tile 局部 softmax 的归一化分母 |
| o(b) |
局部输出 |
第 b 个 Tile 的局部注意力结果 |
该 Tile 内部做 softmax 后的加权平均值 |
2.4.1 每个 Tile 的局部计算
对于第 b 个 KV Tile(b=1,2,…,B),SM b 并行计算以下四个量:
-
注意力分数:s(b)=dqK(b)⊤∈R1×Ntile
- 这是 Query q 与 Tile b 中所有 Key 的相似度分数向量。
-
局部最大值(running max):m(b)=maxj=1Ntilesj(b)
-
局部指数和(running sum):ℓ(b)=∑j=1Ntileexp(sj(b)−m(b))
- 该 Tile 内所有(经数值稳定后的)指数值之和,充当局部 softmax 的分母。
-
局部加权输出:o(b)=ℓ(b)∑j=1Ntileexp(sj(b)−m(b))⋅Vj(b)∈R1×d
- 该 Tile 的局部 softmax 结果,即 Value 的加权平均,权重来自局部 softmax。
重要说明:这里的 o(b) 是局部 softmax 结果——它只考虑了 Tile b 内部的归一化。如果直接将所有 o(b) 相加,结果不等于全局 Attention,因为每个 Tile 的 softmax 分母 ℓ(b) 只包含了该 Tile 内的指数和,而非全局所有位置的指数和。必须通过 2.4.2 节的全局合并公式才能得到正确结果。
2.4.2 全局合并公式推导
目标:给定所有 Tile 的局部统计量 {(m(b),ℓ(b),o(b))}b=1B,求全局正确的注意力输出 ofinal。
步骤 1:求全局最大值
全局最大值是所有 Tile 最大值的再取最大:
mglobal=b=1maxBm(b)
为什么要这一步? 因为每个 Tile 的局部计算已经减去了自己的局部最大值 m(b),但全局 softmax 需要减去全局最大值 mglobal。我们需要找到所有分数中的真正最大值。
步骤 2:计算全局归一化因子
全局的指数和需要将每个 Tile 的局部指数和 "重新缩放" 到全局最大值的尺度上:
ℓglobal=b=1∑Bexp(m(b)−mglobal)⋅ℓ(b)
推导依据:
ℓglobal=b=1∑Bj=1∑Ntileexp(sj(b)−mglobal)=b=1∑Bexp(m(b)−mglobal)j=1∑Ntileexp(sj(b)−m(b))=b=1∑Bexp(m(b)−mglobal)⋅ℓ(b)
【知识卡片:指数乘法恒等式】
- 定义:指数函数满足 exp(a+b)=exp(a)⋅exp(b)。
- 公式:exp(x−mglobal)=exp(x−m(b))⋅exp(m(b)−mglobal)。
- 本步作用:将局部坐标系(以 m(b) 为参考)的指数值转换到全局坐标系(以 mglobal 为参考),使得来自不同 Tile 的数值可以在同一尺度上相加。
【小例子:尺度转换】
假设 Tile 1 的最大值 m(1)=5.0,Tile 2 的最大值 m(2)=8.0,则 mglobal=8.0。
对于 Tile 1 中的某个分数 sj(1)=3.0:
- 局部坐标:exp(sj(1)−m(1))=exp(3.0−5.0)=exp(−2.0)=0.135
- 全局坐标:exp(sj(1)−mglobal)=exp(3.0−8.0)=exp(−5.0)=0.00674
- 用恒等式:exp(3.0−5.0)⋅exp(5.0−8.0)=0.135⋅0.0498=0.00674 ✓
步骤 3:合并局部输出
全局的输出向量是所有 Tile 局部输出的加权平均,权重包含了重新缩放因子:
ofinal=ℓglobal∑b=1Bexp(m(b)−mglobal)⋅ℓ(b)⋅o(b)
推导依据:
ofinal=∑b=1B∑j=1Ntileexp(sj(b)−mglobal)∑b=1B∑j=1Ntileexp(sj(b)−mglobal)⋅Vj(b)
分子展开:
b=1∑Bj=1∑Ntileexp(sj(b)−mglobal)⋅Vj(b)=b=1∑Bexp(m(b)−mglobal)j=1∑Ntileexp(sj(b)−m(b))⋅Vj(b)
注意到 o(b)=ℓ(b)∑j=1Ntileexp(sj(b)−m(b))⋅Vj(b),所以 ∑j=1Ntileexp(sj(b)−m(b))⋅Vj(b)=ℓ(b)⋅o(b)。
代入即得:
ofinal=ℓglobal∑b=1Bexp(m(b)−mglobal)⋅ℓ(b)⋅o(b)
2.5 完整算法流程
综合以上推导,FlashDecoding 的完整算法流程如下:
输入:Query 向量 q∈R1×d,Key 矩阵 K∈RNkv×d,Value 矩阵 V∈RNkv×d,Tile 大小 Ntile。
输出:全局注意力结果 ofinal∈R1×d。
阶段 1:各 SM 并行计算局部结果(步骤 (2a)-(2d) 对每个 Tile 并行执行)
对每个 Tile b=1,2,…,B(其中 B=⌈Nkv/Ntile⌉):
(2a) 提取 KV Tile:
K(b)=K[(b−1)⋅Ntile:min(b⋅Ntile,Nkv),:]∈RNtile(b)×d
V(b)=V[(b−1)⋅Ntile:min(b⋅Ntile,Nkv),:]∈RNtile(b)×d
(2b) 计算注意力分数:
s(b)=dqK(b)⊤∈R1×Ntile(b)
(2c) 计算局部统计量(数值稳定的 Online Softmax):
m(b)=j=1maxNtile(b)sj(b)
ℓ(b)=j=1∑Ntile(b)exp(sj(b)−m(b))
o(b)=ℓ(b)∑j=1Ntile(b)exp(sj(b)−m(b))⋅Vj(b)∈R1×d
阶段 2:全局归约合并(一个轻量级的 Reduce Kernel)
(3a) 求全局最大值:
mglobal=b=1maxBm(b)
(3b) 计算全局归一化因子:
ℓglobal=b=1∑Bexp(m(b)−mglobal)⋅ℓ(b)
(3c) 合并局部输出:
ofinal=ℓglobal∑b=1Bexp(m(b)−mglobal)⋅ℓ(b)⋅o(b)
2.6 等价性证明
定理:FlashDecoding 的分块计算结果与全序列直接计算的 Attention 结果完全等价。
证明:
全序列直接计算的注意力输出为:
odirect=∑j=1Nkvexp(sj−mglobal)∑j=1Nkvexp(sj−mglobal)⋅Vj
其中 sj=dq⋅Kj,mglobal=maxjsj。
将序列按 Tile 划分后,分子和分母都可以按 Tile 分解:
j=1∑Nkvexp(sj−mglobal)⋅Vj=b=1∑Bj∈Tile b∑exp(sj−mglobal)⋅Vj
对于 Tile b 内部的元素,利用 m(b) 进行分解:
exp(sj−mglobal)=exp(sj−m(b))⋅exp(m(b)−mglobal)
因此:
j∈Tile b∑exp(sj−mglobal)⋅Vj=exp(m(b)−mglobal)j∈Tile b∑exp(sj−m(b))⋅Vj=exp(m(b)−mglobal)⋅ℓ(b)⋅o(b)
同理,分母:
j=1∑Nkvexp(sj−mglobal)=b=1∑Bexp(m(b)−mglobal)⋅ℓ(b)=ℓglobal
因此:
odirect=ℓglobal∑b=1Bexp(m(b)−mglobal)⋅ℓ(b)⋅o(b)=ofinal
证毕。

2.7 与 FlashAttention 的对比
| 特性 |
FlashAttention(Prefill) |
FlashDecoding(Decoding) |
| Query 长度 |
Nq≫1(长序列) |
Nq=1(单个 token) |
| 切分维度 |
沿 Query 维度切分 |
沿 KV Cache 维度切分 |
| 并行来源 |
多个 Query Tile 并行 |
多个 KV Tile 并行 |
| 每个 SM 的工作 |
处理部分 Query + 完整 KV |
处理完整 Query + 部分 KV |
| 是否需要合并 |
不需要(各 SM 结果独立) |
需要 Online Softmax 合并 |
| 适用阶段 |
Prefill(编码阶段) |
Decoding(解码阶段) |

三、涉及的基本数学知识清单
| 概念名称 |
在本推导中的具体作用 |
一句话定义或公式表达 |
| Softmax 函数 |
将注意力分数转换为概率分布 |
softmax(xi)=∑jexp(xj)exp(xi) |
| 缩放点积注意力 |
定义 Query 与 KV 的交互方式 |
Attention(Q,K,V)=softmax(QKT/d)V |
| Max-Shift 数值稳定 |
避免 softmax 计算中的指数溢出 |
softmax(xi)=∑jexp(xj−m)exp(xi−m),m=maxjxj |
| Online Softmax |
支持增量式 softmax 计算,是分块合并的核心 |
递推维护 mj=max(mj−1,xj) 和 dj=dj−1⋅exp(mj−1−mj)+exp(xj−mj) |
| 指数乘法恒等式 |
将局部坐标系的指数值转换到全局坐标系 |
exp(a−c)=exp(a−b)⋅exp(b−c) |
| 矩阵乘法 |
计算 Query 与 Key 的相似度分数 |
(AB⊤)i,j=∑kAi,k⋅Bj,k |
| GPU SM(流式多处理器) |
FlashDecoding 要充分利用的并行计算资源 |
GPU 的核心计算单元,多个 SM 可同时执行不同任务 |
| 递推关系 |
描述 Online Softmax 的逐步累积过程 |
an=f(an−1,new_input) |
| 最大值运算 |
确定全局 softmax 的参考点 |
mglobal=maxbm(b) |
| 加权平均 |
合并各 Tile 的局部输出为全局输出 |
ofinal=∑bwb∑bwb⋅o(b) |
四、总结
FlashDecoding 是一种针对 LLM 推理解码阶段的高效注意力算法。其核心创新在于:
- 反转并行策略:Prefill 阶段切分 Query,Decoding 阶段切分 KV Cache。
- Online Softmax 合并:通过维护每个 Tile 的局部最大值 m(b) 和局部指数和 ℓ(b),在全局归约阶段将各局部结果正确合并。
- 数学等价性:分块计算的结果与全序列直接计算的结果完全等价(已在 2.6 节证明)。
FlashDecoding 的完整公式可以概括为:
局部计算(每个 Tile 并行):
s(b)=dqK(b)⊤,m(b)=jmaxsj(b),ℓ(b)=j∑exp(sj(b)−m(b)),o(b)=ℓ(b)∑jexp(sj(b)−m(b))Vj(b)
全局合并:
mglobal=bmaxm(b),ofinal=∑b=1Bexp(m(b)−mglobal)⋅ℓ(b)∑b=1Bexp(m(b)−mglobal)⋅ℓ(b)⋅o(b)
该算法已被集成到 FlashAttention 2.2+、xFormers、FlashInfer 等主流推理加速库中,成为长序列 LLM 推理的标准优化技术。
本文档所有推导均基于 Dao et al., "Flash-Decoding for long-context inference" (2023) 及知乎技术博客,推导过程经过双重校验。
评论