Transformer核心创新:自注意力,一文搞懂自注意力机制
Transformer核心创新:自注意力,一文搞懂自注意力机制
Transformer的出现彻底改变了自然语言处理领域,成为目前大模型的基石,其核心创新——自注意力机制,赋予了模型动态聚焦的能力。自注意力机制让模型在处理序列时,能够同时关注所有位置的信息,从而捕捉长距离依赖关系,提升生成效果。本文将结合具体示例,详细讲解自注意力机制的原理和运作方式,帮助读者清晰理解这一技术的魔力。
什么是自注意力机制
自注意力机制是一种在深度学习中用于处理序列数据的技术,能够动态地捕捉序列中不同元素之间的依赖关系。最早在 2017 年由 Google 的研究团队在论文《Attention is All You Need》中提出,并成为 Transformer 模型的核心组成部分,它的核心思想是通过计算序列中每个元素与其他元素之间的相似度(注意力权重),从而为每个元素生成一个全局上下文的表示。
相比于传统序列模型(如 RNN 和 LSTM),自注意力机制解决了传统序列模型(如 RNN 和 LSTM)在处理自然语言任务时的一个主要痛点:
- 长距离依赖问题:在自然语言中,单词之间的依赖关系可能跨越很长的距离。例如,在句子“The cat sat on the mat because it was tired.”中,“it”指代的是“cat”,而不是“mat”。自注意力机制能够直接捕捉这种远距离依赖关系,而无需逐步传递信息。
自注意力机制中的 QKV 是什么?
在 Transformer 模型中,Q(Query)查询向量、K(Key)关键向量和 V(Value)值向量是自注意力机制(self-attention mechanism)的核心组成部分。
定义:
Q 向量:表示当前元素的查询向量,用于在序列中查找相关信息。
K 向量:表示所有元素的关键字向量,用于存储每个元素的信息,供 Q 进行查询。
V 向量:表示所有元素的值向量,包含了实际的信息内容,这些信息将根据 Q 和 K 的相似度(注意力权重)进行加权求和。
如何生成 QKV:
假设输入序列为一系列词,首先通过 embeding 将这些词转化为固定维度的向量表示(嵌入向量)Dx。对于每个嵌入向量,通过三个不同的线性变换(即 Query、Key、Value 变换)得到三个向量 Q、K、V。这些变换由三个可训练的权重矩阵 Wq、Wk、Wv 实现(不同的大模型这三个权重矩阵不同)。
编码器中如何计算自注意力
在编码器中,自注意力机制用于计算每个单词与其他单词之间的相关性。举个例子,现在需要将输入的句子:"我爱打球",翻译成英语输出。
"我爱打球"这个输入的每个单词的向量被作为查询、键和值输入到自注意力层中。然后计算每个单词与其他单词之间的相关性得分,得分越高表示两个单词之间的相关性越大。最后,这些得分对值进行加权平均,生成一个加权向量,表示每个单词与其他单词的相关性。这个加权向量有助于编码器更好地理解输入序列的语义信息,从而提高输出的准确性。
具体来说,对于输入句子"我爱打球",我们可以按照以下步骤计算自注意力:
- 将每个单词的向量转化成查询(Q)、键(K)和值(V)输入到自注意力层中
- 使用查询向量(Q)和键向量(K)计算注意力得分,得分越高表示两个单词之间的相关性越大
查询向量和键向量计算注意力得分如下所示
- 我 -> [0.9, 0.4, 0.2, 0.1]
- 爱 -> [0.4, 0.8, 0.3, 0.2]
- 打 -> [0.2, 0.3, 0.6, 0.4]
- 球 -> [0.1, 0.2, 0.4, 0.9]
这里的得分表示了每个单词与其他单词之间的相关性,例如"我"与"爱"之间的得分为 0.5,表示两个单词之间的相关性较低,而"我"与"球"之间的得分为 0.1,表示两个单词之间的相关性更低。
- 对注意力得分进行归一化,得到每个单词与其他单词之间的相关性得分。
- 将相关性得分作为权重对值(V)进行加权平均,得到每个单词与其他单词的加权向量。这个向量包含了每个单词在上下文中的语义信息。
上述得分矩阵作为中间权重,用于融合 V(值)向量,最终生成一个 512 维的向量。当中文序列“我”“爱”“打”“球”通过编码器处理后,每个词会生成一个 512 维的上下文向量。因此,编码器的输出为四个向量矩阵:
[V_ 我, V_ 爱, V_ 打, V_ 球]。
这些向量不仅包含了每个词本身的语义信息,还融合了上下文关系。例如,“打”与“球”之间的动宾关联也被编码在这些向量中,从而更好地捕捉句子的整体语义。
解码器中如何生成输出内容
生成第一个字
这里重点说明一下解码器生成"I"的具体过程
初始输入与 Query 来源
解码器的初始输入是起始符(这个是大模型的标准做法),通过词嵌入层将 转换为一个 512 维的向量,记为 Q_。此时,Query 矩阵(Q)仅包含的向量 [Q_],其维度为 1×512。这个向量将作为解码器生成第一个词的起点。 掩码自注意力计算:在下面生成多个内容部分详细说明
交叉注意力(Encoder-Decoder Attention)
在编码器-解码器注意力层中,解码器通过以下步骤与编码器的 Key/Value 向量进行匹配
- 点积计算相似度
解码器的 Query 向量 Q_ 与编码器输出的 4 个 Key 向量(V_ 我, V_ 爱, V_ 打, V_ 球)分别计算点积,得到相似度得分。计算公式为:
其中,K_i 是编码器输出的第 i 个向量,d_k 是向量的维度(这里为 512)。通过点积计算,可以得到与每个 Key 向量的相似度得分,生成一个一维向量矩阵:
[score_1, score_2, score_3, score_4]。
- Softmax 归一化
对上述得分进行 Softmax 归一化,将得分转换为概率分布。假设归一化后的权重分布为 [0.85, 0.1, 0.04, 0.01],这表明""与“我”的语义关联最强,权重为 0.85,而与其他词的关联较弱。
为什么
这个跟的语义有关,前面提到
加权融合与输出生成
Value 加权求和
以“我”的权重 0.85 为主导,对编码器的 Value 向量进行加权求和,生成 Context 向量。计算公式为:
Context=0.85⋅V 我+0.1⋅V 爱+0.04⋅V 打+0.01⋅V 球
最终得到的 Context 向量主要携带“我”的语义特征,同时融合了少量其他词的语义信息。
- 概率映射
Context 向量是编码器输出经过注意力加权后的融合结果,例如在生成"I"时,该向量携带了"我"的核心语义(权重 0.85)以及"爱""打""球"的辅助语义(权重 0.1/0.04/0.01)。这种向量本质上是 512 维语义空间的非线性映射,每个维度对应不同粒度的语义特征(如词性、句法角色等)。
Context 向量通过解码器的前馈网络(Feedforward Network)和 Softmax 层,映射到英文词表上。Softmax 层会计算每个英文词的概率分布,并选择概率最高的词作为输出。在这个例子中,“I”的概率最高,因此解码器生成“I”作为第一个词。
生成后续内容
上述是生成第一个字“I”,然后递归,将"
Query 矩阵(Q)、Key 矩阵(K)和 Value 矩阵(V)的生成
解码器的输入"I "后,其中 是序列起始符,I 是已生成的第一个词。 和 I 首先通过词嵌入层转换为高维向量(如 512 维)。 然后分别生成 Q K V 矩阵 掩码矩阵的生成
为了确保 I 只能关注,而不能关注未来的词,使用一个掩码矩阵 M。对于输入I,掩码矩阵是一个下三角矩阵,形状为 2×2(序列长度为 2,掩码矩阵随着递归输入序列增加而增加,例如输入序列长度为 3,则掩码矩阵为 3x3)。
其中,1 表示允许关注,0 表示禁止关注。
- 第一行表示只能关注自身。
- 第二行表示我可以关注和我自身。
- 掩码自注意力计算
这个环节与编码器里面的计算方式一样,计算 Query 矩阵 Q 与 Key 矩阵 K 的点积得分矩阵 S,将掩码矩阵 M 与得分矩阵 S 按位相乘,屏蔽未来位置的信息。引入上面的例子展开说明递归输入解码器中的序列为:“我爱打”, 经过自注意力计算得分,输出以下矩阵。
我 -> [0.9, 0.4, 0.2]
爱 -> [0.4, 0.8, 0.3]
打 -> [0.2, 0.3, 0.6]
上述矩阵是每个字与其他几个字包含自己的关联得分,而乘上掩码矩阵,就是让每个字只关注自己和之前的字,跟后面生成字的关系就屏蔽掉,即变成下面这样
我 -> [0.9, 0, 0]
爱 -> [0.4, 0.8, 0]
打 -> [0.2, 0.3, 0.6]
掩码矩阵作用是什么,其实在推理场景没有啥作用,纯粹就是为了保证推理与训练的一致性在推理阶段,模型是逐词生成目标序列的,未来的词尚未生成,因此不存在“偷看”的问题。然而,掩码机制在推理阶段仍然被使用,主要是为了保持与训练阶段的计算一致性,确保推理时的行为与训练时完全匹配
交叉注意力(Encoder-Decoder Attention),这个环节与编码器里面的计算方式一样 .
再经过 Softmax 归一化、加权求和,生成的输出向量包含了I 的上下文信息,再到解码器-编码器自注意力层,与编码器的 Key/Value 向量进行自注意力计算,这部分与生成第一个 I 字一样,这里不赘述。
总结
通过上文可以看出自注意力机制贯穿整个 Transformer 模型,在编码器(Encoder)与解码器(Decoder)中都需要该机制,但功能侧重点不同:
- 编码器的自注意力计算:编码器通过自注意力处理输入序列,动态捕捉序列中每个元素与其他元素的全局依赖关系,形成包含上下文语义的向量表示。
- 解码器的双重注意力计算:
- 掩码自注意力:在生成当前词时,仅允许关注已生成的词(如“ I”中的“I”只能关注“”),通过下三角掩码矩阵屏蔽未来位置的信息。
- 交叉注意力(Encoder-Decoder Attention):解码器的 Query 与编码器的 Key/Value 进行交互,例如在翻译任务中,解码器生成“I”时会从编码器输出的中文向量(如“我”“爱”“打”“球”)中提取语义权重,融合生成目标语言表示。
我们都知道大模型算力需求高,其中一个原因就是自注意力机制,自注意力机制的复杂度为 O(n2),因其需计算序列中每对元素之间的相似度(如长度为 n 的序列需计算 n×n 次点积),随着序列长度增加(如处理长文本或高分辨率图像),计算量呈平方级增长,导致大模型对 GPU 显存和算力要求极高。例如,处理 1000 词序列需约 100 万次点积运算,而扩展到数万词时算力需求急剧攀升。 自注意力机制其实是通过牺牲了部分计算效率,换来了更强的语义捕捉能力和并行性。
说明:上述过程其实有些简化,例如 Transformer 用到了多头自注意力机制,上面没有展开,本文主要是让读者了解自注意力机制,多头自注意力本质是在自注意力上的优化,后续再展开说明。