想象一个大案现场:门锁没有撬痕,窗户关着,但保险柜里的钻石不见了。你派出了一支侦探团队,每位侦探拿着不同颜色的放大镜——红色侦探负责时间线,蓝色侦探负责人物关系,绿色侦探负责物证痕迹,紫色侦探负责财务流水。他们各自在案件信息中搜索自己关心的线索,写下判断,最后把报告拼在一起,你才看清真相:是内部人干的。多头自注意力,就是Transformer派出的这支侦探团队。它让模型在读懂一句话时,同时从多个维度观察词与词的关系:语法、语义、指代、情感……每一种维度由一个“头”负责。本文会用这个比喻,把多头自注意力从QKV到缩放再到多头拼接讲得明明白白,不堆公式吓人。

岗位关联

多头自注意力是Transformer时代大模型理解语言的核心引擎。掌握它,你就掌握了BERT、GPT等主流模型的底层逻辑,是从事深度学习算法工程师、LLM应用开发等岗位的必修课。

目录
  1. 可视化演示
  2. 自注意力总览
  3. QKV矩阵变换
  4. 注意力分数计算
  5. 多头机制原理
  6. 长距离依赖优势
  7. 实际应用场景
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示多层神经网络前向传播过程,数据从输入层经隐藏层传递到输出层,实时显示各层神经元激活值变化。

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

输入层 L0 青色节点为神经元,线条粗细表示权重大小 流动粒子表示数据前向传播过程 a = σ(Σ w·x + b) 每个神经元计算加权输入后经激活函数输出

自注意力总览

侦探团队刚到案发现场,队长说:“先别下结论,每个人都把整本卷宗从头到尾翻一遍,看看谁和谁之间存在关联。”于是每位侦探拿着自己的笔记本,在卷宗里划出重点。这就是自注意力的开始——每个词不再是孤立的信息点,而是与句子里的每一个词交换情报。

在Transformer中,输入是一串词向量。自注意力让每个词向量通过计算与其他所有词向量的关联,更新自身为包含上下文信息的表示。这种关联用三个角色描述:Query(查询)、Key(键)、Value(值)。一段话里,Query问“我在找什么”,Key回答“我身上有什么标签”,Value给出“我实际的内容”。输出是Value按关联度加权汇总的结果。

就像侦探们最终会根据某个线索与本案的匹配程度来分配注意力,自注意力的输出就是每个词在全文语境下的“案情摘要”。

Attention(Q,K,V)=softmax(QK⊤dk)V\text{Attention}(Q,K,V)=\text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V
  1. 计算查询与键的匹配度将Q与K的转置相乘,得到每对词之间的原始分数,分数越高代表关系越紧密。
    QK⊤\displaystyle QK^\top
  2. 缩放分数除以$\sqrt{d_k}$,防止向量维度大时点积过大。
    QK⊤dk\displaystyle \frac{QK^\top}{\sqrt{d_k}}
  3. 归一化成权重用Softmax将每一行的分数变成总和为1的概率。
    softmax(QK⊤dk)\displaystyle \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)
  4. 加权汇总内容用权重对V做加权平均,得到该位置的上下文表示。
    softmax(QK⊤dk)V\displaystyle \text{softmax}\left(\frac{QK^\top}{\sqrt{d_k}}\right)V

QKV矩阵变换

每位侦探都有特殊的笔记本:红色侦探的本子只记时间,蓝色侦探只记人物关系。他们拿着同一份案件材料,但记录的格式不同。同样地,输入词向量本身并不天然区分Q、K、V,需要通过三个可学习的权重矩阵,把同一个输入投影到三种“笔记本格式”里去。

具体来说,输入矩阵$X$的每一行是一个词的嵌入向量。分别乘以$W_Q$、$W_K$、$W_V$三个权重矩阵后,就得到了Q、K、V。这三个矩阵是模型训练中逐渐学出来的,相当于侦探们自己调整记录方式。

这就像给每位侦探分发不同颜色的笔记本——同样的证词,不同的关注点,最终让模型在后续计算中“各取所需”。

Q=XWQ,K=XWK,V=XWVQ=XW_Q,\quad K=XW_K,\quad V=XW_V
  1. 输入矩阵X把一句话的n个词向量堆叠成矩阵,行数是词数,列数是嵌入维度。
    X\displaystyle X
  2. 三次矩阵乘法X分别与三个可学习的投影矩阵相乘,完成线性变换。
    XWQ, XWK, XWV\displaystyle XW_Q,\ XW_K,\ XW_V
  3. 得到三种角色Q、K、V在数值上不同,但形状相同,分别承载查询、标签、内容三种语义。
    Q, K, V\displaystyle Q,\ K,\ V

