为什么 Self-Attention 要除以根号 dk?

为什么 Self-Attention 要除以根号 dk?
上篇我们搞清楚了 Q、K、V 各自代表什么意思。Q 是你脑海中的问题,K 是每本书的目录标签,V 是书里的具体内容。
但知道了它们是什么,下一个问题就来了:Q 和 K 到底怎么"匹配"的?为什么匹配完之后还要除以一个奇怪的根号 dk?
这个问题的答案,藏着 Transformer 能训练成功的秘密。
Self-Attention 在算什么?
先来回顾一下 Q、K、V 是怎么配合工作的。
整个流程是这样的:先用你的问题 Q,去和所有的 Key 做比较,看看哪个 Key 最匹配你的问题。匹配度越高,权重就越大。最后根据这些权重,从 Value 里取出对应的信息。
类比一下,就像你在图书馆找书。你脑子里有个模糊的搜索词(Q),你去书架上扫一眼每本书的书脊标签(K),发现有两本书的标签特别匹配你的需求。你就重点看这两本书(V),其他书暂时忽略。
这个"匹配程度"是怎么算出来的?
答案是一个简单的操作:点积(dot-product)。
简单说就是把两个向量对应位置的数字相乘,然后加起来。点积越大,两个向量越"相似"。
但问题来了:点积的结果会随着向量维度变大而变大。这听起来是个小问题,但真正计算的时候,它会变成灾难。
点积为什么会"爆炸"?
先来做个思想实验。
你抛两枚硬币,数一数正面出现了几个。这个数字大概在 0 到 2 之间,差距不会太大。
但如果你抛 512 枚硬币呢?正面数量可能在 200 到 350 之间波动,差距就非常悬殊了。
点积也是同样的道理。
假设 Q 和 K 都是标准化的向量(均值 0,方差 1)。当你计算 Q · K^T 时,相当于把对应位置的数字相乘再加总。
如果维度 dk 只有 64,点积结果的方差大概是 64。换句话说,数值范围还算可控。
但如果 dk 是 512,点积结果的方差就变成了 512。数值范围一下子大了 8 倍!
这意味着什么?有的点积结果可能是几十,有的可能是几百甚至更大。差距变得非常悬殊。

你可能觉得"数值大一点有什么关系?"
关系大了。这个问题会在下一步暴露出来。
softmax 遇到极端值会怎样?
算完点积之后,Self-Attention 会做一个 softmax,把这些分数变成概率分布。
softmax 的公式长这样:
softmax(x_i) = e^{x_i} / Σe^{x_j}
说人话就是:把每个数取 e 的指数次方,然后除以所有指数的和。
这样输出的就是个概率分布,所有值加起来等于 1。
问题来了:当输入值的差距很大时,softmax 会"赢家通吃"。
举个例子你就明白了。
假设考试满分 100 分:
- 场景 A:分数是 60、65、70 → softmax 后大概是 0.25、0.30、0.35,差距不大
- 场景 B:分数是 1、2、100 → softmax 后大概是 0.00、0.00、1.00,几乎只有一个生效
在场景 B 里,100 分那个同学拿走了几乎所有"注意力",其他人的分数被完全忽略了。
这就是 softmax 在 Self-Attention 里干的事。当点积结果变得很大很悬殊时,softmax 的输出会变成一种"一个很强、其他全是零"的极端分布。
这时候会发生什么?
反向传播的时候,梯度会变得极其小。模型几乎学不动,就像在一条几乎平坦的马路上开车,方向盘怎么打车子都不转弯。
这就是传说中的梯度消失。

根号 dk 是怎么来的?
好,现在问题清楚了:点积结果太大 → softmax 输出太极端 → 梯度消失 → 模型训练不动。
解决方案是什么?
很简单:在 softmax 之前,把点积结果缩小一点。
怎么缩?除以根号 dk。
为什么偏偏是根号 dk?
让我们来算一笔账。
假设 Q 和 K 都是标准化过的向量,每一维的均值接近 0,方差接近 1。
两个独立的这样分布的向量做点积,结果的方差就等于 dk。
所以 Q · K^T 的标准差是 √dk。
为了让这个标准差恢复到 1(和输入保持一致),我们需要除以 √dk。
1 / √dk × √dk = 1
这就是根号 dk 的数学来源。
不是拍脑袋选的,是唯一正确的选择。
除以其他常数要么缩得不够(还是会有极端值),要么缩得太过(softmax 输出又变得太平均,丢失了区分度)。

