阶段 3 · 处理序列

注意力:「该看哪」
这件事到底怎么算

读到「猫很累,所以它睡了」里的「它」,你会自动回头看「猫」。上一章 《Seq2Seq 与注意力》里的注意力让模型也会这样回头看, 可凭什么看这里、不看那里,没算清。这一章就从「取个平均」出发,一步步推出那行有名的公式。
第 2 节那张图可以拖:改一个词的问题,看它「看谁」的分布整个重排。

1

一个词,凭什么决定去看另一个词

上一章的注意力只有三步:打分 → softmax 归一化 → 加权求和。 三步能背下来,可一追问就卡住:分数拿什么打?为什么是点积?那个 √d 从哪来? 下面五个问题,这一章一个个答掉。①③⑤ 都能自己动手,②④ 用一张图和一笔数字讲清。

这一章回答的五个问题,各在哪一节

2

拖一个词的「问题」,看它「看谁」整个变

先放下公式。下面这句话有 6 个词,每个词身上挂着两串数字: Q(它想问的问题)和 K(它挂出来的标签)。 每个词还带着第三串数 V(它携带的内容)——小例子里先让 V = K,第 3 节讲清它从哪来。 拿一个问题去跟所有标签比一遍,谁像就看谁——就这么简单。

互动 · 真的算 QKᵀ、真的过 softmax、真的加权求和

右边那张 6×6 热力图,每一格都是现场算出来的:先做 4 次乘加得到点积, 除以 √dk,再过 softmax。每行横着加起来永远等于 1.000——那是 softmax 保证的。
操作:点左边任意一行切换「谁在提问」→ 拖下面的滑块改它的 Q → 看它的那一行热力图重排。也可以按下面那排按钮,直接把它的 Q 换成另一个词的标签。

💡 这张图里藏着这一章全部的内容

① 为什么有 Q 和 K 两串?因为「我要找什么」和「我是什么」是两件事。同一个词可以问一件事、 挂牌另一件事。
② 为什么要除以 √dk?它治的不是「你故意拖出的极端」——那种情况 softmax 本来就会让一格吃掉全部。 它治的是另一件事:维度一高,点积是 dk 个数相加,数值自己就会变大,softmax 被推成 one-hot——只有一个位置拿到权重。 第 5 节真的量给你看。
③ 那一行权重最后干什么用?它们是配比:按这个比例把每个词的 V 混起来,就是输出。 读数区最后一行那个向量,就是混出来的结果。

3

Q、K、V:拿着问题去图书馆借书

注意力最容易被讲糊涂的地方,是「为什么是三组向量,不是一组」。 用一个日常场景就清楚了——你去图书馆借书。

三个记号先说清:x 是这个位置进来时的那串数(词向量,前面章节讲过); WQ / WK / WV 是训练出来的三张表:训练时只看最后的损失(答错多少), 梯度一路传回这三张表,把有用的格子推高、没用的压低。 n 是「几个词在提问」,m 是「几个词被查」:自注意力里 m = n,翻译时 m 是原文长度。

在图书馆里在注意力里在第 2 节那张图上形状
你脑子里要问的问题 Q(query,查询):这个位置想要什么。由 W_Q · x_i 学出来 左边表里标着 Q 的那 4 个数——你拖的滑块改的就是它 n × dk
每本书书脊上的标签 K(key,键):这个位置挂出来什么。由 W_K · x_j 学出来 同一行标着 K 的那 4 个数——它是「货架」,不被拖动 m × dk
书里的内容 V(value,值):匹配上之后真正被搬走的东西。由 W_V · x_j 学出来 小例子里让 V = K(省一组数字)。真实模型里 V 是另外一组投影 m × dv
每本书的匹配度 → 借阅比例 softmax(QKᵀ):分数变成加起来等于 1 的配比 右边那张 6×6 热力图,每一行加起来 = 1.000 n × m
按比例带回家的内容 AV:把几本书的内容按比例混成一份 读数区最后那个 4 维向量 n × dv
🎯 一句话记住分工