注意力分数计算

侦探如何判断一条线索是否重要?他会把自己关心的点(Q)与证据上贴着的标签(K)做匹配,匹配度就是分数。最常见的匹配方式就是点积:两个向量方向越一致,点积越大。但点积的数值会随着向量维度$d_k$增大而变大,就像多人同时说话时音量会失控,所以需要除以$\sqrt{d_k}$来“压音量”。

缩放之后的分数矩阵再进入Softmax,把每一行变成和为1的注意力权重。这一步让权重既能保留相对强弱,又不会因为个别极大值抢走全部注意力。

缩放因子就像音响系统的音量限制器——如果某个线索音量过大,就会掩盖其他线索,所以要把音量调回舒适区。合理缩放之后,Softmax才能给出既锐利又稳定的注意力分布。

scoreij=qi⋅kjdk\text{score}_{ij}=\frac{\mathbf q_i\cdot \mathbf k_j}{\sqrt{d_k}}
  1. 点积计算位置i的查询向量$\mathbf q_i$与位置j的键向量$\mathbf k_j$做内积,得到相似度。
    qi⋅kj\displaystyle \mathbf q_i \cdot \mathbf k_j
  2. 除以缩放因子用$\sqrt{d_k}$缩放,把分数拉回适合Softmax的区间。
    qi⋅kjdk\displaystyle \frac{\mathbf q_i \cdot \mathbf k_j}{\sqrt{d_k}}
  3. 得到分数矩阵所有i和j的组合构成注意力分数矩阵,矩阵中的每个元素就是对应两个位置的关联强度。
    scoreij\displaystyle \text{score}_{ij}

多头机制原理

一个侦探可能很擅长时间线,但让他同时关注人物关系就会漏掉重要线索。所以队长安排多位侦探,每人专攻一个方向,最后把报告拼在一起。多头注意力正是这样:不再只做一次注意力,而是把Q、K、V分别投影到h组较低维的子空间,在每组里独立计算注意力,最后把所有头的结果拼接起来,再经过一个输出投影矩阵$W_O$。

每个头都有自己独立的$W_i^Q$、$W_i^K$、$W_i^V$,因此可以学到不同的注意力模式。比如一个头关注语法依赖,另一个头关注指代关系,第三个头关注词义相似性。这正是“多头”比单头强大的根本原因:不同子空间中的模式可以互补。

不同侦探的独立报告最后拼成完整案情,Transformer也因此能同时捕捉语法、指代、语义等多维信息。这就是多头自注意力的核心魅力。

MultiHead(Q,K,V)=Concat(head1,…,headh)WO\text{MultiHead}(Q,K,V)=\text{Concat}(\text{head}_1,\dots,\text{head}_h)W_O
headi=Attention(QWiQ,KWiK,VWiV)\text{head}_i=\text{Attention}(QW_i^Q,KW_i^K,VW_i^V)
  1. 每个头独立投影用$W_i^Q$、$W_i^K$、$W_i^V$把原始Q、K、V映射到各自的子空间。
    QWiQ, KWiK, VWiV\displaystyle QW_i^Q,\ KW_i^K,\ VW_i^V
  2. 单头注意力计算每个头内部执行一次标准自注意力,得到该头关注的上下文向量。
    headi=Attention(QWiQ,KWiK,VWiV)\displaystyle \text{head}_i=\text{Attention}(QW_i^Q,KW_i^K,VW_i^V)
  3. 拼接所有头把h个头的结果按列拼接成一个长向量,相当于把各位侦探的报告装订成册。
    Concat(head1,…,headh)\displaystyle \text{Concat}(\text{head}_1,\dots,\text{head}_h)
  4. 输出投影用$W_O$把拼接后的长向量映射回模型原始维度,形成最终输出。
    Concat(head1,…,headh)WO\displaystyle \text{Concat}(\text{head}_1,\dots,\text{head}_h)W_O

长距离依赖优势

如果只有一个侦探,他必须从头到尾逐一念证词,念到第100句时早就忘了第1句说了什么。而多侦探团队直接把整本案卷摊开在桌上,第1句和第100句都能直接建立连线。RNN处理长文本时,信息沿时间步传递,遇到长距离就容易被遗忘;而自注意力让任意两个token一步直达,天然适合长距离依赖。

