Self-Attention 和 Multi-Head Attention 有什么区别?
Self-Attention 和 Multi-Head Attention 有什么区别?
一句话核心:这是Transformer模型的两大核心注意力模块。Self-Attention负责让序列内部的每个位置“看见”其他所有位置,是基础;Multi-Head Attention则通过并行化多个Self-Attention“头”,让模型能从不同子空间同时捕捉多样化的上下文关联,是能力的跃升。面试必问,因为它直接决定了模型对复杂语言结构的理解深度。
核心概念(术语表)
- Self-Attention(自注意力机制):一种让序列中每个元素都能直接与序列内所有其他元素交互,并计算相关性权重的机制。用途:用于提取序列内部的依赖关系,是Transformer编码器和解码器的基础构建块。
- Multi-Head Attention(多头注意力机制):将输入的查询、键、值矩阵分割到多个并行的“头”中,在每个子空间独立执行Self-Attention,再将结果拼接并线性变换的机制。用途:增强模型同时关注来自不同表示子空间信息的能力,提升表达能力。
- QKV(查询、键、值):Self-Attention计算中的三个核心向量。查询向量(Query)代表当前要关注的位置,键向量(Key)代表可被关注的位置,值向量(Value)代表位置的实际信息。用途:通过Q和K的点积计算注意力权重,再对V进行加权求和。
- Softmax:一个归一化函数,将原始的注意力分数转换为和为1的概率分布。用途:在计算完Q和K的点积后,用于生成注意力权重。
- 缩放点积:在点积后除以键向量维度的平方根(√dk)的操作。用途:稳定梯度,防止点积值过大导致Softmax函数梯度消失。
- 线性层(投影层):对向量进行线性变换的全连接层。用途:用于将输入映射为Q、K、V,以及在多头注意力最后将拼接结果映射回原始维度。
- 子空间(Subspace):将高维的嵌入空间(如512维)分割成的多个低维空间(如8个64维空间)。用途:每个“头”在各自的子空间内独立计算注意力,捕获不同的特征模式。
历史背景 / 来源
- 提出者与时间:由Google团队Vaswani等人在2017年的论文《Attention Is All You Need》中首次提出并系统化。
- 解决的问题:旨在完全抛弃传统的循环(RNN)和卷积(CNN)结构,仅通过注意力机制构建一个全新的序列到序列模型(Transformer),以解决RNN难以并行计算、长距离依赖建模能力有限的问题。Self-Attention是基础组件,而Multi-Head Attention则是为提升该组件能力而设计的并行化方案。
工作原理 / 核心机制(详细讲解)
整体思路:Self-Attention通过QKV计算序列内部元素间的权重进行聚合;Multi-Head Attention将这一过程并行化到多个低维子空间,并聚合多维度的结果。
输入/输出:输入是一个由嵌入向量组成的序列(例如,“我爱AI”对应的三个词向量,每个为512维)。输出是同样形状的序列,但每个向量都已经融入了整个序列的上下文信息。
Self-Attention核心步骤详解:
- 第一步:生成Q、K、V。输入序列的每个512维向量,分别与三个独立的512x512的权重矩阵相乘,得到该位置的查询(Q)、键(K)、值(V)向量(均为512维)。输入:512维词向量;处理:三个线性变换;输出:三个512维向量Q, K, V。
- 第二步:计算注意力分数。对于序列中的每个位置,用其Q向量与序列中所有位置的K向量做点积,得到一个分数。输入:Q (1x512), 所有K (n x 512);处理:矩阵乘法;输出:一个 (1 x n) 的原始注意力分数矩阵。n为序列长度。
- 第三步:缩放与归一化。将每个分数除以 √dk(dk=512),然后对整个分数行应用Softmax函数。输入:原始分数矩阵;处理:缩放 + Softmax;输出:一个 (1 x n) 的注意力权重矩阵,每行和为1。
- 第四步:加权求和。用得到的注意力权重,对序列中所有位置的V向量进行加权求和,得到该位置的输出向量。输入:注意力权重 (1 x n), 所有V (n x 512);处理:加权求和;输出:一个512维的向量。对所有位置重复此过程,得到最终输出序列。
Multi-Head Attention核心步骤详解:
- 第一步:初始化与线性变换。拥有h个头(通常h=8)。每个头都有三套独立的权重矩阵,用于将原始的Q、K、V分别投影到更小的子空间。输入:原始Q、K、V (n x 512);处理:与h套 512x64 的权重矩阵相乘;输出:h组 Q、K、V,每组为 (n x 64)。
- 第二步:并行计算h个Self-Attention。对每一组 (Q_i, K_i, V_i) 独立执行完整的Self-Attention计算(包括点积、缩放、Softmax、加权求和)。输入:h组 (n x 64) 的Q、K、V;处理:h次独立的Self-Attention;输出:h个 (n x 64) 的子空间输出矩阵。
- 第三步:拼接与线性变换。将h个 (n x 64) 的输出矩阵在最后一维拼接起来,得到一个 (n x 512) 的大矩阵。然后将此矩阵通过一个最终的线性层(512x512)进行融合和变换。输入:h个 (n x 64);处理:拼接 + 线性变换;输出:最终的 (n x 512) 输出矩阵,与输入维度一致。
关键知识点(15条 bullet)
- 核心差异:Self-Attention是单个注意力机制,Multi-Head Attention是其并行化、多通道的增强版本。
- 表达能力:Multi-Head Attention通过多头并行,能同时捕获语法、语义、指代等不同层面的上下文信息,表达能力更强。
- 维度拆分:一个512维的输入向量,在8头注意力中会被拆分成8个64维的子向量,分别在8个子空间计算注意力。
- 独立权重:每个“头”都拥有自己独立的Q、K、V投影矩阵,确保学习到不同的注意力模式。
- 计算流程:Self-Attention流程为 QKV生成→点积→缩放Softmax→加权和;Multi-Head Attention是 线性投影→分割→并行Self-Attention→拼接→最终线性变换。
- QKV角色:Q是“提问者”,K是“被检索的标签”,V是“实际的内容”,注意力分数衡量Q与K的匹配度。
- 缩放因子:点积后除以√dk,是因为当维度dk较大时,点积结果方差会很大,导致Softmax梯度极小,训练困难。
- 通俗类比:Self-Attention像一个人仔细阅读文章,理解词与词的关系;Multi-Head Attention像一组专家从不同角度(语法、情感、逻辑)同时分析文章,再综合意见。
- 参数量:Multi-Head Attention的参数量大约是Self-Attention的h倍(h为头数),但通过降维子空间,总计算量增加可控。
- 位置信息:Self-Attention本身不包含位置信息,因此Transformer必须加入位置编码(Positional Encoding)来注入序列顺序。
- 普遍头数:在原始Transformer论文及BERT、GPT等模型中,头数h常取8或12,对应的子空间维度dk=64或更小。
- 输出维度:无论头数h多少,Multi-Head Attention的最终输出维度通过线性层变换回与输入相同的维度(如512),便于残差连接和层堆叠。
- 残差连接:Multi-Attention的输出通常会与输入进行相加(残差连接),然后进行层归一化,这是Transformer稳定训练的关键技巧。
- 信息整合:多头注意力的“拼接+线性变换”步骤,负责整合来自不同子空间的信息,生成统一的上下文表示。
- 应用场景:不仅用于NLP,也广泛应用于计算机视觉(Vision Transformer)、语音识别等任何需要建模元素间关系的任务。
应用场景(3-5个真实例子)
- 场景 1:机器翻译(Google Transformer)。原生Transformer模型使用Multi-Head Attention解决了英法翻译任务,在WMT 2014数据集上达到当时的SOTA(BLEU值41.0),训练速度比基于RNN的模型快数倍。
- 场景 2:预训练语言模型(BERT)。谷歌的BERT模型使用12头的Multi-Head Attention作为核心,在超过33亿单词的语料上预训练,在11项NLP基准任务上刷新纪录,证明了其强大的语言理解能力。
- 场景 3:文本生成(GPT系列)。OpenAI的GPT-3/4等模型使用包含Multi-Head Attention的解码器结构,在万亿级token数据上训练,能够生成流畅、连贯且富有创造性的长文本。
- 场景 4:图像识别(ViT)。Vision Transformer(ViT)将图像切分成序列块,使用Multi-Head Attention建模块与块之间的关系,在ImageNet数据集上性能媲美甚至超越顶尖的CNN模型。
常见误区 / 踩坑
- ❌ 误区 1:Multi-Head Attention只是简单地把Self-Attention重复执行h次。
✅ 正解:不仅重复,关键在于投影到h个不同的低维子空间。每个头通过独立的投影矩阵学习不同的注意力模式(如一个头关注局部语法,另一个头关注远距离依赖),最后拼接整合。 - ❌ 误区 2:Self-Attention的输出维度会随着序列长度n变化。
✅ 正解:Self-Attention的输入输出维度固定(如512维)。序列长度n影响的是注意力矩阵的大小(n x n)和计算复杂度(O(n²d)),但每个位置输出向量的维度始终是d。 - ❌ 误区 3:头数h越多,模型效果一定越好。
✅ 正解:头数过多会导致每个头的子空间维度过小(dk = d_model / h),可能无法承载足够的特征信息,增加训练难度。头数是一个需要在表达能力和计算开销间权衡的超参数。 - ❌ 误区 4:Multi-Head Attention中的线性层是可有可无的。
✅ 正解:最后的线性层至关重要。它负责将拼接的、来自不同子空间的信息进行融合和转换,映射回模型主干需要的维度,是信息整合的关键一步。 - ❌ 误区 5:注意力权重高的词在语义上一定更重要。
✅ 正解:注意力权重反映的是模型当前“关注”的程度,可能与语法结构、代词指代或训练数据中的统计偏差相关,并不直接等同于人类判断的语义重要性。
性能 / 复杂度(数据驱动)
- 时间复杂度:Self-Attention为 O(n²·d),其中n为序列长度,d为模型维度。Multi-Head Attention因为头数h通常很小(如8),总复杂度仍为 O(n²·d·h),但因为h是常数,通常简化为 O(n²·d)。
- 空间复杂度:主要是存储注意力权重矩阵,为 O(n²),与序列长度的平方成正比。这是处理超长序列的主要瓶颈。
- 与替代方案对比:
- 方案 A(Self-Attention):时间O(n²d),空间O(n²),能够全局建模,但长序列下计算和内存开销巨大。
- 方案 B(本方案,Multi-Head Attention):时间O(n²dh)(h为常数),空间O(n²),以增加可控的并行计算和参数量为代价,换取更强的特征抽取能力和多角度理解能力。
- 临界点与优化:当序列长度n非常大(如数万token)时,两者都面临平方复杂度的瓶颈,催生了Sparse Attention、Linear Attention等高效变体。对于常规任务(n
<1024),Multi-Head Attention是绝对主力。
- 性能数字:以BERT-base为例,它包含12层,每层12头Multi-Head Attention。在TPU Pod上预训练,约需4天处理40个epoch的BookCorpus+Wikipedia数据。
与相关概念的区别
vs 缩放点积注意力(Scaled Dot-Product Attention):
- 维度 1(构成):缩放点积注意力是单个注意力计算的核心操作(包含QKV点积、缩放、Softmax)。Multi-Head Attention则包含多个缩放点积注意力头以及前后的投影层。
- 维度 2(能力):前者是基础单元,后者是模块化、增强版的架构。
- 怎么选:在实际代码实现中,你通常直接调用
MultiheadAttention模块,它内部封装了多次缩放点积注意力。你需要决定的是头数和维度。
vs 自注意力(Self-Attention)与交叉注意力(Cross-Attention):
- 维度 1(输入源):Self-Attention的Q、K、V来自同一个序列(如编码器输出)。Cross-Attention的Q来自一个序列(如解码器),K和V来自另一个序列(如编码器输出)。
- 维度 2(用途):Self-Attention用于理解单个序列内部关系。Cross-Attention用于融合两个序列的信息(如翻译中,解码器关注源语言句子)。
- 怎么选:在Transformer编码器中只用Self-Attention;在解码器中,第一层用Masked Self-Attention,第二层用Cross-Attention连接编码器。
vs 卷积神经网络(CNN):
- 维度 1(视野):CNN通过卷积核感受野,局部、逐层地提取特征。注意力机制(自注意力)一步就能建立全局的、任意距离的依赖关系。
- 维度 2(参数效率):CNN参数与输入序列长度无关,注意力参数与序列长度无关,但与维度相关。在长距离依赖建模上,注意力更直接有效。
- 怎么选:CNN适合具有平移不变性的空间数据(如图像局部纹理)。Self-Attention适合需要理解全局上下文关系的序列数据(如语言、长视频帧)。
进阶 / 面试加分项
- 最新进展:Multi-Head Attention架构持续进化。例如,分组查询注意力(Grouped-Query Attention, GQA)通过让多个查询头共享同一组键值头,减少了KV缓存的内存占用,被用于Llama 2等最新大模型,以提升推理效率。
- 业界争议/未解问题:注意力机制是否是唯一或最优的解决方案?状态空间模型(如Mamba)等替代架构正在兴起,它们声称能以线性复杂度处理长序列,挑战着基于注意力的Transformer的统治地位。
- 一句话送给候选人:理解Multi-Head Attention的关键,是认识到它不仅仅是“并行计算”,而是通过构建多个“低维、异构的注意力子空间”,让模型能够像拥有多个专业“视角”一样,立体地解读信息,这是Transformer强大的根源。
面试如何回答
🟢 请用一句话解释Self-Attention和Multi-Head Attention的核心区别。
回答要点:
Self-Attention是单通道的注意力机制,让序列中每个元素直接关注整个序列的所有其他元素;而Multi-Head Attention则是将这一过程并行化到多个低维子空间(头),每个头独立学习不同的注意力模式,最后拼接整合,从而能从多个维度同时捕捉更丰富的上下文信息。前者是基础,后者是增强。
🟢 Transformer模型中,为什么在计算注意力分数时需要进行缩放(除以√dk)?
回答要点:
直接点积的结果会随着向量维度dk的增大而方差增大。当dk较大时,点积结果会变得非常大,导致Softmax函数在其梯度极小的区域饱和,从而引起梯度消失问题,阻碍模型训练。除以√dk相当于对点积进行了标准化,使其方差稳定在1左右,保证了Softmax的输入落在梯度敏感区间,使训练过程更稳定。这是《Attention Is All You Need》论文中的一个关键设计细节。
🟡 能否详细描述一下Multi-Head Attention的完整计算流程?
回答要点:
Multi-Head Attention的计算分为五步。第一步是线性投影,对输入的Q、K、V分别通过h套独立的权重矩阵,投影到h个更低的维度(如将512维投影到8组64维)。第二步是并行计算,对每组Q、K、V独立执行标准的缩放点积Self-Attention,得到h个输出。第三步是拼接,将h个输出在特征维度拼接起来,恢复原始维度(如8个64维拼回512维)。第四步是最终线性变换,将拼接后的结果通过一个线性层,进行信息融合和维度变换。第五步是输出,得到与输入形状一致的最终结果。这个过程让模型能在不同子空间并行捕获多样化信息。
🟡 在实现Multi-Head Attention时,头数h通常怎么选择?为什么原始Transformer用了8头?
回答要点:
头数h的选择是一个经验性的超参数调优问题,需要平衡模型表达能力和计算开销。常见选择是8、12、16等2的幂次,便于计算划分。原始Transformer选择8头,其背后有一个重要约束:保证每个头的子空间维度dk = d_model / h 不能太小。以d_model=512为例,若h=8,则dk=64。这个维度被验证足以承载有意义的特征信息,同时8个并行头提供了足够多样化的视角。若h过大(如32),dk=16,可能限制了每个头的表达能力;若h过小(如2),则模型从不同角度捕捉信息的能力不足。因此,8是在当时计算资源和模型维度下的一个稳健选择。
🟡 Multi-Head Attention相比单层的Self-Attention,在模型表达能力上具体强在哪里?能否举个例子?
回答要点:
单层Self-Attention只能学习一种注意力分布模式,而Multi-Head Attention通过多个并行的头,可以同时学习多种不同的、互补的模式。例如,在分析句子“The animal didn't cross the street because it was too tired.”中“it”的指代时,一个头可能专门学习关注局部语法结构(如找最近的名词“street”),另一个头可能专门学习关注长距离的语义关联(如理解“tired”更可能修饰“animal”)。最后,Multi-Head Attention通过拼接和线性变换整合这些不同视角的结果,做出更准确的判断。这种“多专家投票”的机制,极大地增强了模型对复杂语言现象的建模能力。
🔴 从计算复杂度和内存占用的角度,分析Self-Attention/Multi-Head Attention处理超长序列(如n=10000)时面临的挑战,并说明有哪些主流的优化思路?
回答要点:
标准Self-Attention的时间和空间复杂度均为O(n²·d),其中n是序列长度。当n=10000时,注意力矩阵大小为108,这不仅带来巨大的计算量(~1012次浮点运算),更关键的是存储这个巨大的浮点数矩阵需要数十GB的内存,远超主流GPU显存,成为处理长序列的绝对瓶颈。主流优化思路有三类:一是稀疏注意力,如Longformer、BigBird,通过只计算局部窗口或特定模式的注意力对,将复杂度降至O(n·w)或O(n·k),其中w、k是常数。二是线性注意力,如Performer、Linear Transformer,利用核函数近似Softmax,将注意力计算转化为矩阵乘法,复杂度降为O(n·d²),当d<<n时更优。三是分组查询注意力,如GQA,通过减少KV头的数目来压缩推理时的KV缓存内存,提升生成效率。这些方法都是在精度和效率间进行取舍。
🔴 为什么说Multi-Head Attention中的最后一步“拼接+线性变换”是不可或缺的?如果没有它会怎样?
回答要点:
最后一步的“拼接+线性变换”是Multi-Head Attention能够形成统一、有效输出的关键整合步骤。其不可或缺性体现在:第一,信息融合:不同头捕捉的信息(如语法、语义、指代)被拼接后,通过一个可学习的线性层进行融合,而不是简单地堆叠,使得模型能学习如何最优地组合这些不同子空间的特征。第二,维度统一:拼接后的维度是原始维度d_model的h倍,必须通过线性变换降维回d_model,才能与Transformer的残差连接和层归一化结构兼容。如果没有这一步,仅是将拼接后的高维向量直接输出,会导致后续模块维度不匹配,且不同头的信息只是机械拼接,缺乏有效的交互与融合,模型能力会大幅退化,参数量也会不必要的激增。
🔴 假设你要设计一个处理超长文档(10万token)的模型,基于标准Multi-Head Attention的Transformer可能无法直接应用。你会如何改进注意力机制来应对?请从原理上简述1-2种方案。
回答要点:
我会考虑两种主流的高效注意力方案。第一种是稀疏注意力+局部窗口,如设计成“滑动窗口+全局注意力”的混合模式。将序列切分成固定大小的窗口,在窗口内使用标准Self-Attention捕捉局部依赖;同时设置少量(如每64个token一个)的“全局”token,它们可以与序列中所有token交互,从而传播全局信息。这样将复杂度降至O(n·w)。第二种是基于线性注意力的方法。采用如Performer的思路,用随机特征映射来近似Softmax核,将注意力计算转化为(Q'·(K'^T·V))的矩阵链乘形式,避免显式构建n×n矩阵,将复杂度降至O(n·d²)。这两种方案的核心思想都是打破“每个元素必须看到所有元素”的严格约束,在可接受的性能损失下,换取处理超长序列的能力。
