想象你是一家侦探社的组长。今天接手了一桩复杂的案件:卷宗里有时间线、地点记录、人物关系、目击证词,线索横跨好多个维度。如果只派一位侦探去查,他只能带着一种疑问去翻档案——比如只盯着“谁在场”,却漏掉了“案发地点有什么异常”。于是你决定:同时派出四位侦探,每人带着完全不同的疑问出发。一位盯时间线,一位盯空间关系,一位盯人物动机,一位盯物证细节。他们各自翻阅卷宗、交叉比对,最后回到会议室,把各自的发现摊在桌上。你综合所有人的意见,得到了一个远比单人调查完整、立体的案件全貌。
这个场景,就是 Transformer 中多头注意力机制(Multi-Head Attention)的完美写照。“多头”不是让模型多看几遍同一个句子,而是让模型用多种不同的“疑问视角”去审视同一段文本,每个视角捕捉一种维度的特征,最后把所有视角的发现汇聚起来,形成对上下文更全面的理解。你可能听说过 QKV 这三个字母,却不知道它们具体在做什么;你也许看到过形如 softmax(QK^T/√d)V 的公式,却不明白它为什么长这样。别急,我们就把这场“侦探会议”从头到尾走一遍。
多头注意力是 Transformer 的“心脏”,几乎所有现代大模型(GPT、BERT、LLaMA)都建立在它之上。理解它,你才能真正看懂 Transformer 的架构设计,也能在面试和工程调参中踩准节奏。
可视化演示
动态演示多头注意力机制原理与实现的核心机制,通过架构/数据/状态/性能四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
多头注意力机制原理与实现:多头注意 多头注意力的架构设计与动机 QKV矩阵的分割与并行计算 核心机制可视化 多头注意力机制原理与实现整体架构与关键组件
注意力概述
侦探组长派侦探去查案,第一件事是明确“疑问”和“关键词”。在注意力机制里,这些角色都有名字:Q(Query,提问)是当前词发出的疑问,K(Key,索引)是档案柜上贴的标签,V(Value,内容)是档案正文。当“坐”想要理解自己在这个句子中应该和谁关联时,它会生成一个 Query,拿去和句子中所有词的 Key 匹配,匹配度高的词(“猫”、“垫子”)就会被取出 Value,参与“坐”的语义更新。
这个“匹配度”被称为注意力分数。它的核心操作是点积:把 Q 和 K 两个向量逐位相乘再相加,得到一个标量分数。分数越高,说明这个档案和当前疑问越相关。为了让分数不受向量维度影响,我们会在点积后除以一个缩放因子 √d_k——维度越大,点积数值会越大,容易让后续的 softmax 陷入“过度自信”的饱和区。
回到侦探社:Q 是侦探脑中随时准备问出口的问题,K 是卷宗封面的标签,V 是卷宗里的详细记录。先看标签是否匹配问题,匹配了才翻阅正文,这样检索效率高又抓得住重点。
- 查询向量 q当前要理解的那个词,将自己的状态编码成“问题”。$q$
- 键向量 k另一个词的“档案标签”,用来被问题匹配。$k$
- 点积相似度逐位相乘再求和,值越大表示越相关。$q \cdot k$
- 缩放因子除以维度开根号,防止高维时点积过大。$\dfrac{q \cdot k}{\sqrt{d_k}}$
QKV 生成过程
侦探不会凭空提问,他需要先把案件材料整理成“问题清单”。类似地,模型需要把原始的词向量变成 Q、K、V 三种向量。原始词向量组成的矩阵记为 X,它来自嵌入层,每个词对应一行向量。为了让同一个词能扮演“提问者”“标签”“内容”三种角色,我们需要三个不同的权重矩阵:W_Q、W_K、W_V。它们都是可以学习的参数,相当于“角色转换手册”。
将 X 分别与这三个矩阵做矩阵乘法,就得到了 Q、K、V。这个过程叫线性变换,本质是对原始向量做一次加权组合和空间变换。之所以不直接复用 X,是因为“提问”和“被检索”需要不同的表达空间:Query 要突出当前词的语义需求,Key 要突出词条本身的可匹配属性,Value 则要保留内容的详细信息。如果不做区分,检索就会变成“自己与自己比对”,失去灵活性。
这就像同一份案件卷宗被复印三份:一份做成“问题手册”(Q),一份做成“标签目录”(K),一份保留“正文原件”(V)。侦探带着问题手册去翻标签目录,找到对应页码后回到正文原件里抄取信息,三者分工明确,缺一不可。
- 输入矩阵 X把句子中每个词的嵌入向量按顺序排成的矩阵。$X$
- 查询投影矩阵把 X 变换到“提问空间”的可学习参数。$W_Q$
- 线性变换矩阵乘法本质上是对每行做一次线性组合。$Q = XW_Q$
- 键值同理K 与 V 分别做相同形式的变换,但参数独立。$K = XW_K, \quad V = XW_V$
缩放点积机制
现在侦探拿到了问题清单和标签目录,开始逐一比对。把所有 Q 和所有 K 做矩阵乘法,就得到一张“匹配分数表”QK^T——每行是一个 Query,每列是一个 Key,交叉点是它们的点积。这个分数表经过缩放后,还要过一层 softmax,把每一行变成“对整句话中所有词的注意力权重”,这组权重和为 1,表示当前词应该如何分配注意力。
最后,用这组权重对 V 做加权求和:权重越大的词,它的内容对当前词的贡献越多。这步操作就是“按重要程度提取档案内容”。整个过程合起来,就是著名的缩放点积注意力公式。注意这里 V 的每一行对应一个词的内容向量,加权求和后得到的行向量,就是当前词融合了整个上下文后的新表示。
在侦探社里,这一步相当于:组长把所有侦探的问题和所有卷宗标签摆在一张大桌上,逐对打分;然后按照“相关程度”决定每位侦探应该重点阅读哪些卷宗。注意力权重越高,翻阅得越仔细;权重趋近于 0 的卷宗,扫一眼略过即可。
- 匹配分数矩阵Q 与 K 转置相乘,得到 n×n 的分数表,n 是句子长度。$QK^\top$
- 缩放除以 √d_k,将分数方差拉回稳定区间。$\dfrac{QK^\top}{\sqrt{d_k}}$
- Softmax 归一化沿每一行做归一化,使权重非负且和为 1。$\text{softmax}(\cdot)$
- 加权取出内容注意力权重矩阵与 V 相乘,等价于按权重提取各词内容后叠加。$\text{softmax}(\cdot)V$
多头分解并行
如果只做一次缩放点积注意力,好比只派一位侦探去查案,他只能带着固定视角看问题。为了多角度侦查,Transformer 提出多头方案:把 d_model 维的 Q、K、V 向量均匀切成 h 份,每份称为一个“头”,维度为 d_k = d_model / h。每个头独立执行一次缩放点积注意力,并与自己的 W_Q、W_K、W_V 对应。
这样做的意义在于子空间特征:每个头在低维子空间里学习不同的匹配模式。实验和直觉都表明,某些头可能倾向于关注语法邻近关系,另一些头可能关注长距离指代,还有一些头关注语义相似性。它们并行计算、互不干扰,仿佛是四位侦探各执一词、分头行动——一位查人物关系、一位查时间线、一位查地点、一位查证物。
常见的头数 h 取 8 或 16。若 d_model = 512,h = 8,则每个头的维度是 64。所以每个头并不是“看整个句子 8 次”,而是“从 64 维的切片视角看句子 8 次”,就像 8 位侦探各自戴着“窄带滤镜”去观察现场——视角不同,发现自然不同。
- 专属投影权重每个头有自己的 W_i^Q、W_i^K、W_i^V,把输入投到不同子空间。$XW_i^Q,\ XW_i^K,\ XW_i^V$
- 分布式注意力每个头独立并行执行缩放点积注意力。$\text{Attention}(\cdot)$
- 得到第 i 个头输出输出向量维度为 d_k,是原 d_model 维的一部分。$\text{head}_i$
拼接与输出
四位侦探各自查完,回到会议室。他们的笔记分别记在不同颜色的本子上,篇幅、格式各不相同。组长要做两件事:第一,把所有笔记拼接成一份完整报告;第二,把这份报告投影成统一的格式,方便后续部门使用。
对应到模型里:首先把 h 个头的输出按特征维度方向拼接起来,得到维度为 d_model 的向量。但这时的向量只是“各头独立结论的物理堆叠”,头与头之间还没有信息交互。于是乘以一个可学习的输出投影矩阵 W_O,将拼接向量混合映射回原始维度。这一步相当于组长把四份独立笔记打散重排,去粗取精,最终形成一份协调一致的总结报告。
随后,Transformer 还会在这个输出上加上残差连接(把最初的输入 X 加回来)和层归一化(对激活值做标准化),帮助深层网络稳定训练。这些操作让信息在网络多层传递中不退化,也避免累计方差越来越大导致训练崩溃。
这也解释了为什么多头没有“增加参数爆炸”:每个头的投影矩阵把维度缩小到原来的 1/h,总参数量和单头大投影基本持平,但表达能力却大幅提升——正如侦探社虽然没有增加总人数,但让每个人分工细分,效率与覆盖度反而更高。
- 拼接各头输出每个头输出 d_k 维,沿特征轴拼成 d_model 维。$\text{Concat}(\text{head}_1, \ldots, \text{head}_h)$
- 输出投影矩阵一个 d_model × d_model 的可学习矩阵,负责融合各头信息。$W^O$
- 完成最终变换拼接向量乘以投影矩阵,得到与输入同形状的输出。$\text{MultiHead}(Q,K,V)$
整体公式复杂度
把前面所有环节串联起来,就得到多头注意力的完整公式:先对输入 X 分别用三套权重生成 Q、K、V,再把 Q、K、V 切成 h 份分别做缩放点积注意力,拼接后乘以 W_O 映射回原空间。整个过程里,最“贵”的操作是 QK^T 这一步——它要为句子中任意两个词之间都计算一个匹配分数。
假设句子长度为 n,嵌入维度为 d,那么注意力分数矩阵的大小是 n × n,所以计算复杂度为 O(n²·d)。这正是 Transformer 对长文本处理成本高的原因:序列长度翻倍,注意力计算量翻四倍。多头注意力并不会改变这个复杂度,因为 h 个头拼起来的计算总量仍是单个大注意力的量级,只是在组织方式上从“一个高维注意力”变成了“多个低维注意力的总和”。
侦探社的比喻到这里就完整了:组长发出任务,侦探们分头形成问题、匹配标签、提取内容、汇总结论。整个过程虽然“出场人物”很多,但每个人都只在自己的低维小岗位上工作,总人力成本没有增加,却带来了更丰富的信息视角。这就是多头注意力既高效又强大的根本原因。
- 完整多头公式六个步骤整合成一行,表示输入到输出的完整映射。$\text{MultiHead}(Q,K,V)$
- 两两词对计算注意力矩阵是 n×n,每个词要和所有词计算分数。$O(n^2)$
- 点积包含 d 维运算每对词的分数计算要对 d 维向量做点积。$O(n^2 \cdot d)$
- 多头不改变量级h 个头各自是 O(n²·d_k),加起来仍是 O(n²·d)。$\sum_{i=1}^{h} O(n^2 \cdot d_k) = O(n^2 \cdot d)$
AI 应用场景
机器翻译中的上下文建模
阶段:模型推理 / 特征编码
解决的问题:传统机器翻译逐词翻译容易丢失长距离依赖,例如“猫坐在垫子上”翻译成英文时,“坐”的主语是“猫”还是“垫子”必须由上下文决定。多头注意力让每个词同时参考多个维度的上下文信息,一个头捕捉主谓关系,另一个头捕捉空间位置,翻译结果更准确自然。
具体案例:在谷歌翻译(Transformer 架构)中,翻译“银行靠近河岸”时,某个注意力头专门关注“银行”与“河岸”的空间语义关系,另一个头关注“银行”作为金融机构还是河岸地形的类别属性,二者融合后选择正确译法。
长文档智能摘要
阶段:文本表示 / 关键信息抽取
解决的问题:人工摘要难以同时覆盖人物、事件、因果等不同侧面。多头注意力将文档切分成多个子空间视角并行提取要点,一个头关注关键实体,另一个头关注时间线,再汇聚成信息更全面的摘要。
具体案例:金融研报摘要系统中,给定一份上市公司年报,头 A 关注“营收增长”等财务指标,头 B 关注“风险提示”语句,头 C 关注“未来战略”表述。系统将各头提取的关键句拼接重排,生成覆盖多维度的摘要。
语义搜索引擎中的 Query-Doc 匹配
阶段:向量检索 / 相关度排序
解决的问题:传统搜索依赖关键词精确匹配,无法理解同义表达。在多头注意力中,用户的搜索请求作为 Q,候选文档的标题与摘要作为 K、V,不同头分别从主题、情感、实体、场景等角度计算相关性,让搜索结果更贴合用户意图。
具体案例:电商搜索“舒适的运动鞋”,用户输入中“舒适”和“运动鞋”分别与商品描述的“缓震科技”“跑步训练”等属性词产生强注意力关联,即使描述中没有出现“舒适”两个字,该商品也会被高权重复选出来。
Python 演示
import numpy as np def softmax(x): x = x - np.max(x, axis=-1, keepdims=True) return np.exp(x) / np.sum(np.exp(x), axis=-1, keepdims=True) def scaled_dot_product_attention(Q, K, V): # Q, K, V shape: (batch, h, seq_len, d_k) d_k = Q.shape[-1] scores = np.matmul(Q, K.transpose(0, 1, 3, 2)) / np.sqrt(d_k) weights = softmax(scores) return np.matmul(weights, V), weights def split_heads(x, h): # x shape: (batch, seq_len, d_model) batch, seq_len, d_model = x.shape d_k = d_model // h x = x.reshape(batch, seq_len, h, d_k) return x.transpose(0, 2, 1, 3) def combine_heads(x, h): # x shape: (batch, h, seq_len, d_k) batch, h_count, seq_len, d_k = x.shape d_model = h_count * d_k x = x.transpose(0, 2, 1, 3) return x.reshape(batch, seq_len, d_model) def multi_head_attention(x, h): batch, seq_len, d_model = x.shape rng = np.random.default_rng(0) W_Q = rng.normal(size=(d_model, d_model)) * 0.1 W_K = rng.normal(size=(d_model, d_model)) * 0.1 W_V = rng.normal(size=(d_model, d_model)) * 0.1 W_O = rng.normal(size=(d_model, d_model)) * 0.1 Q = split_heads(np.matmul(x, W_Q), h) K = split_heads(np.matmul(x, W_K), h) V = split_heads(np.matmul(x, W_V), h) out, weights = scaled_dot_product_attention(Q, K, V) out = np.matmul(combine_heads(out, h), W_O) return out, weights if __name__ == "__main__": batch, seq_len, d_model = 2, 4, 8 x = np.random.rand(batch, seq_len, d_model) out, weights = multi_head_attention(x, h=2) print("Multi-head output shape:", out.shape) print("Attention weights shape:", weights.shape) print("Weights for head 0, token 0:") print(weights[0, 0])
Q = split_heads(np.matmul(x, W_Q), h)先做线性投影生成 Q,再把 d_model 维切分成 h 个低维头。scores = np.matmul(Q, K.transpose(0, 1, 3, 2)) / np.sqrt(d_k)每个头内部做“查询×键”的点积并除以 √d_k,防止 softmax 饱和。weights = softmax(scores)沿最后一个维度归一化,得到和为 1 的注意力权重。np.matmul(weights, V)按权重对值向量加权求和,实现“按相关性提取内容”。out = np.matmul(combine_heads(out, h), W_O)拼接各头输出后乘输出投影矩阵,完成跨头信息融合。
常见误区
误区反正后面还有 softmax,不缩放也能归一化。这个 √dk 顶多算个“稳住数值”的小技巧,去掉应该没事吧?
正解缩放非常重要。当 d_k 较大时,点积的方差会随维度线性增长,导致分数数值很大,softmax 进入饱和区,梯度趋近于 0,参数几乎学不动。除以 √d_k 把分数方差拉回 1 的量级,让 softmax 区域保留足够的梯度信号,是训练稳定性的关键保障。
为何常见:直觉上 softmax 对任何输入都能给出概率分布,初学者容易忽略“数值范围对梯度的影响”这一层,以为只要分布和为 1 就够了。
误区网上文章常说“头 A 学习主谓关系,头 B 学习指代关系”,所以应该每个头都有明确的含义,可以逐个分析解释。
正解实践中注意力头并不总是可解释的。某些头确实会呈现出明显的模式,但更多头的“职责”是隐式的、混合的,甚至依赖具体任务。研究者通过探针实验能发现的规律,并不代表模型显式地按这些规则工作。
为何常见:神经网络的分布式表示很难被完全拆解,而“每个头一个角色”的叙事简单直观,容易传播,但过度简化了真实机制。
误区多头就是把同一个注意力计算多跑几遍,然后平均一下,相当于“多看一眼更安心”。
正解每个头投影到不同的低维子空间,使用的是不同的权重矩阵,计算的是不同“视角”的特征。与其说是重复看,不如说是“分工看”——像四位侦探各查各的线索,最后拼接出完整案情,而不是把同一份卷宗读四遍。
为何常见:从公式表面看,每个头都长得一模一样,容易误以为是同一操作重复执行。只有理解了维度切分和独立投影,才能看到“各司其职”的本质。
误区既然 Q、K、V 都由同一个 X 乘权重得到,那 Q 和 K 信息相同,只是换了名字,可以混用。
正解Q、K、V 经过三套不同的权重投影进入不同的语义空间。Q 代表“我想找什么”,K 代表“我能被什么找到”,V 代表“我实际提供什么”。三者的角色差异正是注意力机制能灵活检索信息的关键——就像“问题”和“标签”可以描述同一对象,但它们的功能完全不同。
为何常见:形式上 Q 与 K 来源相同、形状相同,初学者容易忽略线性投影改变了语义方向,误以为只是符号不同。
误区多头能捕捉更多特征,那头数设得越多,模型能力就越强,干脆设成 64 甚至 128。
正解头数并非越大越好。当 d_model 固定时,h 越大每个头的维度 d_k 就越小,单头能表达的信息容量大打折扣;同时计算和内存开销也会上升。经验上 8~16 个头在多数任务中表现良好,过大的 h 反而可能带来性能退化。
为何常见:“更多即更强”的直觉很自然,但忽略了资源约束与特征容量之间的权衡,以及低维切片带来的信息损失。
面试题
Q1. 在多头注意力中,QK^T 计算得到的矩阵表示什么?
- A.查询与键的相似度分数← 正确答案
- B.查询与值的相似度分数
- C.键与值的相似度分数
- D.输入与输出的损失函数
答案:A。Q 是查询,K 是键,Q 与 K 的转置相乘得到每个查询与每个键的匹配分数。V 不参与相似度计算,它是在得到权重之后才被加权求和的。类比侦探用问题去匹配卷宗标签,Q·K^T 就是“问题与标签的匹配表”。
Q2. 为什么缩放点积注意力要除以 √d_k?
- A.将分数取值范围压到 0 到 1 之间
- B.防止点积数值过大导致 softmax 梯度消失← 正确答案
- C.减少矩阵乘法的计算复杂度
- D.让 Q 和 K 的维度保持一致
答案:B。d_k 较大时点积方差变大,softmax 输入落在两端饱和区,梯度趋近于 0,模型难以训练。除以 √d_k 将方差拉回 1 的量级,使梯度保持平稳。它不是为了让分数在 0-1 之间,也不改变计算复杂度。
Q3. 关于多头注意力,下列说法正确的有?
- A.各头可并行捕捉不同特征← 正确答案
- B.各头输出最终会拼接← 正确答案
- C.头数越多效果一定越好
- D.QKV 来自输入投影← 正确答案
答案:ABD。多头将输入投影到多个子空间并行计算,最后拼接经 W_O 输出,因此 A、B、D 都正确。C 过于绝对,头数过多会使单头维度过低、表达容量下降,还可能增加计算开销,并非越多越好。
Q4. 设 d_model = 512,头数 h = 8,则每个头中 Q、K、V 的维度是?
- A.512
- B.64← 正确答案
- C.8
- D.128
答案:B。每个头的维度 d_k = d_model / h = 512 / 8 = 64。原始 512 维被均匀切成 8 份,每份 64 维在独立子空间计算注意力。8 个 64 维头拼接后恢复 512 维,正好与输入维度对齐。
Q5. 各头输出拼接之后,通常还需要做哪些操作?
- A.乘以输出矩阵 W_O 进行投影← 正确答案
- B.加上残差连接← 正确答案
- C.进行层归一化← 正确答案
- D.再按头切分回去
答案:ABC。拼接后先乘 W_O 完成跨头信息融合,再通过残差连接把输入加回来,最后做层归一化稳定训练。D 是逆向操作,与拼接目的相悖。
Q6. 缩放点积注意力的计算顺序正确的是?
- A.QK^T → 缩放 → softmax → ×V← 正确答案
- B.softmax → QK^T → ×V → 缩放
- C.KV^T → softmax → ×Q → 缩放
- D.QV^T → 缩放 → softmax → ×K
答案:A。标准流程是先算查询与键的匹配矩阵,缩放后做 softmax 得到注意力权重,最后对值加权求和。其余顺序在数学上不成立,混淆了 Q、K、V 的角色分工。
Q7. 多头注意力与单头注意力相比,最大的优势是什么?
- A.在多个子空间并行关注不同信息← 正确答案
- B.计算量一定更小
- C.完全避免过拟合
- D.不需要任何权重矩阵
答案:A。多头把高维空间切成多个低维子空间,每个头独立学习不同的特征模式。计算量大致同阶,并非“一定更小”;它也不能完全避免过拟合。其核心价值是“多视角并行”的信息捕捉能力。
Q8. 关于多头注意力的输出维度,以下说法正确的是?
- A.单头输出 d_k 维,拼接后为 d_model 维← 正确答案
- B.单头输出 d_model 维,拼接后为 h×d_model 维
- C.拼接后维度与输入无关
- D.输出维度与头数 h 无关
答案:A。每个头在 d_k 维子空间工作,输出 d_k 维。h 个头拼接后是 h × d_k = d_model 维,恰好等于输入维度。其他说法在维度推导上均不成立。
Q9. 残差连接与层归一化在 Transformer 中的作用包括?
- A.缓解深层网络梯度消失← 正确答案
- B.稳定训练过程← 正确答案
- C.使注意力权重之和为 1
- D.替代多头注意力计算
答案:AB。残差连接让梯度能直接流过深层网络,缓解梯度消失;层归一化把中间激活标准化,稳定训练。注意力权重和为 1 是 softmax 的特性,与这两者无关;它们也不替代注意力本身。
Q10. 若 d_k 很大且不对分数做缩放,softmax 的输出最可能呈现?
- A.近似均匀分布
- B.近似 one-hot 分布← 正确答案
- C.完全保持线性比例不变
- D.全为零向量
答案:B。d_k 大时点积分数的方差大,最大值与最小值差距被拉大,softmax 的指数运算会让最大分数对应的权重趋近于 1,其余趋近于 0,形成近似 one-hot 的分布。这会导致非最大项梯度几乎消失,模型难以学习特征之间的细微差异。