想象你是餐厅大厨,要为一百桌客人做一道招牌菜。菜谱很简单:把三种原料按顺序混合、加热、出锅。但你的厨房有个奇怪规定——所有食材都存放在离灶台很远的超大冷库里(HBM),而灶台旁的备菜台只有书本大小(SRAM)。每做一步,你都得跑一趟冷库把半成品端回来,做完再端回去存好。一百桌客人的分量全堆在冷库里,三个步骤来回搬运几百次,客人饿得直拍桌子。 后来你想明白了:与其每次跑冷库存半成品,不如把原料一小份一小份搬到备菜台上,在灶台边完成“打分—归一—拌菜”全部动作,最后只把成品端回去。搬动次数从“按桌数的平方”骤降到“按桌数”。 这就是 Flash Attention V2 的绝活。注意力计算——AI 判断“哪些词该互相注意”的核心步骤——本来要来回读写三个巨大的中间矩阵,显存带宽被撑爆。V2 把计算分块锁在 GPU 的 SRAM 里一次搞定,IO 复杂度从 O(N²) 降到 O(N),长上下文训练直接提速 2-4 倍,而且结果和原来一模一样,没有一丁点近似。

岗位关联

对 AI 从业者:Flash Attention 是当前大模型训练与推理的事实标准算子。理解它的分块与 IO 优化思路,是做长上下文调优、推理服务压测和手写高性能算子的必备底子。

目录
  1. 可视化演示
  2. 1. 注意力三连乘:QK^T、Softmax、PV
  3. 2. 存储金字塔:SRAM 与 HBM
  4. 3. IO 复杂度:从 O(N^2) 到 O(N)
  5. 4. 分块策略:一次只做一盘菜
  6. 5. 在线 Softmax:边做边校正温度计
  7. 6. 重计算与内核融合:反向的省钱之道
  8. 7. V2 工程优化:主厨的流程革命
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示Flash Attention V2三阶段:标准与Flash Attention的HBM读写IO对比、QKV分块融合在SRAM内完成计算、不同序列长度下加速比对比,三模式递进呈现从IO瓶颈分析到分块优化到性能提升。

本节配有交互动效(进入视口后自动加载,约 3KB)。

标准vs Flash Attention IO对比 STD: 标准方式需6次HBM读写(Q/K/V/S/P/O),中间矩阵S和P尺寸N×N FLA: Flash方式仅4次HBM读写,S和P在SRAM内融合计算不落盘 IO: O(N²) → O(N²·d/M),M=SRAM大小 IO降低33%,无近似精确计算

1. 注意力三连乘:QK^T、Softmax、PV

大厨的招牌菜有三个固定步骤:先给每桌客人的口味打分,再把分数折算成“谁该多吃一口”的权重,最后按权重把食材拌成一盘菜。每一步做完,大厨都习惯把半成品端回冷库保存——毕竟备菜台太小,放不下全部东西。

注意力机制正是这三步。Query 与 Key 做内积,得到“两两相关”的分数矩阵 S;Softmax 把每行的分数变成和为 1 的概率矩阵 P;最后用 P 对 Value 做加权求和,得到输出 O。标准实现中,S、P、O 都是 N×N 的大矩阵,每一步都要写入 HBM 再读回来,等于大厨每做一步都跑一趟冷库。

这盘菜本身并不难做,难的是每一步都要跑冷库:S 写完存回去、读完算 P、P 写完存回去、读完算 O。三步三趟,一百桌客人就这么被冷库的路程拖垮了。

Attention(Q,K,V)=softmax(QK⊤d)V\text{Attention}(Q,K,V)=\text{softmax}\left(\displaystyle\frac{QK^\top}{\sqrt{d}}\right)V
  1. 相关性打分$QK^\top$ — 把序列里每个 query 与所有 key 做内积,生成 N×N 的分数矩阵 S,标记每对 token 的关联强度。
  2. 缩放稳定$\displaystyle\frac{1}{\sqrt{d}}$ — 除以维度 d 的平方根,防止内积数值过大导致后续 softmax 梯度消失。
  3. 按行归一$\text{softmax}(\cdot)$ — 将每行分数转成和为 1 的概率分布,回答“当前 token 该把注意力分给谁”。
  4. 加权输出$V$ — 用概率矩阵 P 对 Value 矩阵做加权求和,得到最终输出 O。

2. 存储金字塔:SRAM 与 HBM

