想象你走进一座藏书百万的图书馆,心里揣着一个问题:“我想学做手冲咖啡。”一个聪明的图书管理员,要在几毫秒之内从书架上挑出最相关的几本书,再综合它们的智慧,给你一个精准的回答。他是怎么做到的?他并不逐本翻书——那太慢了。他先把你的疑问抄在一张“查询卡”上,再让每本书的“标签卡”和它做一次快速匹配:相似度高的书获得更多关注,最终所有书的内容按关注比例混合成答案。这套机关就是缩放点积注意力,由“查询(Q)—键(K)—值(V)”三张卡片、一次点积匹配、一个音量旋钮(缩放因子)和一次加权拌和组成。今天所有大语言模型的心脏,都是这个看似简单的机制。接下来,我们把它一步步拆开。

岗位关联

缩放点积是 Transformer 中最底层的“原子操作”。理解它,你才能读懂注意力可视化、排查训练中的梯度异常,并在设计新模型时知其所以然——它是每一位 NLP/AI 工程师的必修地基。

目录
  1. 可视化演示
  2. 查询键值三要素
  3. 点积相似度
  4. 缩放因子
  5. Softmax 归一化
  6. 加权求和输出
  7. 并行计算优势
  8. 工业级应用
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

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

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

查询键值三要素

老馆长递给小林三张颜色不同的卡片,说:“记住咱们图书馆的规矩。读者走进来,心里那个问题要抄在蓝色卡片上,这叫查询卡(Q);每本书的书脊上都贴着一张绿色标签卡(K),写着书讲什么;至于书里真正的内容,我们抄在黄色卡上,叫值卡(V)。你要做的,就是拿着蓝卡,去和几万张绿卡一一比对。”小林恍然大悟:原来“找书”这件事,被拆成了三个各司其职的角色。

在注意力机制里,这个比喻完全成立。Transformer 处理一个句子时,每个词的位置都拥有一个原始向量表示 X。但同一个 X 不能既当“提问者”又当“应答者”——于是模型准备了三个可学习的投影矩阵,把 X 分别映射成三种角色向量:Q 代表“我在找什么”,K 代表“我身上挂着什么标签”,V 代表“我真正要贡献的内容”。这样,句子里的每个词既能主动询问别人,也能被动地被别人询问。

走出馆长办公室,小林把三张卡片挂在胸前:蓝色 Q 是“我想了解什么”,绿色 K 是“我介绍了什么”,黄色 V 是“我实际能讲什么”。三张卡片同出一源,却各司其职——这正是自注意力最精妙的设计:让信息自己组织起“提问—匹配—回答”的完整流程。

Q=XWQ,K=XWK,V=XWV\displaystyle Q = XW^{Q}, \quad K = XW^{K}, \quad V = XW^{V}
一句话:用三个不同的“滤镜”看同一份输入,得到三种分工不同的向量,注意力才有戏可唱。
  1. 输入矩阵 X把一句话的所有词向量按顺序叠成一个矩阵,每一行是一个词的原始表示。
    X∈Rn×dmodelX \in \mathbb{R}^{n \times d_{\text{model}}}
  2. 投影矩阵 W三个可学习的参数矩阵,训练过程中由梯度下降不断调整,相当于三个“滤镜”。
    WQ,WK,WV∈Rdmodel×dkW^{Q}, W^{K}, W^{V} \in \mathbb{R}^{d_{\text{model}} \times d_{k}}
  3. 矩阵乘法X 与每个 W 相乘,本质是对每一行做一次线性变换,把词向量“旋转并拉伸”到新的语义空间。
    Q=XWQQ = XW^{Q}
  4. 角色分工Q 用于提问,K 用于被匹配,V 用于输出内容,三者缺一不可。
    Q,K,V∈Rn×dkQ, K, V \in \mathbb{R}^{n \times d_{k}}

点积相似度