Q 是问题,K 是书脊,V 是书的内容。
拿问题去比对书脊(Q · K),按匹配度决定借哪几本(softmax), 把借来的那几本按比例合起来(· V)。
为什么不能只有一组向量?因为「我在找什么」和「我提供什么」是两件事—— 就像书脊上的字和书里的内容不必一样。

4

一行公式,两次矩阵乘法

把第 2 节那张图上真跑的那套流程写下来,就是这一行:

它不是四条规则,是一台机器。下面这张图是它的数据流——注意每一站的形状, 这就是暗线 A(信息流动)在这一章的答案。

形状是什么那个数是怎么来的
n × dkQ,n 个位置的查询n 个词,每个投影成 dk 个数
dk × mKᵀ,m 个位置的键,转置过来转置只是为了对齐 —— 矩阵乘法要求内维相等
n × m分数矩阵 QKᵀn×m 个格子,每个是一次长度 dk 的点积。 第 8 节的 O(n²) 就是这一项
n × m注意力矩阵 A对分数矩阵逐行过 softmax,形状不变
n × dv输出A(n×m) · V(m×dv) —— 又一次矩阵乘法

整个注意力只有两次矩阵乘法和一个 softmax 第一次 QKᵀ 算「谁看谁」,softmax 把它变成配比,第二次 AV 把内容混起来。
没有循环、没有逐时刻依赖——所以 n 个位置可以同时算。 这就是 Transformer 能把 RNN 整个删掉的底气。

互动 · 一条分数从点积到「配比」的完整旅程

5

为什么非要除以 √dk

这是注意力里最容易被当成「经验技巧」带过去的一步。它其实是一个可以直接算出来的事实。

第几步算的是什么得到什么
1 点积是 dk 项相加:q·k = Σt qt kt 一个数
2 假设每个分量独立、均值 0、方差 1(初始化就是这么设计的,见初始化那一章) Var(qtkt) = 1·1 = 1
3 独立项的方差可以相加 Var(q·k) = dk ← 方差随维度线性增长
4 那把点积除以它的标准差 Var(q·k/√dk) = 1 —— 尺度被拉回和维度无关

为什么方差大是灾难?因为 softmax 对尺度极端敏感。分数一拉开, 它就把几乎全部权重压到最大的那一格上(退化成 one-hot), 于是「只有一格拿到梯度,其余全被压成 0」——梯度消失。 (为什么权重是 0、梯度就跟着是 0?softmax 的导数里乘着权重本身。) 下面这张图就是这件事的实测。

互动 · 拖 dk,看 softmax 的熵怎么塌下去

每次换维度,下面都是真的重新生成 dk 维的 q 和 6 个 k、真的做 dk 次乘加、 真的过 softmax。左图是其中一次抽样的 6 个权重,右图是 300 次抽样的平均熵。
熵量的是权重有多平均:六个位置完全均分时最大,等于 ln6 = 1.7918;全压在一格上时为 0。 熵越接近 0,权重越像 one-hot。

把 1~4 步的数字摊开

下表每一个数字都是打开这一章时现场跑 300 次抽样算出来的。 看第二列和第三列:实测方差一路跟着 dk 涨,而除以 √dk 之后,熵几乎不动。

dk实测方差(300 次)理论 dk 原始分数的极差softmax 平均熵÷√dk 后的平均熵最大权重

第二列不会和第三列完全相等。 它是 300 次抽样的估计,自己就带采样误差(每次抽样只有 6 个数,估出来的方差本身很抖)。 但趋势是铁的:方差随维度线性长,而熵只在我们除掉 √dk 之后才稳得住。

⚠️ 一个常被讲错的地方

「除以 √dk 是为了让 softmax 不至于太尖锐」——这句话对,但不够。 它准确的意思是:让分数的方差和维度无关。
这也是 Transformer 论文里的原话:小维度下点积和加性打分差不多;维度一大、又没除 √dk, 点积才明显变差(§3.2.1,引 Britz et al. 2017 的对照)。
所以它不是一个调参技巧,而是把「dk 变了,行为不该变」这条要求翻译成了数学。 这也解释了另一个现象:模型里那些「除以 √某维度」的地方(比如初始化时按维度定权重尺度)都是同一个道理。