冷库又大又远,备菜台又小又近。大厨真正慢下来的时候,往往不是切菜本身,而是往返冷库的腿。GPU 的存储世界也是这样一座金字塔:HBM 容量以 GB 计,但走到它面前要花几十上百个时钟周期;SRAM 只有几十 KB,却几乎可以瞬间访问。

更关键的是带宽的增速赶不上算力的增速。GPU 算力每年翻倍,HBM 带宽却只涨四成,于是越来越多的算子从“计算密集”变成“访存密集”——GPU 算得再快,也在干等数据搬进来。注意力就是最典型的例子。

冷库再大,腿脚不够快也没用。注意力计算恰恰是“搬货”远多于“干活”,所以优化它的关键不在灶台上的刀工,而在减少往返冷库的趟数。

I=FLOPsBytesI=\displaystyle\frac{\text{FLOPs}}{\text{Bytes}}
  1. 分子 FLOPs$\text{FLOPs}$ — 一次操作需要的浮点运算次数,代表 GPU 真正“干活”的量。
  2. 分母 Bytes$\text{Bytes}$ — 从 HBM 读入或写出的字节数,代表“搬货”的量。
  3. 商 I$I$ — 算术强度,即每搬 1 字节数据能支撑多少次计算。I 越大,越不容易被带宽卡住。

3. IO 复杂度:从 O(N^2) 到 O(N)

桌数翻倍,大厨来回搬半成品的趟数会变成四倍——因为每一桌都要跟另外每桌做一次配菜组合,这就是二次方增长。而分块上菜的做法,每桌只搬一次原料和成品,翻倍之后只是两倍。

IO 复杂度衡量的就是读写 HBM 的次数。标准注意力里,S 和 P 都是 N×N 的矩阵,写一遍、读一遍,光这两个中间矩阵就贡献了 O(N²) 的流量。Flash Attention 把 S 和 P 留在 SRAM 上用完即弃,Q、K、V、O 各自流式读写一次,中间矩阵完全不落地。

从“每桌跑三趟”变成“全场按桌数跑一趟”,IO 少了一个量级,墙钟时间自然跟着缩水。这就是 Flash Attention 能在长上下文训练中拿到 2-4 倍加速的根源。

CIOstd=Θ(N2),CIOflash=Θ(N)C_{\text{IO}}^{\text{std}}=\Theta(N^2),\qquad C_{\text{IO}}^{\text{flash}}=\Theta(N)
  1. N 的含义$N$ — 输入序列长度,比如一段文本的 token 数,也代表客人桌数。
  2. 渐近记号$\Theta(\cdot)$ — 表示复杂度的紧致界,描述“随 N 增大,读写量按什么速度膨胀”。
  3. 平方与线性$N^2$ 与 $N$ — 标准实现因为搬运 N×N 的中间矩阵而呈平方增长,Flash 只搬运 Q/K/V/O,呈线性增长。

4. 分块策略:一次只做一盘菜

备菜台每次只能放下一桌的食材,所以大厨把一百桌的原料分成小批,每批在灶台上完成“打分—归一—拌菜”全套流程,再把成品端回冷库。一批做完再做下一批,绝不中途回冷库。

Flash Attention 的外层循环遍历 Query 块,内层循环遍历 Key/Value 块。对每个 Q 块,依次扫过所有 K/V 块,在 SRAM 里算出局部分数、局部 softmax,再累加进输出。关键是块大小由 SRAM 容量决定,不能拍脑袋随便设。

灶台有多大,每份菜就只能做多大。分块之后还有个小问题:每个块算出的 softmax 只是局部的,怎么拼起来才是完整的 softmax?这就要靠下一节的在线技巧了。

BQ=⌊MSRAM4d⌋B_Q=\left\lfloor\displaystyle\frac{M_{\text{SRAM}}}{4d}\right\rfloor
  1. SRAM 容量$M_{\text{SRAM}}$ — GPU 片上可用的 SRAM 总空间,相当于备菜台的总面积。
  2. 四份开销$4$ — 一次迭代要同时容纳 Q 块、K 块、V 块和输出 O 块,共四个矩阵。
  3. 向量维度$d$ — 每个 token 的特征维度,决定单块体积。
  4. 平均分配$\displaystyle\frac{M_{\text{SRAM}}}{4d}$ — 四个块平分灶台,算出每个块最多能放多少行。
  5. 向下取整$\left\lfloor\cdot\right\rfloor$ — 留出余量,防止数据超出 SRAM,宁可少放不可溢出。

