Self-Attention 学习
深入剖析Self-Attention中最核心、最关键的数学操作:Q, K, V矩阵运算。现代所有大语言模型基础架构的基石。
核心比喻:信息检索系统
想象一个高度智能的图书馆:
- 你(Query):带着一个明确的问题走进图书馆,比如“我想找关于人工智能伦理的哲学论述”。
- 书籍的索引卡(Key):每本书都有一张索引卡,上面有关键词(如“哲学”、“AI”、“伦理”、“技术”)。
- 书籍的实际内容(Value):书架上书籍的完整文本。
工作流程:
- 匹配(打分):将问题(Query)与图书馆里所有书的索引卡(Key)进行比对,看哪本书的索引最符合你的问题。
- 聚焦(权重):发现一些书非常相关(高分),一些一般相关(中等分),一些不相关(低分)。
- 合成(加权求和):不会只借一本最高分的书,而是根据相关性分数,从所有书中提取相关的章节段落(Value),组合成一份定制的研究报告。
这就是Self-Attention所做的:为句子中的每个词,生成一份基于整个句子上下文的定制化新表示。
第一步:从输入到Q, K, V的诞生
假设我们的输入是包含3个词的句子,每个词已经被转换为一个维度为 d_model=4 的向量(例如通过词嵌入层)。
输入矩阵 X (形状:[3, 4])
行 = 词,列 = 特征
[
[x1, x2, x3, x4], # 词1:“苹果”
[x5, x6, x7, x8], # 词2:“很”
[x9, x10,x11,x12] # 词3:“甜”
]
关键:我们不直接使用这些原始向量。为了获得更大的灵活性(让模型可以学习“如何查询”、“如何建立索引”和“提取什么信息”),我们为每个词生成三个新的向量:Q, K, V。
这是通过三个可学习的权重矩阵 W_Q, W_K, W_V 实现的。在训练中,模型会调整这些矩阵的参数。
计算过程:
# 矩阵乘法
Q = X * W_Q # (形状:[3, 4]) * (形状:[4, d_k]) -> [3, d_k]
K = X * W_K # (形状:[3, 4]) * (形状:[4, d_k]) -> [3, d_k]
V = X * W_V # (形状:[3, 4]) * (形状:[4, d_v]) -> [3, d_v]
通常我们设 d_k = d_v = d_model (例如64)。现在我们得到了三个新矩阵:
Q (查询)矩阵,形状:[3, 64]
K (键)矩阵,形状:[3, 64]
V (值)矩阵,形状:[3, 64]
物理意义:
W_Q:学会了“应该提出什么样的问题”。对于一个词,它的Query向量编码了“我需要从其他词那里了解什么信息”。W_K:学会了“应该用什么标签来索引自己”。一个词的Key向量编码了“我能向其他词提供什么信息,我的身份是什么”。W_V:学会了“当被关注时,应该提供什么实质内容”。一个词的Value向量编码了“我的实际、完整的语义信息”。
第二步:计算注意力分数(匹配与打分)
现在,我们要为每个词(作为查询者)计算它与其他所有词(包括它自己)的关联强度。
操作:用当前词的 Query向量,去点积所有词的 Key向量。
点积结果越大,表示两个向量的方向越相似,关联性越强。
矩阵形式(核心公式1):
注意力分数 Scores = Q * K^T
K^T 是K的转置。为什么?
Q形状: [3, 64] (3个查询,每个查询64维)K^T形状: [64, 3] (3个键,每个键64维,转置后列变行)Scores形状: [3, 3] (一个3x3的矩阵)
这个 [3, 3] 的分数矩阵 S 就是注意力权重蓝图:
S = [
[s11, s12, s13], # 词1(苹果)对 词1,词2,词3 的分数
[s21, s22, s23], # 词2(很)对 词1,词2,词3 的分数
[s31, s32, s33] # 词3(甜)对 词1,词2,词3 的分数
]
其中 s23 代表 词2的Query 与 词3的Key 的点积,即“很”有多关注“甜”。
第三步:缩放与归一化(聚焦)
-
缩放:将分数除以
sqrt(d_k)。这是为了稳定梯度。当d_k较大时,点积的结果可能非常大,将Softmax函数推入梯度极小的区域,不利于学习。Scores_scaled = Scores / sqrt(d_k) -
Softmax归一化(核心公式2):
Attention_Weights = Softmax(Scores_scaled, dim=-1)对 每一行 进行Softmax操作。这使得每一行的分数变成一个概率分布(和为1)。
A = [ [a11, a12, a13], # a11 + a12 + a13 = 1 [a21, a22, a23], # a21 + a22 + a23 = 1 [a31, a32, a33] # a31 + a32 + a33 = 1 ]物理意义:
A矩阵的第一行[a11, a12, a13]表示,在合成 词1“苹果” 的新表示时,应该分别以多大的权重(注意力)去吸取词1、词2、词3的信息。
以“苹果很甜”为例,我们期望:- 对于 词1“苹果”:
a13(关注“甜”的权重)会很高。 - 对于 词3“甜”:
a31(关注“苹果”的权重)会很高。
- 对于 词1“苹果”:
第四步:加权求和与输出(合成)
操作:用刚刚得到的注意力权重矩阵 A,对 Value矩阵 V 进行加权求和。
矩阵形式(核心公式3):
Output = Attention_Weights * V
A形状: [3, 3]V形状: [3, 64]Output形状: [3, 64]
让我们看看这是如何为每个词工作的:
-
词1“苹果”的新向量 =
a11 * V1+a12 * V2+a13 * V3
它等于一小部分自己(V1) + 一小部分“很”(V2) + 一大部分“甜”(V3)
结果:新的“苹果”向量包含了“甜”的语义! -
词3“甜”的新向量 =
a31 * V1+a32 * V2+a33 * V3
它等于 一大部分“苹果”(V1) + 一小部分“很”(V2) + 一小部分自己(V3)
结果:新的“甜”向量包含了“苹果”的语义!
最终输出是一个形状为 [3, 64] 的矩阵,其中每一行都是一个词融合了全局上下文信息后的全新表示。这才是传给神经网络下一层的真正输入。
整合公式与总结
将上述四步合并,得到最经典的Self-Attention公式:
Attention(Q, K, V) = softmax( (Q K^T) / √d_k ) V
为什么需要三个独立矩阵?
这是设计的精妙之处,它赋予了模型巨大的灵活性:
- 解耦了“匹配”和“提取”:
Q和K负责计算关联性(应不应该关注),V负责提供被提取的实质内容(关注后拿什么)。 - 想象一下:如果
K == V,那么一个词的“索引标签”就必须和它的“全部内容”严格绑定,这限制了模型的表达能力。分开后,模型可以学会:虽然“苹果”和“甜”的Key(索引标签)高度匹配,但从“甜”的Value中提取的可能是“正向味觉感受”这种更抽象的信息,而非“甜”字本身。 - 这类似于在搜索引擎中,用来查询的关键词(Q)和网页的元标签(K)进行匹配,但最终呈现的是网页的摘要和内容(V),而元标签本身并不直接作为内容显示。
下一步:多头注意力
理解了单头Self-Attention后,多头注意力(Multi-Head Attention) 就很简单了:
- 就是将上述过程并行执行多次(例如8次,即8个头)。
- 每次使用 不同的
W_Q^i, W_K^i, W_V^i矩阵,从而将输入投影到不同的子空间。 - 每个头都会产生一个
[3, d_v]的输出。 - 将8个头的输出拼接起来,再通过一个线性层
W_O融合,得到最终的输出。
好处:就像CNN中使用多个滤波器可以捕捉不同纹理一样,多个注意力头可以让模型同时关注来自不同位置、不同子空间(如语法、语义、指代关系)的信息。一个头可能专门学习指代关系(“它”->“苹果”),另一个头可能专门学习修饰关系(“甜”->“苹果”)。
详细拆解,真正掌握Q、K、 V的运算精髓。理解Transformer,是现代LLM的最重要一部分。
浙公网安备 33010602011771号