现在,小林站在书架前,手里捏着蓝色的查询卡。他该怎么快速判断“这本书是否相关”?老馆长教他一个绝招:把查询卡和标签卡都当成一串数字组成的向量,然后“逐位相乘、全部相加”。比如查询卡写“咖啡、手冲、器具”,标签卡写“咖啡、手冲、文化”,逐位相乘再求和,得数就很高;若标签卡写“量子、物理、粒子”,得数就低。这个操作,数学上叫点积(内积),它测的就是两个向量“方向有多一致”。

在公式里,第 i 个位置的查询向量 q_i 与第 j 个位置的键向量 k_j 的点积写作:

这个 s_ij 就是“查询 i 对键 j 的原始关注分数”。它有两个直观性质:一是方向越一致(夹角越小),分数越大;二是模长也会放大分数——一个“嗓门大”的向量即使方向一般,也能拿到高分。在注意力里,这两点都承载着语义信息,所以不需要额外归一化模长。维度上,q_i 和 k_j 必须长度相同(都是 d_k),否则无法逐位相乘——这就是“维度约束”。

小林试了一下午,发现“点积”就像给每一对“问题—标签”打一个亲切度积分,一分定亲疏。但他也发现一个隐患:当标签卡上写满密密麻麻的数字(维度 dk 很大)时,积分经常爆表——这就要靠下一个机关来解决。

sij=qi⋅kj=∑l=1dkqi,l kj,l\displaystyle s_{ij} = \mathbf{q}_i \cdot \mathbf{k}_j = \sum_{l=1}^{d_k} q_{i,l} \, k_{j,l}
点积衡量的是“方向相似度 × 信号强度”的混合体:夹角小、模长大,分数就高。
  1. 两个向量q_i 是第 i 个位置的查询,k_j 是第 j 个位置的键,维度都是 d_k。
    qi,kj∈Rdk\mathbf{q}_i, \mathbf{k}_j \in \mathbb{R}^{d_k}
  2. 逐分量相乘把两个向量同一位置的分量一对一对相乘,得到 d_k 个乘积项。
    qi,1kj,1,  qi,2kj,2,  …,  qi,dkkj,dkq_{i,1}k_{j,1}, \; q_{i,2}k_{j,2}, \; \ldots, \; q_{i,d_k}k_{j,d_k}
  3. 全部相加把这 d_k 个乘积项加起来,得到一个标量分数。
    sij=∑l=1dkqi,lkj,ls_{ij} = \sum_{l=1}^{d_k} q_{i,l} k_{j,l}
  4. 相似度语义几何上点积等于模长之积乘以夹角余弦,夹角越小、模长越大,分数越高。
    qi⋅kj=∥qi∥∥kj∥cos⁡θ\mathbf{q}_i \cdot \mathbf{k}_j = \| \mathbf{q}_i \| \| \mathbf{k}_j \| \cos \theta

缩放因子

小林发现,书架上有些“大嗓门”的书,标签卡上的数字又大又密,跟谁的查询卡配对都能拿高分,把真正相关的书全挤下去了。老馆长悠悠地掏出一个旋钮:“这就是你要学的下一课——缩放因子。分数高了别急着用,先除以一个跟标签长度挂钩的常数,把音量调回正常水平。”

为什么点积分会随维度 dk 变大?假设 q 和 k 的每个分量都是均值 0、方差 1 的随机变量,那么点积是 dk 个独立乘积之和,方差会叠加成 dk。dk 越大,分数分布越分散,有些分数会冲到很大。而 softmax 对超大输入极其敏感:分数差距一拉大,输出就会迅速偏向 1 和 0 的两极,梯度趋近于零,模型几乎学不动——这就是经典的梯度消失问题。解决办法很朴素:除以根号 dk,让方差回到 1:

小林把这个旋钮拧到“根号 dk”的位置,果然,分数不再疯狂爆表,softmax 也有了正常工作的余地。他暗自记下:这一步看似简单,却是整个机制能稳定训练、模型能真正学进去的定海神针。