互动 · 真抽 300 次,量一量点积的方差是不是真的等于 dk

6

同一批词,h 种不同的看法

上面那一整套,里头的 Q/K/V 都是一组投影。多头做的事只有一件: 把它做 h 遍,每一遍用另一组投影矩阵,最后把 h 份结果拼起来再线性变换一次。

先说一句免得误会:下面这 4 组投影矩阵是用固定随机数生成的,不是训练出来的, 看它们给出什么,再回来说真实模型里这些矩阵从哪来。

互动 · 4 组不同的投影,4 张完全不同的注意力图

这 4 个头看的是同一批 6 个词,用的也是同一个问题——差别只在投影矩阵。 (真实模型常用 8 个或更多头,这里只画 4 个。)
每一格都是现场算的:投影 → 点积 → ÷√dk → softmax,一步不少。
下面那四行数字是真的权重。注意最后一行:4 个头给出的答案彼此差多远。

一张图看懂:一个维度 d 怎么切成 h 个头

那么真实模型里这几张表是怎么来的?训练出来的——训练会自动把每一组推到某个有用的方向上。 训练之后,模型里也真的会分化出不同性格的头:有的盯住固定的位置,有的摊在整句上 (Clark et al. 2019《What Does BERT Look At?》在 BERT 里数到过这些模式)。 这里用固定随机数,只是为了让这一页每次打开的数字都一样, 矩阵乘法、点积、softmax 一步都没少。

这一点很关键:多头之所以有用,不是因为 8 个头各自被指派了任务(没人指派), 而是因为给模型 h 个互相独立的通道,训练就有机会让它们分工。 这正好是「没有免费午餐 → 必须有归纳偏置」的一种写法: 你不需要事先知道该看什么关系,你只需要提供足够多的「看的方式」。

为什么是拼接而不是平均 平均等于「大家一起拿主意」,谁也说不清话; 拼接(concat)是「每个人都说完,再让下一层去挑」,决定权交给后面那层可学的线性变换。 好处是参数量和计算量不随头数增加:每个头的维度取 dk = d/h, 投影矩阵总量和单头一样大——所以「8 个头」几乎不额外花钱,这是它被普遍采用的原因。

7

为什么 GPT 不许往后看

上面所有例子里,每个词都能看全部 6 个词,包括它自己右边的。 这对「理解一句话」没问题,对生成下一个词是致命的——GPT 就是这一类一个词一个词往外说的模型。

看一眼就明白的漏洞 训练时模型要预测「第 5 个词是什么」。如果第 5 个位置能直接看到第 6 个词, 那它抄答案就行——损失会飞快降到 0,但模型什么都没学会。
更糟的是,真正拿来用(推理)时第 6 个词还不存在,模型会直接崩。这就是数据泄漏。

做法粗暴但有效:把分数矩阵的上三角(j > i 的格子)设成 −∞, 过 softmax 之后它们就真的变成 0。剩下的格子会被重新归一化,所以每行仍然加起来等于 1。

互动 · 遮住上三角之后,权重去哪了

左边是掩码本身(灰色 = 被遮住,权重真的等于 0)。右边是当前这一行的真实算术: 分子哪些被丢掉、分母剩下多少、归一化之后每个权重是多少。点左边任意一行切换。

互动 · 遮住之后,这张表还剩多少格真的在干活

🎯 类比

像一个考场上不许翻后面的章的考试。你可以看已经答过的部分,不能看还没答的。 原因不是道德,是因为后面那几章在考场上根本不存在—— 训练时允许你看,考试时却没有,模型就学废了。

这个掩码让「生成」变成可能:一行一行往下算,每一行只依赖上面的行。 这也是 KV Cache(见《推理与 KV Cache》)能成立的前提。

8

O(n²) 到底是从哪冒出来的