5. 在线 Softmax:边做边校正温度计

大厨没法等一百桌的打分全部齐了再统一调咸淡,他选择边炒边尝。每尝一口,就看看温度计上的最高温度;如果这口更热,就把之前调好的味道乘以一个缩放系数,整体校正到新刻度上。最后出锅时,味道跟“先算完再一起调”一模一样。

Softmax 需要整行的最大值 m 和总和 l。分块后 Flash 看不到整行,于是维护两个“运行中的统计量”:当前见过的最大值 m,和当前总和 l。每来一个新块,若新块出现更大的最大值,就把旧统计按比例缩小到新刻度,再累加新块的贡献。

这套“边算边校准”不是近似,而是精确的数学恒等变换。温度计虽然一直在动,但最后读出的温度,和一步到位是同一个数字。

mnew=max⁡(m,rowmax(Sj))m^{\text{new}}=\max(m,\text{rowmax}(S_j))
lnew=l⋅em−mnew+erowmax(Sj)−mnewl^{\text{new}}=l\cdot e^{m-m^{\text{new}}}+e^{\text{rowmax}(S_j)-m^{\text{new}}}
Onew=O⋅llnew⋅em−mnew+eSj−mnewlnewVjO^{\text{new}}=O\cdot\frac{l}{l^{\text{new}}}\cdot e^{m-m^{\text{new}}}+\frac{e^{S_j-m^{\text{new}}}}{l^{\text{new}}}V_j
  1. 更新最大值$m^{\text{new}}=\max(m,\text{rowmax}(S_j))$ — 取旧的最大值和新块的最大值中更大的那个,作为校正基准。
  2. 校正旧总和$l\cdot e^{m-m^{\text{new}}}$ — 旧总和里的每一项都在旧刻度下,乘以指数因子缩放到新刻度。
  3. 加入新块$+\ e^{\text{rowmax}(S_j)-m^{\text{new}}}$ — 新块的最大值也缩放到新刻度,计入总和 l。
  4. 合并输出$O^{\text{new}}$ — 旧输出按新旧总和比例衰减,新块加权求和后合并,每一块都对最终结果做出贡献。

6. 重计算与内核融合:反向的省钱之道

大厨做菜时不再写详细笔记。等到要复盘“这道菜到底怎么做的”时,他宁可把关键步骤重新做一遍,也不愿随身带一本占地方的厚笔记本。反向传播也是同样的道理。

训练时反向要算 S 和 P 的梯度。传统做法正向时把 S、P 存到 HBM,反向再读回来;Flash Attention V2 干脆不存,反向需要时重新算一遍正向。多花一次前向的浮点运算,却省下 O(N²) 的显存读写。在访存瓶颈面前,这笔买卖非常划算。

除了重算,V2 还把多个 CUDA kernel 融合成一个:原本“写入→读回→再计算”的割裂流程,变成一次启动内连续完成。好比大厨把洗菜、切菜、下锅的多个动作合并成一套流水,少弯腰,少转身。

FLOPsrecompute=FLOPsforward,memorysaved=Θ(N2)\text{FLOPs}_{\text{recompute}}=\text{FLOPs}_{\text{forward}},\qquad \text{memory}_{\text{saved}}=\Theta(N^2)
  1. 前向浮点量$\text{FLOPs}_{\text{forward}}$ — 正向一次 Attention 所需的浮点运算。
  2. 相等关系$\text{FLOPs}_{\text{recompute}}=\text{FLOPs}_{\text{forward}}$ — 反向重算让总计算量翻倍,但换来的是更少等待。
  3. 节省的显存$\text{memory}_{\text{saved}}=\Theta(N^2)$ — 省掉的是 S 和 P 两个 N×N 矩阵,序列越长省得越多。

7. V2 工程优化:主厨的流程革命

V1 大厨已经学会在灶台上做菜,但他频繁停下来看火、翻勺,真正切菜的时间只占七成。V2 大厨重新设计了站位和流程:把更多时间留给切菜(矩阵乘法),减少看火翻勺(非矩阵运算),还同时开四个灶头按行并行。

V2 相对 V1 有三个关键改进:不再使用 split-K 带来的原子操作,改为按行并行,减少非矩阵乘法的占比;把缩放因子融合进计算,少一次独立乘法;在 A100 上精细调优块大小和循环顺序,让矩阵乘法的时间占比从约 75% 提升到 90% 以上。算法没变,流程变了,速度就上来了。