sij′=qi⋅kjdk,Var⁡(sij′)≈1\displaystyle s'_{ij} = \frac{\mathbf{q}_i \cdot \mathbf{k}_j}{\sqrt{d_k}}, \qquad \operatorname{Var}(s'_{ij}) \approx 1
缩放不是把分数压到 0~1(那是 softmax 的活),而是控制方差,让 softmax 输入端保持在梯度友好的范围。
  1. 点积方差当各分量独立且方差为 1 时,dk 个独立乘积的方差相加,总方差等于 dk。
    Var⁡(qi⋅kj)=∑l=1dkVar⁡(qi,lkj,l)=dk\operatorname{Var}(\mathbf{q}_i \cdot \mathbf{k}_j) = \sum_{l=1}^{d_k} \operatorname{Var}(q_{i,l} k_{j,l}) = d_k
  2. 除以根号 dk方差是平方量级,所以除以根号 dk 后,方差正好回到 1。
    Var⁡ ⁣(qi⋅kjdk)=dkdk=1\operatorname{Var}\!\left(\frac{\mathbf{q}_i \cdot \mathbf{k}_j}{\sqrt{d_k}}\right) = \frac{d_k}{d_k} = 1
  3. 梯度保护softmax 输入极大时输出趋近 0 或 1、导数趋近 0;方差回 1 后梯度不再枯竭。
    ∂softmax⁡(x)∂x≈0当 x 极大或极小时\frac{\partial \operatorname{softmax}(x)}{\partial x} \approx 0 \quad \text{当 } x \text{ 极大或极小时}

Softmax 归一化

分数调平了,但还不是“注意力”——因为分数想加就加,小林没法决定“到底该花多少精力读哪本书”。老馆长又递来一个工具:softmax。它像一场“注意力拍卖会”:把每个候选书的分数放进指数放大器里,谁的分数高,谁的音量就指数级放大;然后再统一换算成百分比,保证所有占比加起来正好是 100%。

softmax 把第 i 个查询对所有键的分数变成一组非负且和为 1 的权重:

这里的 α_ij 就是“第 i 个位置应该放多少注意力在第 j 个位置上”。指数函数 exp 放大了分数差异:分数稍高的一方会获得不成比例的更多权重,形成“赢者通吃”式的峰值竞争;同时所有权重落在 (0,1) 区间、总和恒为 1,天然就是一个概率分布,方便后续做加权平均。

拍卖会结束,小林手里攥着一沓“注意力份额券”,每张券上都写着某个候选位置和对应的百分比。他明白,接下来要做的事情只有一个:按比例把这些书的内容拌在一起。