答案在第 4 节那张形状表里已经出现了:分数矩阵是 n × m 的。 序列长度翻一倍,这张表就大四倍。这就是全部来源,没有别的。

互动 · 把 n 拖大,看这张表怎么吃掉显存

每一个数字都是现场算的:每个头一张 n×n 的表,这一层 32 个头就是 32 张; 每个头只分到 dhead = 128 维(就是第 5 节那个 dk), 32 × 128 = 4096 是这一层的总维度 D。按 FP16 存(16 位浮点,一个数 2 字节)。显存就是显卡上的内存。 右图是同一批数画在对数坐标上——虚线是「和 n 成正比」,实线是真的 n²。
注意下面那条 KV Cache 的对照:它只随 n 线性增长。

💡 记住这三个推论,后面三章都是在还这笔债

① KV Cache(那一章):既然每算一个新词都要跟前面所有位置比一遍, 那就把前面那些 K 和 V 存下来——算得省了,显存在涨。
② 高效注意力(那一章):干脆不把 n×n 那张表写出来, 分块算、融合算,把显存从 O(n²) 压到 O(n)。
③ 线性注意力(那一章):把括号挪一下, 让 n² 从乘法里消失——代价是「装不下全部原文」。

9

从「取个平均」推出那行公式

前面都是现象。这一节把公式从零推出来——全站三处完整推导之一 (另两处是 backprop 的链式法则、softmax 与交叉熵的求导)。 Transformer 里几乎所有变体(线性注意力、FlashAttention、多头、掩码)都只是在这条链的某一步上做替换。

第 0 步:我们到底想要什么

撇开术语,先问一个笨问题:「让一个词看到别的词」该输出什么? 最简单的是把整句话取平均——每个位置拿到的都是同一份东西。

这个式子是集合操作,不知道谁是谁:输入倒过来,输出完全一样。 要改的只有一件事——把永远等于 1/n 的权重,换成每个位置自己算的 w(i, j),并要求非负、每行加起来等于 1。

条件 α ≥ 0, Σα = 1 保证输出是凸组合(输入的某种平均), 不会外推到训练时从没见过的区域。到这一步,只剩一个问题:α 从哪里来。

第 1 步:α 应该是「相似度」——而且必须是内积

最自然的想法:越像就看它越多。「像」用什么量?候选有距离、余弦、内积——选内积的理由很功利:

为什么选内积说明
它是一次矩阵乘法 所有 n×m 个匹配度一次算完。GPU 最擅长的事就是它,而「逐对算距离」要写两层循环
它可以微调「像」的定义 距离是死的(欧氏距离就是欧氏距离),但内积可以先把向量投影一下再比——那就是参数
它是双线性的 对 q 和 k 都是线性的,梯度好看,也匀给两个位置各一半
代价:它没有上界 这就是第 5 节那个 √dk 的由来——余弦相似度没有这个问题,但要先把每个向量各自除以长度,多一步

一张图看懂:加性打分和乘性打分差在哪

第 2 步:为什么要把 x 投影成三个(而不是一个)

直接用 xi · xj 也有问题:它是死的,没有参数可学。 所以给每个位置先投影一下:

⚠️ 这一处几乎所有教程都讲错

常见的说法是:「一个矩阵做不到不对称,所以要拆成 Q 和 K」。这句话是错的。 xiᵀ M xj 里的 M 完全可以是不对称矩阵,它能表达任何「我→你」和「你→我」不同的关系。

真正让它们分开的,是三个工程与训练上的事实:

① V 必须独立:「拿什么去匹配」和「匹配上之后搬什么」是两件事。 连着用同一个向量,一个词就不能「广泛地匹配、精确地提供内容」——这是分开 V 的全部理由,而它是必需的。

② 拆开更省:WQᵀ WK 相当于一个秩最多 dk 的 M(秩就是「这张表最多只有 dk 个独立方向」:两张中间只有 dk 的窄表乘出来的 d×d 大表,不会有比这更多的独立方向)。 每个头只要 2·d·dk 个参数,一个完整的 M 要 d² 个;头一多,这笔账差得很远。