同样的菜谱,换一种更顺手的方式上菜,客人等的时间直接砍半。Flash Attention 的进化路线也告诉我们:到了带宽瓶颈时代,优化往往不靠发明新算法,而靠少搬一次货。

---

Speedup≈TV1TV2≈2×\text{Speedup}\approx\displaystyle\frac{T_{\text{V1}}}{T_{\text{V2}}}\approx 2\times
  1. 耗时比$\displaystyle\frac{T_{\text{V1}}}{T_{\text{V2}}}$ — V1 的墙钟时间除以 V2 的墙钟时间,得到相对加速比。
  2. 近似结果$\approx 2\times$ — 论文报告在 A100 上 V2 比 V1 快约 2 倍。

AI 应用场景

场景一:大模型长上下文训练

阶段:模型训练与调优

解决的问题:预训练时序列长度从 2048 拉到 128k,标准注意力的 S/P 中间矩阵是 N×N,128k 时单是中间矩阵就要约 64GB,远超单卡显存。Flash Attention V2 让中间矩阵不落地,长上下文训练不再被显存卡死,同时 IO 降低带来 2-4 倍训练加速。

具体案例:某团队微调 7B 模型,序列长度 32k,标准实现需要 8 张 A100 且频繁重试;换上 Flash Attention V2 后 4 张卡即可训练,每轮耗时缩短约 3 倍,效果完全不下降。

场景二:长文本在线推理服务

阶段:推理部署与性能优化

解决的问题:在线问答要处理几十页文档,每次生成 token 都要做注意力计算。KV cache 在 HBM 里反复读写,成为吞吐瓶颈。FlashAttention 系列(含 Decoding 变体)减少中间读写,让长文档摘要的首 token 延迟和每秒生成数都明显改善。

具体案例:一个文档摘要服务,输入 10k token,优化前单请求延迟 8 秒,引入 FlashAttention 后降到 2.5 秒,服务端吞吐提升 2 倍以上。

场景三:推荐系统序列特征建模

阶段:特征工程与模型训练

解决的问题:用户行为序列就像一段“行为文本”,注意力机制要给每个历史行为打分。序列从几十条增长到上千条时,标准注意力同样面临中间矩阵膨胀。用 FlashAttention V2 处理行为序列,可以支撑更长的行为历史,提升 CTR 预估精度。

具体案例:某电商推荐团队把用户最近 512 个行为作为序列特征,用注意力建模。此前序列长度 256 时训练一天;用 FlashAttention 后序列翻倍到 512,训练时间反而缩短 40%。

Python 演示

