为什么 Transformer 注意力要除以 √dₖ
本文从符号开始,一步步讲清楚 Scaled Dot-Product Attention 中/√dₖ的来历。重点是把每个数学符号、每个公式、每个等号的含义都说明白,不跳步。0. 先把符号约定讲清楚在看任何公式之前,先认识这些记号。后面所有推导都基于它们。符号读法含义qquery 向量一个长度为 dₖ 的向量,代表当前 token 想查询什么kkey 向量一个长度为 dₖ 的向量,代表某个 token 能提供什么dₖd-k向量的维度(分量个数)。比如 dₖ 64qᵢq 下标 i向量 q 的第 i 个分量(一个标量数字)。i 从 1 取到 dₖkᵢk 下标 i向量 k 的第 i 个分量(一个标量数字)q · kq 点乘 k点积:对应分量相乘再求和,结果是一个标量Σᵢsigma,对 i 求和把后面的式子对 i 1, 2, …, dₖ 全部加起来E[X]X 的期望expectation,见下一节详解Var(X)X 的方差variance,衡量 X 波动有多大,见后文点积写成求和形式就是:q · k q₁k₁ q₂k₂ … q_dₖ·k_dₖ Σᵢ qᵢ kᵢ也就是说,点积是 dₖ 个乘积项 qᵢkᵢ加在一起。记住这一点,后面整个分析都围绕它。1. E[ ] 到底是什么意思 —— 期望E[X]读作X 的期望(Expectation),它的意思是:如果把随机变量 X 重复采样无数次,这些值的平均值会趋向于多少。期望就是理论上的平均值 / 长期平均值。举两个直观例子:掷一个公平的六面骰子,点数 X 可能是 1~6,每个概率 1/6。E[X] 1·(1/6) 2·(1/6) … 6·(1/6) 3.5虽然你永远掷不出 3.5,但掷很多很多次,平均点数会无限接近 3.5。这个 3.5 就是期望。如果一个随机变量(总体)均值为 0,意思就是E[X] 0,即它正负波动,长期平均下来是 0。在我们的场景里,为什么 qᵢ、kᵢ 是随机变量?因为在模型刚初始化时,权重是随机生成的,所以 q、k 的每个分量 qᵢ、kᵢ 都可以看成从某个分布里随机抽出来的数。我们没法预知某一个具体的值,但可以谈论它们的统计性质(期望、方差)。这就是为什么要用E[ ]。⚠️ 重要区分:期望、总体均值、样本均值不是一回事均值这个词在中文(和英文 mean)里指两种不同的东西,务必分清,否则后面会被绕晕:名称是什么是否随机和期望的关系期望E[X]由分布定义的理论中心固定常数—— 它本身总体均值μ同上,就是E[X]的另一个叫法固定常数相等,μ E[X]样本均值x̄手里一组实际数据的算术平均(x₁…xₙ)/n随机,换批数据就变不相等,只是 E[X] 的估计两条结论:期望 总体均值,这两者确实相等(都是分布的理论中心)。样本均值 ≠ 期望。它只是期望的一个估计;由大数定律,当样本数 n → ∞ 时样本均值才收敛到期望:样本均值 x̄ ──(n 越大越接近)──→ 期望 E[X] (随机,会变) (固定的理论值)用掷骰子说明区别:E[X] 3.5是期望(总体均值)——一个理论值;而你真掷 6 次得到的平均(比如 (251634)/6)是样本均值,几乎不可能正好等于 3.5。两者是不同的东西,只是次数越多,样本均值越接近 3.5。所以本文里所有E[ ] …、所有均值为 0/方差为 1,指的都是期望(总体均值)这一支,是针对分布的理论假设,而不是说我手上这批 qᵢ 的算术平均恰好等于 0。2. 逐符号拆解E[qᵢ kᵢ] E[qᵢ] · E[kᵢ] 0 · 0 0这是你特别想搞懂的一步。我们把它拆成三个等号,一个一个看。这个式子整体在问什么?qᵢ kᵢ是两个随机数相乘,结果还是一个随机数。我们想知道:这个乘积的期望(长期平均值)是多少?也就是求E[qᵢ kᵢ]。第一个等号:E[qᵢ kᵢ] E[qᵢ] · E[kᵢ]这一步用到一条概率论的规则:如果两个随机变量 X 和 Y 相互独立,那么乘积的期望等于期望的乘积:E[X · Y] E[X] · E[Y]注意:这条规则只有在 X、Y 独立时才成立。所以原文括号里写了(因为独立)——这是在声明我们用了独立这个前提条件。独立是什么意思?指 qᵢ 取什么值,不影响 kᵢ 取什么值,反之亦然。q 来自当前 token,k 来自另一个 token,初始化时它们由不同的随机权重生成,所以假设独立是合理的。套进来:把 X 换成 qᵢ,Y 换成 kᵢ,就得到E[qᵢ kᵢ] E[qᵢ] · E[kᵢ]。第二个等号:E[qᵢ] · E[kᵢ] 0 · 0这一步用到我们的假设:q、k 的每个分量的**期望(总体均值)**都是 0。期望为 0用符号写就是:E[qᵢ] 0 且 E[kᵢ] 0(回忆上一节的区分:这里说的是期望 / 总体均值——分布的理论中心是 0,而不是某一批采样出来的 qᵢ 算术平均恰好为 0。)把这两个 0 代进去,E[qᵢ]变成 0,E[kᵢ]变成 0,于是右边就成了0 · 0。第三个等号:0 · 0 0这就是普通的算术了,0 乘 0 等于 0。合起来读这一行“乘积 qᵢkᵢ 的期望,等于(因为独立)各自期望的乘积,而各自期望都是 0(因为我们假设均值为 0),所以整个乘积的期望是 0。”直觉解释:qᵢ 和 kᵢ 各自都是围绕 0 上下波动的(有时正有时负)。它们相乘,有时得正、有时得负,长期平均下来正负抵消,平均值就是 0。3. 接着算方差:为什么点积方差 dₖ知道了均值是 0,下一步看波动有多大,也就是方差Var。Var 是什么?Var(X)衡量 X 偏离它均值的程度,波动越大方差越大。它的定义是:Var(X) E[ (X − E[X])² ] 即X 减去均值,平方,再取期望有一个常用的等价公式:Var(X) E[X²] − (E[X])²特例:当均值 E[X] 0 时,上式第二项是 0,于是:Var(X) E[X²] 均值为0时,方差就等于平方的期望这个特例后面要用。单项 qᵢkᵢ 的方差Var(qᵢ kᵢ) E[(qᵢkᵢ)²] − (E[qᵢkᵢ])² 方差的等价公式 E[qᵢ² kᵢ²] − 0² 上一节已证 E[qᵢkᵢ]0 E[qᵢ²] · E[kᵢ²] 独立,乘积期望期望乘积 Var(qᵢ) · Var(kᵢ) 均值为0,所以 E[x²]Var(x) 1 · 1 1 假设方差为1所以每一个乘积项 qᵢkᵢ 的方差都是 1。整个点积的方差点积是 dₖ 个独立项相加。独立随机变量相加时,方差可以直接相加:Var(q · k) Var(Σᵢ qᵢkᵢ) Σᵢ Var(qᵢkᵢ) dₖ × 1 dₖ结论:点积的方差是 dₖ,标准差是 √dₖ。这就是维度越大,点积数值越大的数学根源——维度 dₖ 越大,累加的项越多,波动(标准差)就按 √dₖ 增长。4. 为什么除以 √dₖ 之后方差变回 1我们要把点积的尺度拉回稳定。利用方差的一条性质:Var(a · X) a² · Var(X) 常数 a 提出来要平方令a 1/√dₖ,对点积做缩放:Var( (q·k) / √dₖ ) (1/√dₖ)² · Var(q·k) (1/dₖ) · dₖ 1这就是为什么是 √dₖ,而不是 dₖ 或别的数:因为点积的标准差是 √dₖ,除以标准差正好把方差归一化回 1。本质上这是一次标准化操作(X − μ)/σ,这里 μ 0 所以只剩除以 σ √dₖ。⭐ 关键澄清:为什么不是除以 dₖ?这是最容易卡住的地方,根源在于方差对常数是平方敏感的——即上面那条性质Var(a·X) a²·Var(X),常数a提出来时要平方。我们的目标是把方差从 dₖ 拉回 1。设缩放系数是a,要求:Var(a · q·k) a² · Var(q·k) a² · dₖ 1目标解这个方程:a² · dₖ 1 ⟹ a² 1/dₖ ⟹ a 1/√dₖ所以缩放系数必然是1/√dₖ,也就是除以 √dₖ。那如果错误地除以 dₖ(即 a 1/dₖ)会怎样?代入算一下:Var( (q·k) / dₖ ) (1/dₖ)² · dₖ (1/dₖ²) · dₖ 1/dₖ方差变成了1/dₖ,而不是 1!dₖ 越大(比如 64、128),方差被压得越小,点积分布几乎全挤到 0 附近,softmax 输出趋近均匀分布,注意力失去了区分不同位置的能力。这同样是坏的。三种情况一张表对比:缩放系数 a缩放后方差a²·dₖ结果不缩放(a 1)dₖ方差太大 → softmax 饱和、梯度消失 ❌除以 √dₖ(a 1/√dₖ)1✅ 刚好归一,softmax 尺度健康除以 dₖ(a 1/dₖ)1/dₖ方差太小 → softmax 过平、没区分度 ❌一句话记牢:方差里常数要平方,所以消掉 dₖ 倍方差需要的系数是1/√dₖ(平方后才是1/dₖ),除以 √dₖ 平方后恰好抵消 dₖ;而除以 dₖ 平方后是 1/dₖ²,把 dₖ 抵消得过头了。另一个等价直觉:方差的单位是平方量纲,标准差才和原数据同量纲。点积的标准差是 √dₖ。要把一个标准差为 √dₖ 的量标准化成标准差 1,当然是除以它的标准差√dₖ,而不是除以方差dₖ。除以方差会把量纲也除错。⭐ 再追问一步:为什么 √dₖ 写在 Var里面,而不是外面?到底在给谁做归一化?很多人会卡在这里:凭什么是Var( (q·k)/√dₖ )(√dₖ 在里面),而不是Var(q·k)/√dₖ(√dₖ 在外面)?这两种写法意思完全不同,先并排看清:写法式子读作A(正确,Transformer 实际做的)Var( (q·k)/√dₖ )先把每个点积除以 √dₖ,再看这批缩放后的数波动多大B(错误理解)Var(q·k) / √dₖ先算原始点积的方差,再把这个方差值除以 √dₖ决定 √dₖ 写在哪的,是你在归一化谁。关键:模型真正动手除的,是点积本身,不是方差。注意力公式是softmax(QKᵀ/√dₖ)——模型在前向传播里,对**每一个算出来的点积q·k(一个具体的数)**除以 √dₖ,得到缩放后的分数再喂给 softmax。被 √dₖ 操作的对象 点积这个随机变量(每个 token 对都会产生一个)。模型从来没有、也无法对方差除以 √dₖ——方差是我们事后为了分析这批分数的波动才计算的统计量,模型前向时根本不算方差。所以被归一化的对象是q·k这个随机变量本身。既然被除的是随机变量,√dₖ 就和这个随机变量绑在一起,写在Var( )的里面:Var( (q·k)/√dₖ ) └────┬────┘ 这一整个,才是我们关心的缩放后的随机变量我们想知道的是:“经过缩放后的那个分数,波动还大不大?” 既然问的是缩放后的分数的方差,√dₖ 当然要写进 Var 里、成为被考察对象的一部分。为什么写法 B(除在外面)是错的?真去算一下:Var(q·k) / √dₖ dₖ / √dₖ √dₖ ← 不等于 1,没归一化好而且给方差这个数除一下在模型前向里压根没有对应的操作,和模型实际做的事对不上,所以无意义。只有写法 A 才得到 1:Var( (q·k)/√dₖ ) (1/√dₖ)² · Var(q·k) (1/dₖ)·dₖ 1 ✓注意写法 A 里 √dₖ 被提出来时变成了平方(1/√dₖ)² 1/dₖ——正因为它本来在 Var 里面,被方差性质提到外面时才要平方;如果它本来就在外面(写法 B),就不会平方,也就抵消不掉那个 dₖ。一句话:你归一化的是点积这个随机变量(模型真正除的就是它),不是点积的方差。(q·k)/√dₖ是一个整体的、缩放后的新随机变量,我们要算的是这个新随机变量的方差,所以 √dₖ 必须写在Var( )里面;它在里面,才会在被提出来时平方成1/dₖ,从而和点积自身的方差dₖ抵消成 1。5. 为什么要假设均值 0、方差 1这是一个为了简化分析的基准假设,不是说真实数据严格满足。原因有三层:它是合理的近似。q、k 来自初始化过的线性层,配合 Xavier/He 初始化和 LayerNorm,激活值的分布本就大致是零均值、单位方差,和假设相差不大。数学上最干净。假设均值 0,推导里一堆交叉项直接消失;假设方差 1,点积方差 dₖ这个结论变得极其简洁。如果方差是 σ²,结论会变成 dₖσ²,缩放因子变成 σ√dₖ——形式一样,只是多个常数,不影响核心洞察。目的是孤立出 dₖ 的影响。我们真正关心的是尺度如何随维度 dₖ 变化。把均值、方差固定成基准值(0 和 1),dₖ 就成了唯一变量,于是 √dₖ 这个缩放因子自然浮现。6. 一句话总结我们假设q、k 是零均值、单位方差(基准坐标系),由此推导出点积方差正比于 dₖ(这就是问题),于是除以 √dₖ把方差重新归一化到 1(这就是解决方案),让 softmax 始终工作在梯度健康的尺度上,避免饱和与梯度消失。附录:延伸 —— 期望与信息熵的关系在第 1 节我们用掷骰子算了期望:E[X] 1·(1/6) 2·(1/6) … 6·(1/6) 3.5这个式子的结构和信息熵的公式很像。它们的相似不是巧合——本质上是同一类东西。两个公式并排期望(均值):E[X] Σᵢ xᵢ · p(xᵢ)信息熵:H(X) − Σᵢ p(xᵢ) · log p(xᵢ)(这里p(xᵢ)表示取值 xᵢ 出现的概率,log是对数。)两者都是Σᵢ (某个量) · p(xᵢ)的形式——对所有取值做概率加权求和。这就是它们长得像的根源。关键:熵本身就是一种期望这是最深刻的联系。先定义每个取值的自信息(惊讶程度):I(xᵢ) − log p(xᵢ)概率越小的事件,发生时越惊讶,信息量越大(−log 一个小数 一个大正数);概率越大的事件越不惊讶,信息量越小。于是熵可以写成:H(X) Σᵢ p(xᵢ) · I(xᵢ) E[ I(X) ] E[ −log p(X) ]所以:熵 自信息的期望。它和E[X]是同一个模具刻出来的,只是把被平均的量换掉了:求和的被加权对象权重整体含义期望E[X]取值本身xᵢ概率p(xᵢ)平均取到多大的数熵H(X)自信息−log p(xᵢ)概率p(xᵢ)平均有多少信息 / 不确定性把熵写成E[−log p(X)],会发现它就是把E[X]里被平均的X换成了−log p(X),形式完全一致。为什么熵多了个 log 和负号log:让信息量满足可加性。两个独立事件一起发生,概率相乘p·q,但我们希望它们的信息量相加。log 正好把乘法变加法:log(p·q) log p log q。负号:因为概率 p ≤ 1,所以log p ≤ 0(是负数或 0),加个负号让信息量变成正数,符合信息量不为负的直觉。小结期望和熵共享同一个骨架Σ (量) × 概率,区别只在于被平均的量是什么:期望平均的是取值xᵢ;熵平均的是自信息−log p(xᵢ)。所以与其说熵像期望,不如说熵本身就是一种期望:H(X) E[−log p(X)]。