③ K 和 V 要被缓存、Q 不用:生成下一个词时,前面所有位置的 K/V 可以存下来重复用, Q 只算一次就丢。混在一个矩阵里,就缓存不动了(见 KV Cache)。

所以三个矩阵不是数学上的必需,它们是工程需要的形状。

第 3 步:为什么归一化必须用 softmax

现在有一串分数 sj,要变成「非负、和为 1」的权重。 三种做法听起来都合理,用同一组真实分数算一遍。

一张图看懂 · 三种归一化各算一遍,看哪一种坏了

六个位置的分数固定为 e = [2.0, 0.5, −1.0, 1.5, −0.5, 0.8] (点积本来就可正可负)。下面三种做法各算一遍、共五行,每一行都是现场算出来的。 最后两行是同一道题:把所有分数同时加上 10 再算一次。

把分数变成权重的方法六个位置的权重Σ结论

最后两行是分水岭:softmax 对「全体加一个常数」不敏感,而其他几种全变了。

一张图看懂 · 实心是原样,空心是全体加 10

exp 还藏着后面两章的根:exp(a + b) = exp(a) · exp(b)——把加法变成乘法。

所以 softmax 可以分块算:先算一块的指数和,碰到更大的分数就把这块按比例重缩放, 不用回头改前面的结果——FlashAttention 的在线归一化靠的就是它。

第 4 步:除以 √dk,以及把所有东西合起来

第 5 节已经把这个算出来了:点积的方差是 dk,除掉 √dk 之后是 1。 把四步串起来,就是那个公式:

写清楚就是两次数值:QKᵀ 得到 n×m 个分数(每个分数是长度 dk 的点积); 逐行 softmax 得到配比 A;AV 把内容按配比混起来。
回到第 2 节:你拖的每个滑块,影响的都是这套算式里的一个数。

这条推导牺牲了什么 为了好读,这条推导有三处没说满:

① 第 2 步的方差假设 q、k 各分量独立且方差为 1——初始化时的近似,真实训练会漂移。

② 「必须选内积」是动机,不是定理:有人用余弦、有人用加性(Bahdanau)、有人用 MLP 打分,都能跑。 内积赢在硬件和参数化。

③ softmax 也不是唯一答案:sparsemax、entmax 同样非负、和为 1,某些任务上更好。 对照只能说「三种最简单的候选里,softmax 最不坏」。

这么做是有意的:这三处不影响理解机器怎么转,严格版本会把它变成一篇论文—— 这就是暗线 B「什么被牺牲了」。

M

数学 · 跟着一个格子,走完那个公式

第 4 节给了那一行公式,第 9 节把它推了一遍。但它到底怎么算成一个数? 最好的办法是跟着「一个格子」走一趟。 这里换一台更小的例子:4 个词(它、很、快、。)、dk = 3—— 机器和前面几节一样是真算的,只是小到每一格都看得清。

下面这张图从 Q 的一行出发,经过点积、除以 √dk、softmax(它要偷看同一行的其他格子), 最后落到输出里的一个数。公式里出现的每个符号,图上都有它的一块。

数学节 · 一格分数是怎么算出来的

公式里每个符号,在图上都有一块 Q 的一行和 K 的一行逐项相乘再相加,就是一个分数——图里选中的那两行就是它们。
÷ √dk 是把整张分数表一起缩小,第 5 节量过为什么。
softmax 不是逐格算的:它要先把同一行的所有分数取指数加起来当分母—— 所以拖滑块时你会看到一整行一起亮,而不只是那一个格子。
V 最后按配比加权:那一行权重乘上去,才混出输出的一个数。 这个 n × dv 的输出就交给下一层继续加工(Transformer 里是前馈层)—— 这一路上还有哪些零件,下一章讲。

微型图解 · 「加权求和」到底在混什么

10

注意力不是一种方法,是一个槽位

「注意力」不是一种方法,是一个槽位:Q 从哪来、K/V 从哪来、要不要遮—— 换这三个旋钮,就得到家族里不同的成员。前面四章讲的每一样,都是这张表里的一行。