当然,这种“全摊开”的代价是计算量。每个位置都要和所有位置做注意力,所以复杂度随序列长度n呈平方增长。理解这个代价,你就明白为什么实际应用中会在长文本上做窗口化或稀疏化优化。

摊开卷宗虽然有成本,但换来的是任何线索都能一眼看到。正是这种“全局视野”,让大模型在长文中依然能抓住关键信息。

O(n2d)\mathcal O(n^2 d)
  1. n个查询与n个键配对数每个位置都要对其他所有位置计算注意力,所以有n×n对。
    n×n\displaystyle n \times n
  2. 每对计算涉及维度d点积和加权平均都要处理d维向量。
    n2d\displaystyle n^2 d
  3. 总复杂度时间和空间复杂度都是$\mathcal O(n^2 d)$,序列变长时成本急剧上升。
    O(n2d)\displaystyle \mathcal O(n^2 d)

实际应用场景

如今这支“侦探团队”已经被各大机构收编,成了处理语言的标配。从翻译到写作文,从问答到图文检索,背后都有多头自注意力在同时关注不同线索。

在机器翻译中,多头注意力让源语言和目标语言的词对齐更准确;在BERT预训练中,模型用多头注意力预测被掩码的词,同时参考左右两侧的上下文;在GPT系列模型中,多头注意力逐词预测下一个token,支撑起强大的文本生成能力;在多模态模型中,不同头还能分别对齐图像中的物体、颜色和文本中的名词、形容词。多头机制让“多视角协作”成为通用方案,任何需要关联两处信息的任务都能受益。

无论案件是翻译、写作还是看图说话,这支多头侦探团队都能靠多视角协作,拼出全局真相。这也解释了为什么Transformer能统一NLP、CV、语音等多种模态的建模方式。

AI 应用场景

机器翻译中的词对齐

阶段:模型训练与推理

解决的问题:传统统计翻译模型难以同时处理源语言和目标语言的远距离对齐,容易漏译。多头注意力的不同头分别关注主谓一致、时态、从句等不同关系,让翻译更加准确。

具体案例:Google翻译在线系统使用Transformer后,翻译“我昨天看到的那只狗,今天又出现了”时,不同注意力头能同时追踪“狗”和“那只”以及“昨天”和“今天”的时间关系,显著减少错译。

BERT预训练中的上下文理解

阶段:预训练

解决的问题:传统语言模型只能单向预测,无法充分理解上下文。BERT使用多头自注意力并行双向读入句子,在掩码词预测中同时参考左右两侧信息,相当于每个侦探都翻阅全文后才给出判断。

具体案例:BERT在预训练时随机遮住15%的词,让注意力头去预测被遮住的词。例如“今天[ ]真不错”,多头同时关注“今天”和“不错”来填出“天气”,让模型学到深层的语义关联。

多模态图文检索

阶段:多模态对齐训练

解决的问题:图像和文本不在同一个语义空间,难以直接比较。多头自注意力将图像块与文本词映射到共享空间,并让不同头分别关注物体、颜色、位置等维度,实现跨模态理解。

具体案例:CLIP模型用多头自注意力对齐图片与标题。用户搜索“红裙子女孩”时,模型不同头分别匹配“红”“裙子”“女孩”,从而在海量图中定位到正确结果。

Python 演示

