Self-Attention 学习

深入剖析Self-Attention中最核心、最关键的数学操作:Q, K, V矩阵运算。现代所有大语言模型基础架构的基石。


核心比喻:信息检索系统

想象一个高度智能的图书馆:

  • 你(Query):带着一个明确的问题走进图书馆,比如“我想找关于人工智能伦理的哲学论述”。
  • 书籍的索引卡(Key):每本书都有一张索引卡,上面有关键词(如“哲学”、“AI”、“伦理”、“技术”)。
  • 书籍的实际内容(Value):书架上书籍的完整文本。

工作流程

  1. 匹配(打分):将问题(Query)与图书馆里所有书的索引卡(Key)进行比对,看哪本书的索引最符合你的问题。
  2. 聚焦(权重):发现一些书非常相关(高分),一些一般相关(中等分),一些不相关(低分)。
  3. 合成(加权求和):不会只借一本最高分的书,而是根据相关性分数,从所有书中提取相关的章节段落(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 的点积,即“很”有多关注“甜”。


第三步:缩放与归一化(聚焦)

  1. 缩放:将分数除以 sqrt(d_k)。这是为了稳定梯度。当 d_k 较大时,点积的结果可能非常大,将Softmax函数推入梯度极小的区域,不利于学习。

    Scores_scaled = Scores / sqrt(d_k)
    
  2. 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(关注“苹果”的权重)会很高。

第四步:加权求和与输出(合成)

操作:用刚刚得到的注意力权重矩阵 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

为什么需要三个独立矩阵?
这是设计的精妙之处,它赋予了模型巨大的灵活性:

  1. 解耦了“匹配”和“提取”QK负责计算关联性(应不应该关注),V负责提供被提取的实质内容(关注后拿什么)。
  2. 想象一下:如果 K == V,那么一个词的“索引标签”就必须和它的“全部内容”严格绑定,这限制了模型的表达能力。分开后,模型可以学会:虽然“苹果”和“甜”的Key(索引标签)高度匹配,但从“甜”的Value中提取的可能是“正向味觉感受”这种更抽象的信息,而非“甜”字本身。
  3. 这类似于在搜索引擎中,用来查询的关键词(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的最重要一部分。

posted on 2026-01-26 16:21  zhangkele  阅读(7)  评论(0)    收藏  举报

导航