python69 行
import math def standard_attention(Q, K, V):    n = len(Q)    d = len(Q[0])    S = [[0.0] * n for _ in range(n)]    P = [[0.0] * n for _ in range(n)]    O = [[0.0] * d for _ in range(n)]    for i in range(n):        for j in range(n):            S[i][j] = sum(Q[i][t] * K[j][t] for t in range(d))            S[i][j] /= math.sqrt(d)    for i in range(n):        m = max(S[i])        total = 0.0        for j in range(n):            P[i][j] = math.exp(S[i][j] - m)            total += P[i][j]        for j in range(n):            P[i][j] /= total        for j in range(n):            for t in range(d):                O[i][t] += P[i][j] * V[j][t]    return O, 4 * n * n def flash_attention(Q, K, V, B):    n = len(Q)    d = len(Q[0])    O = [[0.0] * d for _ in range(n)]    L = [0.0] * n    M = [-float('inf')] * n    for ib in range(0, n, B):        qb = Q[ib:ib + B]        for jb in range(0, n, B):            kb = K[jb:jb + B]            vb = V[jb:jb + B]            for li, q in enumerate(qb):                i = ib + li                scores = [sum(q[t] * kb[j][t] for t in range(d)) / math.sqrt(d)                          for j in range(B)]                row_max = max(scores)                row_exps = [math.exp(s - row_max) for s in scores]                row_sum = sum(row_exps)                new_m = max(M[i], row_max)                old_scale = math.exp(M[i] - new_m)                new_scale = math.exp(row_max - new_m)                new_l = L[i] * old_scale + row_sum * new_scale                for t in range(d):                    local = sum(row_exps[j] / row_sum * vb[j][t]                                for j in range(B))                    O[i][t] = (O[i][t] * L[i] * old_scale / new_l                               + local * row_sum * new_scale / new_l)                L[i] = new_l                M[i] = new_m    return O, 0 if __name__ == '__main__':    n, d, B = 8, 4, 2    Q = [[(i + 1) * 0.5 + t for t in range(d)] for i in range(n)]    K = [[(i + 1) * 0.3 - t for t in range(d)] for i in range(n)]    V = [[(i + 1) * 0.2 + t * 0.1 for t in range(d)] for i in range(n)]    O_std, io_std = standard_attention(Q, K, V)    O_fa, io_fa = flash_attention(Q, K, V, B)    diff = max(abs(O_std[i][t] - O_fa[i][t])               for i in range(n) for t in range(d))    print('standard S/P HBM elements:', io_std)    print('flash   S/P HBM elements:', io_fa)    print('max abs diff:', diff)    assert diff < 1e-9
目的:用纯 Python 模拟标准注意力与 Flash Attention 分块计算的数值一致性和中间矩阵 HBM 访问量对比。
  1. S[i][j] = sum(Q[i][t] * K[j][t] for t in range(d))计算 QK^T 打分,对应注意力公式的第一步。
  2. P[i][j] = math.exp(S[i][j] - m)减去行最大值再指数,保证数值稳定。
  3. scores = [sum(q[t] * kb[j][t] for t in range(d)) / math.sqrt(d) for j in range(B)]分块内只算当前 K 块的小分数矩阵,不触碰其他行。
  4. row_exps = [math.exp(s - row_max) for s in scores]在块内先算指数,等价于局部 softmax 分子。
  5. new_m = max(M[i], row_max)在线 softmax 的第一步:更新运行中的最大值。
  6. old_scale = math.exp(M[i] - new_m)把旧的统计量缩放到新最大值刻度。
  7. O[i][t] = O[i][t] * L[i] * old_scale / new_l + local * row_sum * new_scale / new_l合并输出:旧输出衰减,新块加权累加。
  8. return O, 0Flash 版本把 S/P 留在"SRAM",因此 HBM 中间矩阵流量为 0。

常见误区

误区听说 Flash Attention 是“分块近似计算”,长上下文训练质量会打折扣,所以不敢用在关键模型上。

正解它和标准 softmax 在数学上完全等价。在线 softmax 每次用全局最大值校正旧统计量,最终结果就是同一个 softmax 的精确值,差异仅来自浮点舍入(通常 <1e-6)。不是牺牲精度换速度,而是省掉了多余搬运。

为何常见:稀疏注意力、线性注意力等加速方案确实是近似的,很多人把“加速注意力”统统归为近似算法。

误区既然 IO 复杂度从 O(N²) 降到 O(N),那 Flash Attention 应该让计算也变成线性,序列越长越“划算”。

正解FLOPs 完全没变,仍是 O(N²d)。O(N) 只是 HBM 读写的量级。GPU 上很多算子卡在访存而不是计算,省 IO 能直接反映为加速 2-4 倍,但数学计算量依旧是那么多。

为何常见:“IO 复杂度”是个较新的概念,初学者容易把它和一般的时间复杂度混为一谈。

误区既然分块是为了减少冷库往返,那把块设置得越大,岂不是越快?

正解块大小受 SRAM 容量硬限制,超了直接放不下。且过大的块会挤占寄存器、降低并行度,反而拖慢速度。真实部署要按 SRAM 容量、维度 d、GPU 架构综合调优,论文给出了经验公式。

为何常见:搬一次大包裹确实比搬十次小包裹省力,但忘记灶台只有那么大。

误区反向传播重算 S/P 会让训练计算量翻倍,感觉很不划算,还是把中间矩阵存下来更稳妥。

正解GPU 最贵的是等待,而不是算力。Flash Attention V2 用翻倍的浮点运算换掉 O(N²) 的 HBM 访问,在访存瓶颈下总时间反而下降。长序列场景中,省显存还能支持更大 batch,收益更明显。

为何常见:CPU 时代计算通常比内存贵,很多人沿用“宁可多存也别重算”的旧直觉。

误区既然中间矩阵不落地,显存占用变成 O(N),那显存焦虑应该彻底消失了。

正解它省的是 S/P 这类 N×N 中间矩阵,但 Q/K/V/O 和 KV cache 仍在 HBM 里。序列极长时 KV cache 照样可能爆显存,还需要序列并行、稀疏注意力、KV cache 量化等手段配合。