成员Q ← 从哪来 → K / V遮不遮它解决什么
加性注意力
Bahdanau 2015
Q:解码器当前状态 s
K/V:编码器每个位置 hj
不遮 第一次把 RNN 的固定长度瓶颈拆开(上一章已经看过)
乘性注意力
Luong 2015
同上,但改用点积打分不遮 同样的效果,便宜得多。它赢了,才有后面的故事
交叉注意力
cross-attention
Q:序列 X
K/V:另一个序列 Y
不遮 两个序列之间通信:翻译、语音、多模态对齐、检索增强生成(RAG)把资料拼进上下文
自注意力
self-attention
都来自同一个序列 X不遮 让每个词综合全句上下文。BERT 那一类「能看全句、不遮」的模型的主体(下一章)
因果自注意力
causal
都来自同一个序列 X遮上三角 可以逐词生成、可以并行训练。GPT 那一类模型的主体
多头
multi-head
上面任何一种,都可以横着切成 h 份并行做,再拼起来 同时提供多种「看的方式」。现代模型几乎都用
滑动窗口 / 稀疏 自己 / 上面几种看情况 只允许看附近 k 个位置或固定的几格,把 n² 变成 n·k
线性注意力 自己看情况 把 n² 整个从算式里挪走。代价是容量固定(单独一章)
FlashAttention 不是新的注意力,是把标准注意力算得更省显存(单独一章)

表里没列出来的还有两个小旋钮:dk 的大小(它决定分数尺度,所以 √dk 得跟着换,也影响单个头的表达能力) 和归一化函数(softmax 换成 sparsemax / entmax 就更稀疏;换成核函数就成了线性注意力)。

一张图看懂:注意力不是一种方法,是一个槽位

互动 · 现代模型为什么不用「每个头都有自己一套 K/V」

11

它贵在哪,什么时候会骗你

代价说明什么时候真的会痛
O(n²) 的时间和显存 n 个位置两两都要算一次。n=8192 时,单层单头就是 6700 万个分数 长上下文(> 8K)、高分辨率图像、长视频
没有天然的局部性和平移不变性 卷积免费得到「相邻像素相关」「平移后一样」,注意力要从数据里学 小数据集、低分辨率视觉任务——这也是 ViT 必须先在超大图库上预训练的原因
丢掉语序 QKᵀ 是集合运算,把输入倒过来结果不变。位置信息必须另外注入 任何语言任务。(位置编码单独一章)
推理时是带宽受限的 最贵的动作不是乘加,是把 K/V 从显存搬到芯片上。 batch 小、序列长的在线推理——KV Cache 涨得比算力快
注意力权重不是「解释」 权重高不等于原因。同一个权重可能有完全不同的作用,甚至可以被改掉而结论不变(Jain & Wallace 2019《Attention is not Explanation》换一组权重、模型照样给出同一个答案) 任何想拿热力图当证据的场合(机械可解释性就是打开网络看某个头到底在算什么,那一章专门讲)
softmax 会把差距放大成陷阱 一旦某格吃掉全部权重,其余位置的梯度就是 0——第 5 节那个图不是装饰 dk 大、初始化不当,或混合精度下数用 16 位存、能表示的范围小,分数一大就超出范围(溢出)

一张图看懂 · 倒过来念,权重一个数都没变

12

小结

这一章属于七条线里的一条——而那条线在这里第一次不是口号,是可以拖的东西。

它对应哪条线 ② 没有免费午餐 → 必须有归纳偏置—— 它把一个巨大的假设写进架构:「谁该看谁」可以从数据里学,但「看谁」这件事必须到处发生。
一句话 注意力本质上是在把「该看哪儿」从一个写死的规则,换成一组可以学的参数—— 卷积把「看邻居」写死,循环把「看上一个时刻」写死,注意力把它们都变成学出来的。
它牺牲了什么 用参数和算力去买「自由度」:O(n²) 的账单、丢掉位置感(得另加位置编码)、 丢掉卷积白送的平移不变性(小数据上直接吃亏)。
这就是暗线 B:自由度不是免费的,你只是把「假设」换成了「数据」。
🎬 自己验一遍

