注意力一定要「看点什么」吗?
本课一问:注意力一定要「看点什么」吗?
这是挂在第 7 课(多头)旁边的岔路。这一课先不碰:门控注意力的完整结构(C4)。
从已有出发
第 3 课的 softmax 有一条性质:每一行的权重之和恰为 1。第 7 课又把注意力切成了很多头,每个头各有自己的 100% 要分。问题来了:如果某个头这一次根本没有要找的东西呢?比如一个专门找「上一次出现的同一个词」的头,在一个没有重复词的位置上,它该看哪?
先自己设计:什么也不改
- ① 朴素方案
- ② 它在哪失败
- ③ 改进方案
softmax 只看分差(第 3 课)。所以「所有候选都很不相关」和「所有候选都很相关」对它来说是一回事:只要分差一样,权重就一样,输出就是这些 V 的一个平均——不管这个平均有没有意义。
给分母加一项 ez′:sj = ezj ÷ (Σk ezk + ez′)。z′ 每个头一个、可学习,它不对应任何 token、也没有 V。它分走的那部分注意力等于「这次不取」,真实 token 的权重之和可以小于 1,甚至接近 0。
试三件事:① 默认选的是「最平」的一行,把「整行分数一起减」拖到 10,确认权重不动;② 勾上 sink logit,把 z′ 从 −6 拖到 6,看真实 token 的权重之和从接近 100% 掉到很小,输出向量随之变短;③ 换一个有明确目标的提问者(比如「给了」),同样的 z′ 分走的份额小得多——分走多少,取决于这一行最高分和 z′ 的差。
大模型里真实发生了什么:把注意力倒在第一个 token 上
标准 softmax 没有「空位」,模型只能自己找一个。研究者在大模型里反复观察到同一个现象:很多头会把大量注意力放在序列最开头的 token 上,即使那个 token 在语义上并不重要——StreamingLLM 论文把它命名为 attention sink 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条原文:strong attention scores towards initial tokens as a sink even if they are not semantically important。观察来自对 Llama-2 等模型的分析 出处Xiao et al. 2023(StreamingLLM) ↗需联网 。
为什么偏偏是第一个?回想第 4 课的因果掩码:第一个 token 是唯一一个所有位置都看得见的 token。任何一行想把「用不掉的注意力」安放到一个固定的地方,它是唯一的共同选项;如果它的 V 被训练得很小,倒在它身上就近似于「什么都不取」 证据等级 · 有理论动机 有数学或机制上的理由说明它可能有效,但没有证明它一定更好。最后是否采用,仍然要看实验。 本条解释性的机制论证,与 StreamingLLM 的解释一致,但不是证明 出处待补 。
这个现象有实际后果。StreamingLLM 发现,用滑动窗口只保留最近的 KV 时,一旦把开头几个 token 挤出窗口,模型就崩了;把开头几个 token 的 KV 一直留着,性能基本恢复,可以流式处理到 400 万 token,比「滑窗重算」快最多 22.2 倍 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条原文:keeping the KV of initial tokens will largely recover the performance of window attention;up to 4 million tokens;up to 22.2x speedup 出处Xiao et al. 2023 摘要 ↗需联网 。他们还发现,预训练时专门加一个占位 token 当 sink,流式部署效果更好。
正式给它一个出口
与其让模型「借用」第一个 token,不如直接给一个出口。2025–2026 年的做法有两类:
- sink logit:就是上面组件里的做法。DeepSeek-V4 在压缩注意力的核心里为每个头设一个可学习的 z′,加进 softmax 的分母,报告明说它让每个头的注意力总和可以不等于 1、甚至接近 0;报告引用的出处是 OpenAI(2025)与 StreamingLLM 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条设计选择;报告没有单独给出去掉它的消融数字 出处DeepSeek-V4 技术报告 §2.3.3 式 (27) ↗ 。
- 输出门:在注意力输出上再乘一个由当前 token 算出的 sigmoid 门,门关上,这个头的输出就接近 0,不必靠把注意力倒在某处来「不取」。Qwen 团队的 Gated Attention 论文报告这种门控能缓解 attention sink 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条原文用词是 mitigates(缓解),不是消除 出处Qiu et al. 2025(Gated Attention) ↗需联网 。锚点 Qwen3.8 就开着它:config 里
attn_output_gate= true,q_proj 的输出宽度因此翻倍,多出来的一半就是门。门的完整结构在 C4 讲。
真模型:我们自己的模型里有没有 sink
下面是我们从 0 训练的小模型在验证集长文本上的统计:每个头平均把多少注意力放在第一个 token 上,橙色虚线是「均匀地看所有可见 token」时第一个 token 应得的份额。高出基线很多的头,才算有 sink 的迹象;结论由组件对数据现算。
⚠ 常见误解
「第一个 token 被大量关注,说明它最重要。」恰恰相反:它被关注,常常是因为「没东西可看」时注意力总得有个去处,而它是唯一所有位置都看得见的 token。StreamingLLM 的原话就是「即使语义上不重要」。看注意力图时,第一列很亮不等于模型在读第一个词。
注意力的演进,你在这里
① 训练时:一个 token 怎么从别的 token 那里取信息
- 解决了能读任意长的序列,参数与长度无关;手里只带一个固定大小的状态 h。卡在ht 要等 ht−1 算完:T = 4,096 时每层 4,096 步不能并行,第 1 个 token 的信息要经过 4,095 次更新才到最后;翻译时整句还得挤进一个定长向量——Bahdanau 2014 说的瓶颈。展开岔路 B1
- 解决了解码器每一步回头给源句的每个位置打分、加权取回,不再只靠那一个定长向量:score = vT·tanh(W1q + W2k)。卡在每一对都要单独过 tanh,交不给矩阵乘单元;朴素实现要先落一个 T×T×da 的中间张量:T = 4,096、da = 256 时单头单层 8.0 GiB(BF16),点积只留 T×T 个分数,32 MiB。它还长在 RNN 翻译模型里,串行没解决。展开第 2 课
- 解决了直接比 embedding 时「给了」最像的是它自己(余弦 1.000),小明、苹果、小王排在最后;投影成 Q、K 再点积,它自己排到最后、前三名是苹果、小王、小明,全部配对一次矩阵乘 QKT;取回用单独的 V——两个人名的 K 余弦 0.995,取回 K 分不清是谁。卡在不缩放:锚点每头 256 维,点积标准差 √256 = 16,同一行分差十几二十是常态(e20 ≈ 4.9 亿),softmax 几乎独占,梯度传不回 WQ、WK。
- 解决了softmax 把分数变成正的、和为 1 的权重,只看分差(按占比分,对话样本的 10、3、−4 会给「汽车」−44.4%);除以 √dk = 16,点积方差回到 1。卡在训练时整句一次喂进去:不加掩码,「给了」一行有 32.5% 的注意力直接落在它要预测的答案「小王」上,loss 低得虚假。展开第 3 课
- 解决了旋转后 q·k 只依赖距离 j − i;V 不参与打分,不转(转了会把绝对位置混进取回的内容)。锚点每头 256 维里只转 64 维。卡在旋转矩阵随位置变,夹在展开矩阵和缓存之间就没法事先并进 Q:MLA 因此把 RoPE 单独拆出 64 维另存(DeepSeek-V2 config,第 10 课)。
- 解决了标准 softmax 逼每行分完 100%:「苹果」一行 3 个分数只差零点几(0.04、0.36、0.00),照样分成 30% / 41% / 29%;分母加可学习的 sink logit,或在输出上乘门,这个头就能「这次不取」——锚点开着输出门(attn_output_gate = true)。卡在出口的效果只有实验证据:Gated Attention 原文说门控「缓解」sink,不是消除;DeepSeek-V4 没给 sink logit 的单独消融。展开岔路 B4
② 生成时:K、V 怎么越存越少
- 解决了缓存直接除以头数:锚点形状下每 token 16 KiB,262,144 上下文 4 GiB。卡在质量会掉、训练可能不稳:GQA 论文表 1(T5-XXL,七个任务平均)MHA 47.2 → MQA 46.6。展开第 9 课
- 解决了24 个 Q 头分 4 组、每组 6 个共用 1 个 KV 头(组数 = KV 头数):每 token 64 KiB、262,144 上下文 16 GiB;T5-XXL 上 GQA-8 平均 47.1、推理 0.28 s,质量接近 MHA(47.2、1.51 s),速度接近 MQA(0.24 s)。卡在再减 KV 头就回到 MQA:DeepSeek LLM 67B 已是 GQA-8,每 token 仍要 389,120 B(每头一份的 MHA 是 3,112,960 B),1M token 单条请求 380 GiB。展开第 9 课
- 解决了不存 K、V,每层每 token 只存 512 维潜向量 + 64 维 RoPE = 576 个数,用时再展开:DeepSeek-V2(60 层)每 token 69,120 B、V3(61 层)70,272 B;相对 67B 按 BF16 降 82.2%,官方「−93.3%」还含约 6 bit 的 KV 量化。卡在仍随长度线性增长,打分仍是 T²:GLM-5.3 同是 576 个数、78 层,每 token 89,856 B,原生 1,048,576 上下文时单条请求只算潜向量就要 87.75 GiB。展开第 10 课
- 解决了换掉「按长度存」本身:锚点 64 层里 48 层不存 KV,只存固定大小的状态(FP32 共 144 MiB),与上下文长度无关(这些层是什么、怎么更新,C11 第 4 课揭晓);DeepSeek-V4.1 叠加压缩、稀疏与低精度,官方报告全局 KV 890 B/token。卡在固定状态装不下任意多对键值,锚点仍留 16 层全注意力;稀疏注意力每步只读挑出来的一部分,挑本身也有代价——各自省了什么、没省什么,C11 讲。
证据三问
- 它解决什么问题?让一个头在「这次没东西要取」时有正当的出路,而不是被 softmax 逼着取回一个无意义的平均。
- 数学上为什么可能有效?标准 softmax 权重和恒为 1,这一点可证明 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条第 3 课 出处待补 ;分母加 ez′ 后真实 token 的权重和 = 1 − sink 份额,可以任意接近 0 证据等级 · 数学可证明 在写明的前提下可以严格推导出来,不依赖实验。只要前提成立,换数据、换规模仍然成立。 本条组件里现算 出处待补 。
- 实验上呢?sink 现象、保留开头 token 的收益、门控的缓解作用,都来自对具体模型的实验 证据等级 · 实验验证 由对比实验得出的经验结论,只在出处写明的模型、数据和规模下成立。换了条件可能不再成立,引用时要带上实验设置。 本条见上文各条出处 出处StreamingLLM 等 ↗需联网 。
一句话
softmax 的权重和必须是 1:没东西可看时注意力也得有个去处,所有位置都看得见的第一个 token 就成了这个去处;sink logit 和输出门给它一个正式的出口。
回到主线
岔路到此。主线接着往下:生成时,每一步都要重算前面所有 token 的 K、V 吗?→ 第 8 课。另一条岔路:为什么不用 RNN?
你可能会问
这一课来自学习问题链里的常见疑问,还没有真实提问记录;你的提问会记到 05-问答记录/C3-B4.md。