αij=exp⁡(sij′)∑l=1nexp⁡(sil′)\displaystyle \alpha_{ij} = \frac{\exp\left(s'_{ij}\right)}{\displaystyle \sum_{l=1}^{n} \exp\left(s'_{il}\right)}
softmax 相当于把“原始分数”翻译成“注意力预算”:预算总量固定为 1,强者多分、弱者少分。
  1. 指数化对每个缩放后的分数取 exp,把负数变成正数,并放大分数之间的差距。
    exp⁡(sij′)\exp(s'_{ij})
  2. 分母归一把所有候选键的指数值相加,作为本次拍卖的总预算。
    ∑l=1nexp⁡(sil′)\sum_{l=1}^{n} \exp(s'_{il})
  3. 相除得到权重每个指数值除以总预算,得到 (0,1) 之间的权重。
    αij=exp⁡(sij′)∑l=1nexp⁡(sil′)\alpha_{ij} = \frac{\exp(s'_{ij})}{\sum_{l=1}^{n} \exp(s'_{il})}
  4. 和为 1所有 α_ij 加起来正好等于 1,构成一个合法的概率分布。
    ∑j=1nαij=1\sum_{j=1}^{n} \alpha_{ij} = 1

加权求和输出

“你已经拿到了对全场每个位置的注意力份额券,”老馆长说,“最后一关,是带着这些份额去领书,然后把书里的内容按份额比例倒进同一个桶里,搅匀。这个桶里的东西,就是你对读者问题的最终回答。”小林眨眨眼:“所以每个位置的输出,其实是所有书内容的加权混合?”“正是,而且混合的比例,是由查询和键的匹配决定的。”

这一步的公式非常简洁:第 i 个位置的输出,等于所有位置的值向量 v_j 乘以对应注意力权重 α_ij 后求和:

把 n 个位置的输出叠在一起,就得到与输入形状完全一致的输出矩阵——这意味着自注意力层不改变序列的长度和维度,可以无缝堆叠成深层网络。更重要的是,每个输出向量都“看过了”整个序列:它按语义相关性吸收了全局信息,这正是“上下文表征”的含义。这套“先加权、再求和”的模式也是多头注意力的地基:把 Q、K、V 各投影成 h 组,并行做 h 次缩放点积注意力,再从多个子空间拼接结果,让模型同时捕捉不同角度的关系。

小林把份额券一张张投进桶里,最后捞出来的“答案向量”既有查询词自己的信息,也融合了所有相关词的精华——每一个词都变成了一个“带着全场记忆的词”。但新的问题来了:图书馆这么大,给几百位读者拌几百份答案,得拌到什么时候?老馆长笑了:这正是下一课要解决的——何必排队?

Output⁡i=∑j=1nαij vj\displaystyle \operatorname{Output}_i = \sum_{j=1}^{n} \alpha_{ij} \, \mathbf{v}_j
输出的关键不在公式本身,而在它的属性:形状不变、携带全局上下文、可堆叠、可多头并行。
  1. 权重乘以值每个值向量按对应注意力权重缩放,权重越大贡献越大。
    αij vj\alpha_{ij} \, \mathbf{v}_j
  2. 对所有位置求和把 n 个缩放后的值向量加总,得到单一的输出向量。
    ∑j=1nαijvj\sum_{j=1}^{n} \alpha_{ij} \mathbf{v}_j
  3. 输出形状不变每个位置都得到一个 d_k 维向量,整体仍是 n × d_k。
    Output⁡=(Output⁡1,…,Output⁡n)\operatorname{Output} = (\operatorname{Output}_1, \ldots, \operatorname{Output}_n)
  4. 多头扩展h 组注意力头的结果拼接后线性投影,得到最终输出。
    MultiHead⁡=Concat⁡(head⁡1,…,head⁡h)WO\operatorname{MultiHead} = \operatorname{Concat}(\operatorname{head}_1, \ldots, \operatorname{head}_h) W^{O}

并行计算优势

小林原以为,要给每个读者调答案,就得像柜台办业务一样,一个接一个地来(先处理“我”,再处理“爱”,再处理“北京”)。老馆长摆摆手:“我们图书馆从来不让读者排队。我们把所有查询卡叠成一摞,跟所有标签卡一次性比对,啪的一下,全部读者的答案份额同时算完。”这,就是矩阵乘法的魔法。

把前面的操作全部写成矩阵形式,就是著名的缩放点积注意力公式:

其中 QK^T 是一次矩阵乘法,一次算出所有位置两两之间的点积分数;softmax 按行归一化;再右乘 V 完成全部位置的加权求和。整个过程没有循环递推、没有先后依赖。对单个查询位置,计算量与序列长度成正比,并且所有位置相互独立、可同时进行;单次点积的运算量则随维度线性增长。而 RNN 必须沿着时间步一个一个地传递隐状态,前一步算完才能算下一步——相比之下,自注意力的并行优势是数量级的。

小林望着大厅里“同时举牌”的几十万读者,终于理解了为什么这套机制能撑起今天的大模型:不是因为它算得快一点点,而是因为它把“必须排队”的流程彻底改造成了“所有人都能同时说话”。而这场改造的起点,就是那个再朴素不过的缩放点积。

Attention⁡(Q,K,V)=softmax⁡(QK⊤dk)V\displaystyle \operatorname{Attention}(Q, K, V) = \operatorname{softmax}\left(\frac{Q K^{\top}}{\sqrt{d_k}}\right) V
注意力把“串行排队”变成了“同时举牌”,矩阵乘法一锤定音,这是它取代 RNN 成为主流架构的核心原因。
  1. 矩阵点积Q 与 K 的转置相乘,结果里第 i 行第 j 列就是 q_i 与 k_j 的点积。
    (QK⊤)ij=qi⋅kj(Q K^{\top})_{ij} = \mathbf{q}_i \cdot \mathbf{k}_j
  2. 整体缩放矩阵里每个元素都除以根号 dk,保持方差稳定。
    QK⊤dk\frac{Q K^{\top}}{\sqrt{d_k}}
  3. 按行 softmax对每一行做归一化,得到注意力权重矩阵。
    softmax⁡(QK⊤dk)\operatorname{softmax}\left(\frac{Q K^{\top}}{\sqrt{d_k}}\right)
  4. 右乘 V权重矩阵与值矩阵相乘,一个矩阵乘法完成所有位置的加权求和。
    softmax⁡(QK⊤dk)V\operatorname{softmax}\left(\frac{Q K^{\top}}{\sqrt{d_k}}\right) V

工业级应用

图书馆的这套“注意力导航系统”很快出了名,被推广到全世界:语言翻译局、新闻报社、甚至问答中心都来取经。老馆长笑着对小林说:“你学的这套缩放点积,现在是整个 AI 行业的地基了。那些顶尖模型,心脏里跳动的都是它。”

在真实世界里,缩放点积注意力以三种面貌出现在 Transformer 家族中。第一种是编码器自注意力:BERT 用它建模句子中任意两个词的关系,让“苹果”在“苹果公司”和“红苹果”里获得不同的上下文表示。第二种是解码器掩码自注意力:生成“我爱北京”时,处理“北京”这一刻不能偷看未来的词,于是给分数矩阵加上一个上三角掩码,把未来位置的分数设成负无穷,softmax 后权重自动归零。第三种是交叉注意力:机器翻译里,解码器用目标语言的 Q 去匹配编码器输出的 K、V,自动学会“bon“和”好”的跨语言对齐,取代了旧式统计翻译里手工设计的对齐规则。GPT、BERT、Transformer 机器翻译,无一例外。

小林站在图书馆的大门前,看着来来往往的读者,感慨万千:一套“提问—匹配—加权—混合”的小机关,从一张书桌出发,长成了整个 AI 世界的地基。所谓大道至简——缩放点积,就是那条最朴素也最深刻的大道。

MaskedAttention⁡(Q,K,V)=softmax⁡(QK⊤+Mdk)V,Mij={0,j≤i−∞,j>i\displaystyle \operatorname{MaskedAttention}(Q, K, V) = \operatorname{softmax}\left(\frac{Q K^{\top} + M}{\sqrt{d_k}}\right) V, \qquad M_{ij} = \begin{cases} 0, & j \le i \\ -\infty, & j > i \end{cases}
掩码的本质是“给未来位置判死刑”:负无穷经过 softmax 后权重为 0,模型永远看不到还没生成的词。
  1. 掩码矩阵 M上三角位置填负无穷,下三角填 0,保证当前位置只能看自己及之前的词。
    Mij={0j≤i−∞j>iM_{ij} = \begin{cases} 0 & j \le i \\ -\infty & j > i \end{cases}
  2. 加入分数矩阵掩码与缩放后的分数相加,未来位置的分数变成负无穷。
    QK⊤dk+M\frac{Q K^{\top}}{\sqrt{d_k}} + M
  3. softmax 后归零e 的负无穷次幂等于 0,未来位置的注意力权重自动为 0。
    exp⁡(−∞)=0\exp(-\infty) = 0
  4. 保持并行结构掩码只影响权重取值,不改变矩阵乘法的并行计算方式。
    softmax⁡(QK⊤+Mdk)V\operatorname{softmax}\left(\frac{QK^{\top}+M}{\sqrt{d_k}}\right) V

AI 应用场景

机器翻译与文本摘要

阶段:模型架构设计(编码器—解码器)

解决的问题:传统统计机器翻译需要语言学家手工编写“词对齐规则”(哪个源语言词对应哪个目标语言词),规则覆盖不全、维护成本极高。缩放点积注意力让对齐自动涌现:解码器每个位置用 Q 与编码器所有位置的 K 做点积,从 V 中按权重提取对应语义,翻译质量显著跃升。

具体案例:在 Google 的 Transformer 机器翻译系统中,翻译“苹果发布了新款手机”时,编码器自注意力让“苹果”同时关联“发布”和“手机”,解码器交叉注意力则让目标语言中的 released 一词自动对齐源语言中的“发布”,无需任何人工对齐标注。

大语言模型文本生成

阶段:推理部署(因果解码)

解决的问题:生成式 AI 的痛点是“边写边看”——生成第 k 个词时只能依据前 k-1 个词,不能偷看未来。掩码缩放点积通过上三角负无穷掩码天然实现“因果性”,同时保留全序列并行训练的能力,让 GPT 类模型可以在海量语料上高效预训练。

具体案例:当你让 ChatGPT 续写“窗外下起了____”时,模型内部对“窗”“外”“下”等位置的 K 做点积检索,把注意力集中到“雨”“雪”等最可能的候选上,再通过加权求和决定下一个词的概率分布——整个过程在几十毫秒内完成。

语义检索与文档问答

阶段:检索增强生成(RAG)

解决的问题:传统关键词检索无法理解“如何让咖啡不苦”和“咖啡苦涩原因与对策”的语义等价关系。RAG 系统先把文档切块并向量化,再用用户查询向量与文档向量做点积相似度排序——这与 Q 和 K 的点积如出一辙;缩放技巧同样被借鉴,防止高维向量分数方差过大导致排序失真。

具体案例:企业知识库问答机器人收到“服务器宕机怎么排查”,先在向量库中与 10 万条文档块做点积打分,选出 Top-20 相关片段,再交给大模型综合生成带依据的回答,显著减少幻觉。

Python 演示

python37 行
import numpy as np  def softmax(x, axis=-1):    # 先减去最大值, 防止 exp 指数溢出, 保证数值稳定    x = x - np.max(x, axis=axis, keepdims=True)    return np.exp(x) / np.sum(np.exp(x), axis=axis, keepdims=True)  def scaled_dot_product_attention(q, k, v):    d_k = k.shape[-1]    scores = q @ k.T                # 第 1 步: 点积相似度    scores = scores / np.sqrt(d_k)  # 第 2 步: 除以根号 dk 缩放    weights = softmax(scores)       # 第 3 步: softmax 归一化    output = weights @ v            # 第 4 步: 加权求和    return output, weights  if __name__ == "__main__":    np.random.seed(0)    # 模拟一句话 "我 爱 北京" 的 3 个词向量, 每行是一个词的原始表示    X = np.array([        [0.9, 0.1, 0.2, 0.3],        [0.2, 0.8, 0.4, 0.1],        [0.1, 0.3, 0.6, 0.9],    ])    d_model = X.shape[1]    # 随机初始化三个投影矩阵, 真实训练中它们会被梯度下降逐步学习    W_q = np.random.randn(d_model, d_model)    W_k = np.random.randn(d_model, d_model)    W_v = np.random.randn(d_model, d_model)    q, k, v = X @ W_q, X @ W_k, X @ W_v    output, weights = scaled_dot_product_attention(q, k, v)    print("注意力权重矩阵(每行之和为 1):")    print(np.round(weights, 3))    print("自注意力输出(形状与输入一致):")    print(np.round(output, 3))
目的:从零实现缩放点积注意力的四步流程,直观展示每一步的矩阵运算。
  1. scores = q @ k.T一次矩阵乘法算出所有位置两两之间的点积相似度,对应公式中的 QK^T。
  2. scores = scores / np.sqrt(d_k)除以根号 dk,把分数方差从 dk 拉回 1,防止 softmax 梯度消失。
  3. weights = softmax(scores)把分数转换成非负且每行和为 1 的注意力权重矩阵。
  4. output = weights @ v用注意力权重对值向量做加权求和,得到携带全局上下文的新表示。
  5. q, k, v = X @ W_q, X @ W_k, X @ W_v同一份输入通过三个可学习投影矩阵,生成查询、键、值三种角色。

常见误区

误区“Q 和 K 做点积,算的就是两个向量的余弦相似度吧?夹角越小越相似,这不是一回事吗?”

正解点积等于两个向量模长之积乘以夹角余弦,它除了夹角还乘上了双方的模长;余弦相似度是先把向量归一化(模长变为 1)再求点积。注意力里刻意保留模长是有意义的——“嗓门大、信号强”的向量也是语义的一部分。把两者划等号,会误以为缩放因子是在修正余弦计算误差,从而误解它控制方差的真实作用。

为何常见:因为市面上讲相似度的资料几乎都以余弦相似度为例,大家容易把“相似度度量”直接等价于“余弦相似度”。

误区“除以根号 dk 就是把分数归一化,让分数落在 0 到 1 之间,不然 softmax 没法用。”

正解归一化是 softmax 的职责——它输出的权重才在 (0,1) 且和为 1。缩放做的是方差控制:当 q、k 各分量方差为 1 时,点积方差等于 dk,dk 越大分数越分散,softmax 输入端差距过大,输出趋近 0 或 1 的两极,梯度几乎消失。除以根号 dk 让方差回到 1,缩放后的分数照样可以大于 1 或小于 0。

为何常见:直觉上“除法 ≈ 归一化”,而且很多教程把缩放和归一化放在一起讲,容易混淆两者的边界。

误区“Q、K 的维度越大,能表达的语义越丰富,所以把 dk 设得越大模型越强。”

正解维度增大的好处是表达力更强,但代价也实打实:参数量、计算量、显存占用都明显上涨;更重要的是,点积方差随 dk 线性增大,如果不做缩放,softmax 梯度会迅速枯竭。缩放点积的设计初衷,正是让模型在较大 dk 下依然能稳定训练,而不是鼓励无限加大 dk。

为何常见:“容量越大能力越强”的直觉在深度学习中太常见,容易忽略数值稳定性这一工程约束。

误区“softmax 输出的权重就是重要性排序,权重最大的那个词一定是对结果贡献最大的词,其他词可以忽略。”

正解权重是“相对竞争”的结果,它受序列长度、分数分布、头数和层数共同影响。一个词可能靠多个中等权重的词协作完成消歧(比如“苹果”同时看“公司”和“手机”),单一最大权重并不能代表全部贡献。直接把权重热力图当可解释性报告,是研究早已证伪的过度简化。

为何常见:注意力矩阵天然是“和为 1 的概率”形态,看起来太像“重要性分布”,让人忍不住直接解读。

面试题

Q1. 缩放点积注意力中,“点积”的作用是什么?

单选题 · easy

  • A.生成查询向量表示
  • B.度量查询与键的相似度← 正确答案
  • C.对键向量进行降维
  • D.对权重进行归一化

答案:B。点积把查询 q_i 和键 k_j 逐分量相乘再求和,得到衡量二者相似程度的标量分数。生成查询向量的是投影矩阵 W^Q,降维和归一化都不是点积的职责,因此 B 正确。

Q2. 点积结果为什么要除以根号 dk?

单选题 · mid

  • A.为了把分数限制在零一之间
  • B.防止方差过大引发梯度消失← 正确答案
  • C.为了减少矩阵乘法的计算量
  • D.为了让模型参数的规模变小

答案:B。当 q、k 各分量方差为 1 时,点积方差等于 dk,dk 越大分数越分散,softmax 输出趋近 0/1 两极导致梯度消失。除以根号 dk 让方差回到 1,这是数值稳定的关键,而非归一化或减少计算量。

Q3. 经过 softmax 后,注意力权重满足什么性质?

单选题 · easy

  • A.全部非负且总和恰好为一← 正确答案
  • B.允许负数但绝对值小于一
  • C.数值之和正好等于根号 dk
  • D.所有位置权重完全相同

答案:A。softmax 先对分数取指数(结果必为正),再除以所有指数之和,因此每个权重落在 (0,1) 且总和恒为 1,天然构成概率分布。负数、和为 dk、处处相等都与 softmax 的定义矛盾。

Q4. 当 dk=64 时,未缩放的注意力分数方差大约是多少?

单选题 · mid

  • A.大约等于六十四← 正确答案
  • B.大约等于八
  • C.大约等于一
  • D.大约等于零

答案:A。若 q、k 各分量独立且方差为 1,点积是 64 个独立乘积之和,方差叠加为 64,标准差为 8。这正是需要除以根号 dk(即 8)把方差压回 1 的原因。

Q5. 关于缩放点积注意力的并行计算,下列说法正确的是?

单选题 · mid

  • A.所有位置的权重可以同步计算← 正确答案
  • B.核心运算可以写成矩阵乘法
  • C.必须按照序列顺序逐步递推
  • D.依赖 GPU 的并行运算加速

答案:A。严格来说,A、B、D 都是自注意力的特性:没有时序依赖、QK^T 与 softmax、乘 V 都是矩阵运算,GPU 可高度并行。C 是 RNN 的串行特性,与注意力相反。本题为单选,C 明显错误,其余为正确表述。

Q6. Q、K、V 是如何从输入 X 得到的?

单选题 · easy

  • A.将 X 复制三份直接使用
  • B.X 与三个投影矩阵相乘← 正确答案
  • C.X 经过 softmax 归一化
  • D.X 与注意力权重逐项相乘

答案:B。X 分别与可学习的 W^Q、W^K、W^V 相乘,得到三种角色向量。直接复制会导致三者完全相同,失去分工意义;softmax 和注意力权重都发生在 QKV 生成之后。

Q7. 解码器中的掩码自注意力主要用于做什么?

单选题 · mid

  • A.防止当前词看到未来位置← 正确答案
  • B.减少模型训练所需数据量
  • C.提升词向量表示的维度
  • D.将注意力分数换成余弦值

答案:A。掩码矩阵把未来位置的分数设为负无穷,softmax 后权重为 0,模型只能依赖当前及之前的词,保证生成的因果关系。它不改变数据量、维度,也不修改相似度算法。

Q8. 相比循环神经网络,缩放点积注意力具备哪些优势?

多选题 · hard

  • A.能直接建模长距离词与词依赖← 正确答案
  • B.以固定步数完成全层计算← 正确答案
  • C.彻底解决了梯度消失问题
  • D.无需任何形式的位置编码

答案:AB。注意力一步连接任意两个位置,长距离依赖路径最短,且整层由固定几步矩阵乘法完成、可并行。但它仍需位置编码注入顺序信息(D 错);缩放只是缓解梯度问题,不代表彻底解决(C 错)。

Q9. 缩放点积注意力的完整计算顺序是?

单选题 · hard

  • A.点积、缩放、softmax、加权求和← 正确答案
  • B.softmax、点积、缩放、加权求和
  • C.缩放、softmax、点积、加权求和
  • D.加权求和、点积、缩放、softmax

答案:A。公式 Attention = softmax(QK^T/√dk)·V 明确定义了顺序:先点积算相似度,再除以根号 dk 缩放,再按行做 softmax,最后与 V 加权求和。顺序错乱会导致分数无法正确归一化或权重未参与求和。

Q10. 关于多头注意力中“多头”与缩放点积的关系,正确的是?

多选题 · hard

  • A.多组投影矩阵生成多个子空间← 正确答案
  • B.每个头都执行完整的缩放点积← 正确答案
  • C.各头输出拼接后做线性投影← 正确答案
  • D.各头必须共享同一组权重参数

答案:ABC。多头注意力把 Q、K、V 分别投影成 h 组,每个头独立执行完整的缩放点积,最后拼接并乘输出投影矩阵 W^O。各组权重是独立学习的,共享同一组权重就不是多头了(D 错)。