打个比方:你的气球吹得有点过了,现在需要放掉一些气。√dk 就是刚好能把气球放回正常大小的那一口气。
多了会瘪,少了还是会爆。
不除会怎样?
来对比一下实际效果。
假设 dk = 512,某个位置的点积结果是 20,其他位置平均是 5。
不做缩放:softmax(20) ≈ 1,其他都是 0。注意力全在一个位置。
做缩放:除以 √512 ≈ 22.6,点积结果变成 20/22.6 ≈ 0.89,5/22.6 ≈ 0.22。
softmax(0.89) ≈ 0.71,softmax(0.22) ≈ 0.29。注意力分散开了,虽然有侧重但不会只有一个选手。
dk 较小时(64 左右),除不除 √dk 差别不大。
因为即使不除,数值范围也大不到哪里去。softmax 不会完全失控。
但 dk 很大时,这个缩放就是救命的设计。
512 维、768 维、1024 维...现代 Transformer 用的是大维度,不用缩放几乎不可能训练成功。
这就是为什么 Transformer 固定用 dk = 512,并且配套使用 √dk 缩放。
这不是巧合,而是经验证有效的工程选择。

面试怎么答?
我面试了不少候选人,发现能把这个点讲清楚的不多。大部分人只会背"防止梯度消失",再追问就卡壳了。所以如果能把这个原理讲清楚,面试官对你的印象会好很多。
先把核心逻辑说清楚:
"点积值会随 dk 增大而变大,导致 softmax 梯度消失。除以 √dk 可以把方差缩放到合理范围。"
如果想拿高分,可以补充数学推导:
"假设 Q、K 是均值为 0、方差为 1 的向量,它们点积的方差等于 dk。要让点积结果的方差恢复到 1,需要除以 √dk。这样 softmax 的输入不会落入极端区域,梯度保持正常。"
再往深了想,可以提一个延伸问题:
"√dk 是让点积方差恢复为 1 的数学解。但为什么原论文选这个而不是其他常数?可能因为它最自然、最简洁。当然,理论上任何能让方差保持稳定的缩放都可以,这方面学术界也还在探索。"
回答问题就像讲故事,从"是什么"到"为什么"再到"还能想什么",一层层递进,面试官听着也舒服。
还有一个细节
等等,还有一点值得提。
我们一直在说 Q 和 K 是标准化过的向量。但实际计算中,它们真的是标准化的吗?
在原始 Transformer 论文里,Q、K、V 都是通过输入 embedding 乘以权重矩阵得到的。这些权重矩阵是随机初始化的,并没有刻意保证 Q 和 K 的方差为 1。
所以严格来说,√dk 的推导依赖一个假设:"Q、K 的各分量是独立同分布的,均值为 0,方差为 1"。
这个假设在训练初期不一定成立,但在足够多的数据和随机初始化下,统计上会趋向这个分布。
这也是为什么 √dk 被称为"缩放因子"而不是"精确归一化"——它更像是一个经验性的调优,让点积结果不会太大。
每次想到这里,我都会感慨深度学习的很多设计,既有理论支撑,也有工程直觉。√dk 就是两者的结合体——不是纯粹的理论推导,也不是盲目的调参碰运气,而是两者配合出来的结果。

下次再被问到这个问题,你可以自信地从点积方差讲到梯度消失,再讲到缩放的数学直觉。
如果面试官继续追问"那如果维度更大怎么办"或者"有没有更好的缩放因子"——
恭喜你,你们可以继续聊下去了。
因为这个问题,学术界也还在探索。
下篇我们就来聊聊 Multi-Head Attention,看看它是怎么进一步优化 Self-Attention 这个机制的。