为何常见:宣传常说“显存节省 O(N²)”,被夸大成了“总显存也降到 O(N)”。

面试题

Q1. Flash Attention 主要减少的是什么开销?

单选题 · easy

  • A.矩阵乘法的计算量
  • B.HBM 的中间读写← 正确答案
  • C.Softmax 的运算量
  • D.参数的存储空间

答案:B。Flash Attention 不动浮点计算量,而是把 S/P 中间矩阵留在 SRAM,避免 HBM 反复搬运,IO 复杂度从 O(N²) 降到 O(N)。

Q2. 在线 Softmax 的核心目的是什么?

单选题 · mid

  • A.让 softmax 数值更平滑
  • B.看不到整行也能精确归一← 正确答案
  • C.避免 fp16 精度不足
  • D.减少矩阵乘法次数

答案:B。分块后拿不到整行的最大值与总和,在线 Softmax 维护运行中的 m 和 l,每块校正,数学上与全局 softmax 完全等价,不是平滑或近似。

Q3. 下列哪些是 Flash Attention V2 相对 V1 的改进?

多选题 · mid

  • A.提高矩阵乘法时间占比← 正确答案
  • B.去掉 split-K 原子操作← 正确答案
  • C.使用稀疏近似注意力
  • D.反向重算不存 S/P← 正确答案

答案:ABD。V2 按行并行去掉原子操作、减少非矩阵乘占比、反向重算不缓存 S/P;它没有引入稀疏或近似,仍是精确注意力。

Q4. HBM 与 SRAM 的关系,最适合类比厨房里的什么?

单选题 · easy

  • A.灶台与装菜的盘子
  • B.冷库与备菜台← 正确答案
  • C.铁锅与菜刀
  • D.大厨与服务员

答案:B。HBM 容量大但访问慢,如冷库;SRAM 容量小但速度极快,如备菜台。两者的速度与容量差异正好对应 GPU 的两级存储。

Q5. 标准 Attention 的 HBM 访问复杂度是?

单选题 · mid

  • A.O(N)
  • B.O(N log N)
  • C.O(N^2)← 正确答案
  • D.O(N^2 d)

答案:C。S 和 P 都是 N×N 矩阵,写一次、读一次就贡献 O(N²) 流量,因此标准实现呈平方级 IO。

Q6. Flash Attention 中,下面哪些矩阵不需要从 HBM 读回?

多选题 · mid

  • A.S = QK^T← 正确答案
  • B.P = softmax(S)← 正确答案
  • C.Q 矩阵分块
  • D.V 矩阵分块

答案:AB。S 和 P 在 SRAM 中算完立刻用于后续,不写回 HBM;Q/K/V 仍需分块从 HBM 读取,O 最后写回。

Q7. 若 SRAM 容量为 M,特征维度为 d,Flash Attention 的 Query 块大小通常取?

单选题 · hard

  • A.M / d
  • B.M / (4d)← 正确答案
  • C.4M / d
  • D.M / d^2

答案:B。一次迭代要同时容纳 Q、K、V、O 四个块,平均每个块约 M/(4d),再向下取整留余量。

Q8. FlashAttention V2 反向传播不保存 S/P,原因是什么?

单选题 · hard

  • A.省显存换取重算← 正确答案
  • B.梯度不需要它们
  • C.S/P 永远不计算
  • D.反向无法重算

答案:A。反向梯度需要 S/P,V2 选择重算来避免存储,多花一次前向 FLOPs,省掉 O(N²) 显存访问,总时间反而更快。

Q9. 长上下文训练中 FlashAttention 带来的好处有哪些?

多选题 · easy

  • A.省下 O(N^2) 显存← 正确答案
  • B.训练速度提升← 正确答案
  • C.降低结果精度损失
  • D.减少分布式通信

答案:AB。中间矩阵不落地,显存和 IO 同时减少,训练更快;它不改变数值精度,也不直接减少分布式通信。

Q10. 合并两个局部 softmax 统计量 (m1, l1) 与 (m2, l2) 时,正确做法是?

单选题 · extreme

  • A.取最大值,总和用指数校正后累加← 正确答案
  • B.取平均值,总和直接相加
  • C.取最大值,总和取两数较大
  • D.取最小值,总和直接相加

答案:A。新最大值为 m=max(m1,m2),旧总和必须乘 e^(m1-m) 和 e^(m2-m) 缩放到新刻度再相加,才能得到正确的全局 softmax 分母。