python42 行
import numpy as np  def softmax(x, axis=-1):    x = x - np.max(x, axis=axis, keepdims=True)    e = np.exp(x)    return e / np.sum(e, axis=axis, keepdims=True)  class MultiHeadAttention:    def __init__(self, d_model, h, d_k=None, d_v=None):        self.h = h        self.d_model = d_model        self.d_k = d_k or d_model // h        self.d_v = d_v or d_model // h        self.W_Q = np.random.randn(d_model, h, self.d_k) * 0.01        self.W_K = np.random.randn(d_model, h, self.d_k) * 0.01        self.W_V = np.random.randn(d_model, h, self.d_v) * 0.01        self.W_O = np.random.randn(h * self.d_v, d_model) * 0.01     def forward(self, X, mask=None):        n, d = X.shape        Q = np.einsum('nd, dhk -> nhk', X, self.W_Q)        K = np.einsum('nd, dhk -> nhk', X, self.W_K)        V = np.einsum('nd, dhv -> nhv', X, self.W_V)        scores = np.einsum('nhk, mhk -> nhm', Q, K) / np.sqrt(self.d_k)        if mask is not None:            scores = scores + mask        attn = softmax(scores)        ctx = np.einsum('nhm, mhv -> nhv', attn, V)        ctx_flat = ctx.reshape(n, -1)        out = ctx_flat @ self.W_O        return out  if __name__ == '__main__':    np.random.seed(0)    d_model, h, n = 16, 4, 6    X = np.random.randn(n, d_model)    mha = MultiHeadAttention(d_model, h)    out = mha.forward(X)    print('输出shape:', out.shape)
目的:用NumPy实现一个简化版多头自注意力,演示QKV投影、缩放点积、多头的拼接与输出投影。
  1. self.W_Q = np.random.randn(d_model, h, self.d_k) * 0.01初始化每个头的Query投影矩阵,小随机值保证初始输出平稳。
  2. Q = np.einsum('nd, dhk -> nhk', X, self.W_Q)用爱因斯坦求和将输入X投影成h个头各自的Q。
  3. K = np.einsum('nd, dhk -> nhk', X, self.W_K)同理得到K,K只负责被查询匹配。
  4. V = np.einsum('nd, dhv -> nhv', X, self.W_V)得到V,V是最终被加权汇总的内容。
  5. scores = np.einsum('nhk, mhk -> nhm', Q, K) / np.sqrt(self.d_k)在每个头内计算所有位置对的相似度,并除以缩放因子。
  6. attn = softmax(scores)将相似度归一化为注意力权重,每行和为1。
  7. ctx = np.einsum('nhm, mhv -> nhv', attn, V)用注意力权重对V加权求和,得到每个头的上下文表示。
  8. ctx_flat = ctx.reshape(n, -1)把多个头的输出拼接成一个大向量。
  9. out = ctx_flat @ self.W_O输出投影,将拼接结果映射回模型维度。

常见误区

误区我觉得多头注意力就是头数越多效果越强,反正每个头都能带来新信息,所以干脆把头数设大一点,模型肯定更聪明。

正解头数增加会摊薄每个头的维度,投影后子空间表达能力反而下降;头数过多还会带来冗余和计算开销。实际中头数需要与模型维度、数据规模平衡。就像派100个侦探,如果任务重叠,不如5个分工明确的精锐更高效。

为何常见:“多头”听起来像“人多力量大”,初学者容易被直觉带偏,忽略了维度分配和计算成本的约束。

误区我一直以为Query、Key、Value是三个不同的输入向量,分别来自句子中不同的来源,所以它们天然不一样。

正解在自注意力中,Q、K、V都由同一个输入矩阵X乘上不同的权重矩阵生成。它们确实数值不同,但来源相同。好比侦探们用的是同一份案件材料,只是各自用了不同格式的笔记本记录重点。

为何常见:因为"Query、Key、Value"名字差异明显,再加上多头里又有多个投影矩阵,就容易误以为数据源头也不一样。

误区我以为除以根号d_k只是为了让公式好看,对模型效果影响不大,删掉它也能训练。

正解不加缩放因子时,高维向量点积的绝对值会偏大,Softmax进入饱和区,梯度极小,训练几乎无法收敛。缩放因子相当于把“证据音量”控制到合理范围,是训练稳定的关键一环。

为何常见:初学者往往先看公式形态,容易忽略数值稳定性问题,只有训练时才感受到它的必要性。

误区既然有多个头,我觉得模型必须一个一个地处理它们,就像多个人排队发言一样。

正解多个头之间没有任何依赖,每个头独立完成投影、注意力计算,可以在GPU上完全并行。这正是Transformer高效的原因之一,也是它比RNN更适合大规模训练的重要原因。

为何常见:“多头”这个名字容易让人联想到“多阶段流程”,而忽略了矩阵运算天然可以批量并行的事实。

误区我以为增加头数就能让模型看得更远,所以处理长文本时应该把头数调得特别大。

正解长距离依赖的捕捉主要来自自注意力机制本身,即任意两个词一步直接关联,而不是靠头数堆出来的。头数影响的是关注模式的多样性,与捕获距离没有线性关系。

为何常见:把“多头”和“多步传递”混为一谈,实际上自注意力并不像RNN那样按步传递信息。

面试题

Q1. 在多头自注意力中,Q、K、V分别对应检测中的三个角色,下列描述正确的是?

单选题 · easy

  • A.查询、键、值← 正确答案
  • B.主键、外键、索引
  • C.质量、关键点、价值
  • D.求商、开方、方差

答案:A。Q(Query)是查询条件,K(Key)是被查询的标签,V(Value)是实际携带的内容。想象侦探问“我找什么”,线索上贴着标签,标签后面的内容就是值。其余选项把字母生硬套到其他概念,不符合定义。