回到第 2 节,选中「它」那一行,按「把它的 Q 换成「很」的书脊」:它对「很」的权重从 3.5% 跳到 71.9%, 对「猫」从 46.7% 掉到 4.5%。别的词的 K 一个都没动。

那一瞬间你看到的就是「归纳偏置换自由度」:没有哪条规则说「它」该看「很」, 是训练去挑。代价是 6 个词就有 6×6 个分数要算,真模型里是 n×n 个。

它在暗线里站在哪

暗线不占任何一章,但每一章都要回答它们。

暗线这一章的回答
A 信息流动 输入 (n×d) → 三组投影 → Q(n×dk)、K(m×dk)、V(m×dv) → 分数矩阵 n×m → softmax 逐行(形状不变)→ AV → n×dv。 序列长度这一维从头走到尾,一次都没变。
B 什么被牺牲了 算力和位置先验。O(n²) 换来了「任意两位置一步直达」; 平移不变性被放弃,换来「关系由数据决定」。 并且必须先算完 QKᵀ 整张表才能做 softmax——这是 FlashAttention 要绕开的可依赖关系。
C 参数账本 三组投影:3 × d × dk × h = 3d²,再加输出投影 WO 一共 4d²,和一层 FFN(8d²)比还小。 真正的大头不是参数,是中间那张 n×n 的矩阵——第 8 节算给你看了。
D 跑在什么上 长序列上带宽受限,短序列上算力受限。 最贵的动作是把 K/V 从显存搬进芯片——一次搬运只配上很少的乘加(算术强度,就是每搬一个数能做多少次乘加,很低)。 n 小时这张表装得下,反而纯算力更快(那一章量过这个交叉点)。
E 它假设了什么 ① 「该看谁」写成一个双线性形式(打分器可以换); ② 权重非负、和为 1——是平均,不能外推; ③ dk 维分量近似独立同分布(√dk 靠这一条); ④ 没有位置信息,顺序必须由外面注入。
F 违背了哪个直觉 「越相似越该多看」是错的。第 2 节里「它」看自己最多的地方是 另一个词——注意力问的是「我需要的」,不是「我像的」。 而 Q≠K 的全部意义就在这里:提问的方向和自身的坐标可以是两回事。
🎯 前后钩子

它接住了上一章的什么:《Seq2Seq 与注意力》给出了 「打分 → 归一化 → 加权求和」三步,但没回答「分怎么打」。这一章把每一步都推到了底。

它给下一章留了什么:现在你有了注意力这一个零件。 但一个零件不等于一栋楼——残差怎么接、LayerNorm 放哪、FFN 那三分之二的参数干什么、 三种拓扑(BERT / GPT / T5)差在哪?这些都是 《Transformer 自注意力》的事。

一句话带走注意力

注意力就是把「加权平均」里的权重,从写死的 1/n 换成学出来的 softmax(QKᵀ/√dk)。
Q 是问题、K 是书脊、V 是内容:拿问题比书脊,按匹配度借哪几本,把内容按比例合起来。
除以 √dk 不是调参技巧——点积的方差等于 dk,不除掉 softmax 就会退化成 one-hot,梯度直接消失。
多头是给模型 h 个独立的「看的方式」,几乎不额外花参数; 因果掩码是让模型不许抄答案,也是生成模型成立的前提。
所以呢:你以后看到的注意力变体,都在这条链的某一步上动刀—— 线性注意力动的是 softmax 的形状,FlashAttention 动的是算的顺序,多头动的是投影的数量。 这一章的推导就是那把尺子——下一章 《Transformer 自注意力》拿它搭楼。

13

拓展阅读

上面讲的都是「够用」的版本。想往下挖,这里有三个入口—— 它们不是必修内容,是给想再往前走一步的读者准备的。

📄 这一章的说法从哪来

💻 工业界怎么写

∑ 更严格的形式