Q2. 多头注意力中每个“头”的核心作用是什么?

单选题 · easy

  • A.控制模型层数
  • B.在不同子空间关注不同信息← 正确答案
  • C.减少模型参数量
  • D.让模型每次只看一个词

答案:B。多个头相当于多位侦探,各自从不同子空间提取信息,再汇总,从而让模型同时关注语法、语义等多种关系。控制层数靠的是Transformer的层叠结构,减少参数量不是多头的主要目的,每次只看一个词则失去了注意力并行的优势。

Q3. 自注意力分数计算中的缩放因子通常使用哪个式子?

单选题 · easy

  • A.d_k 开根号
  • B.1 除以根号 d_k← 正确答案
  • C.直接取 d_k
  • D.d_model 的一半

答案:B。缩放因子是$\frac{1}{\sqrt{d_k}}$,计算时用分数除以$\sqrt{d_k}$。这样能把点积结果压回合适范围,防止Softmax饱和。取d_k会让分数持续偏大,d_model的一半更是没有依据的随机值。

Q4. 多头注意力的输出投影矩阵W_O的输入维度是?

单选题 · mid

  • A.d_model 本身
  • B.头数乘 d_v← 正确答案
  • C.键向量维度
  • D.序列长度乘头数

答案:B。多个头的输出维度是h×d_v,拼接后成为W_O的输入,W_O再把它映射回d_model。d_model是最终输出维度而非输入维度;键向量维度是单头内部的维度;序列长度与矩阵投影没有直接关系。

Q5. 为什么自注意力能够捕捉长距离依赖?

单选题 · mid

  • A.使用循环结构
  • B.所有词对直接计算相关性← 正确答案
  • C.使用更大的卷积核
  • D.进行梯度裁剪

答案:B。自注意力让任意两个词一步建立联系,不需要像RNN那样逐帧传递,所以第1个词和第100个词也能直接交互。循环结构是RNN的特点,大卷积核是CNN的做法,梯度裁剪只是训练稳定技巧,都不是长距离依赖的关键。

Q6. 缩放因子的作用包括哪些?

多选题 · mid

  • A.防止梯度饱和← 正确答案
  • B.控制注意力温度← 正确答案
  • C.增加模型规模
  • D.提升训练稳定性← 正确答案

答案:ABD。缩放因子把点积压回合理范围,等价于调整Softmax的温度,既能防止梯度饱和,也能提升训练稳定性。它不会增加模型规模,因为缩放因子本身不是可学习的额外参数。

Q7. Softmax在注意力机制中的主要作用是?

单选题 · mid

  • A.增加非线性
  • B.将分数归一化成概率← 正确答案
  • C.降低向量维度
  • D.防止模型过拟合

答案:B。Softmax将注意力分数转换成总和为1的权重,让加权求和在数值上稳定且有概率解释。增加非线性不是Softmax的核心目的,降低维度是投影矩阵的事,过拟合防护通常靠Dropout和正则化。

Q8. 自注意力的计算复杂度关于序列长度n和维度d是?

单选题 · hard

  • A.O(n) 线性
  • B.O(n^2) 平方
  • C.O(n^2·d) 含维度← 正确答案
  • D.O(n·d) 线性

答案:C。每个位置要对所有n个位置计算点积,共n^2对,每对涉及d维向量,因此复杂度为O(n²d)。O(n)是线性序列模型的复杂度,O(n²)忽略了维度,O(n·d)只适合单步操作,都不完整。

Q9. 关于多头注意力中各头的投影矩阵,下列说法正确的是?

多选题 · hard

  • A.各自独立← 正确答案
  • B.共享部分权重
  • C.关注不同子空间← 正确答案
  • D.一起更新参数← 正确答案

答案:ACD。每个头有自己的W_Q、W_K、W_V,互不共享,在训练中同时更新。不同头从不同子空间提取信息,因此关注模式可以互补。B说共享权重不符合多头设计初衷,如果共享就退化成单头。

Q10. 以下关于多头自注意力的说法,正确的有哪些?

多选题 · extreme

  • A.各头可并行计算← 正确答案
  • B.缩放因子能防止梯度问题← 正确答案
  • C.拼接后需输出投影← 正确答案
  • D.头数越多越好

答案:ABC。各头是独立的,因此可以并行;缩放因子改善数值稳定性;拼接后要过W_O映射回原维度。头数太多未必更好,要平衡表达能力与计算量,D说法过于绝对。