Q, K, V 都来自同一个输入序列,那么如何使用先验知识

张开发
2026/4/17 3:11:54 15 分钟阅读

分享文章

Q, K, V 都来自同一个输入序列,那么如何使用先验知识
Q是我要什么K是我有什么特征V是我的实际内容。Q、K、V矩阵本身并非先验知识但生成它们的投影矩阵Wᴼ、Wᴷ、Wᵛ 是模型从数据中学到的先验知识。让我详细拆解这个过程 从输入到Q、K、V的完整流程1.原始输入词嵌入 位置编码输入序列: [x₁, x₂, ..., xₙ] # 每个x是d_model维向量2.学习的投影矩阵模型学到的先验知识# 这些是模型训练得到的参数矩阵W_Qnn.Linear(d_model,d_k)# 形状: (d_model, d_k)W_Knn.Linear(d_model,d_k)# 形状: (d_model, d_k)W_Vnn.Linear(d_model,d_v)# 形状: (d_model, d_v)# 可选的输出投影W_Onn.Linear(d_v,d_model)# 形状: (d_v, d_model)这些矩阵的本质它们是注意力机制的可学习透镜训练过程中通过反向传播学习代表了模型应该如何看输入数据的不同方面3.生成Q、K、V# 同一个输入X经过不同的投影QX W_Q# Query: 我们寻找什么KX W_K# Key: 每个位置提供什么特征VX W_V# Value: 每个位置的实际内容核心洞见虽然Q、K、V来自同一输入但Wᴼ、Wᴷ、Wᵛ 给它们赋予了不同的语义角色。 不同投影矩阵学到的先验知识Wᴼ生成Q学到的“在当前位置我应该关注什么样的特征”实际学习内容哪些语法/语义特征在当前上下文最重要例如是关注主语-动词一致性还是形容词-名词搭配Wᴷ生成K学到的“我有什么特征可以被其他位置关注”实际学习内容如何展示自己的可被关注性例如动词形态、时态信息、语义角色标注Wᵛ生成V学到的“我的实际信息内容应该如何被表达”实际学习内容信息的浓缩和重新表达保留语义核心过滤无关细节 为什么同一个输入要学三个投影这实际上是注意力最精妙的设计之一分离原因直觉解释类比解耦关注与被关注我关心什么(Q) vs 我能提供什么(K)找工作时你的需求(Q) vs 公司要求(K)信息分层匹配特征(K)可以简单但内容(V)要丰富书索引(关键词K) vs 书内容(V)计算效率匹配用低维(K)内容用高维(V)用ISBN号找书(K)但看书内容(V) 具体学习实例分析假设处理句子“猫 追 老鼠”训练后Wᴼ、Wᴷ、Wᵛ 学到的模式# 计算追这个位置的注意力X[embed(猫),embed(追),embed(老鼠)]Q_追embed(追) W_Q# 学到的追应该关注动作执行者和目标# 可能的Q特征[动作, 及物性, 方向]K_猫embed(猫) W_K# 学到的猫能提供的特征# 可能的K特征[生物, 施事者, 动物]K_老鼠embed(老鼠) W_K# 学到的老鼠能提供的特征# 可能的K特征[生物, 受事者, 动物]V_猫embed(猫) W_V# 学到的猫的信息内容# 比K更丰富[猫科动物, 宠物, 捕食者, ...]# 注意力计算# score(追→猫) Q_追·K_猫 ≈ 高 (施事匹配)# score(追→老鼠) Q_追·K_老鼠 ≈ 高 (受事匹配)# 最终输出包含猫和老鼠的信息 训练过程中的演化训练初期随机初始化W_Q, W_K, W_V 几乎是随机矩阵 注意力权重近乎均匀分布 模型不知道该关注什么训练中期模型开始学习 - 语法结构主语-动词-宾语 - 语义关联同义词、反义词 - 距离衰减较近的词更相关训练后期收敛W_Q, W_K, W_V 编码了复杂的语言知识 - 句法依赖主谓一致 - 语义角色施事、受事、工具 - 篇章结构指代、连贯性 从左右手互搏到自我反思您用左右手互搏形容很形象但我更倾向于理解为**“自我反思”**第一阶段特征提取不同视角Q从我这个位置看应该关注什么K从我这个位置看我能提供什么特征第二阶段信息交换注意力计算# 每个位置问所有人谁的特征和我最匹配# 根据匹配程度聚合所有人的信息第三阶段信息整合输出# 每个位置都获得了全局视角# 输出是自我 他人相关部分的融合 关键洞见真正的先验是投影矩阵不是Q/K/V本身分离Q/K/V让模型学会提问和回答而不只是简单匹配多头注意力多个投影矩阵学不同的关注策略跨层共享不同Transformer层的Wᴼ、Wᴷ、Wᵛ 是分开学习的高层学到更抽象的模式如何理解词嵌入和位置编码 词嵌入让计算机理解词义基本概念词嵌入是将离散的单词符号转换为连续的向量表示。你可以把它看作一本数字化的词典每个词对应一个高维向量一个语义坐标系相似的词在向量空间中位置相近模型的第一印象输入层的核心表示直观理解假设我们用3维向量表示实际是几百维国王 → [0.8, 0.2, 0.9] 王后 → [0.7, 0.3, 0.85] # 与国王接近 苹果 → [0.1, 0.9, 0.2] # 远离国王 梨子 → [0.15, 0.88, 0.25] # 靠近苹果经典例子词向量关系国王 - 男人 女人 ≈ 王后 [0.8,0.2,0.9] - [0.7,0.1,0.3] [0.3,0.9,0.1] ≈ [0.4,1.0,0.7] ≈ 王后在Transformer中的实现# 词汇表大小V嵌入维度d_modelembedding_layernn.Embedding(num_embeddingsV,embedding_dimd_model)# 输入单词的索引 [batch_size, seq_len]input_ids[101,2054,2003,1037,...]# 如[CLS], hello, world, ...# 输出词嵌入向量 [batch_size, seq_len, d_model]word_embeddingsembedding_layer(input_ids) 位置编码告诉Transformer词序问题背景纯注意力机制是排列不变的如果不告诉模型词的位置信息它会认为狗追猫 和 猫追狗 是一样的 我不喜欢你 和 你不喜欢我 是一样的这显然是错的我们需要编码位置信息。解决方案位置编码给每个位置一个唯一的地址加到词嵌入上。Transformer使用的正弦位置编码这是Transformer论文的经典设计defget_positional_encoding(seq_len,d_model):生成正弦位置编码petorch.zeros(seq_len,d_model)positiontorch.arange(0,seq_len).unsqueeze(1)# [seq_len, 1]div_termtorch.exp(torch.arange(0,d_model,2)*-(math.log(10000.0)/d_model))pe[:,0::2]torch.sin(position*div_term)# 偶数维度用sinpe[:,1::2]torch.cos(position*div_term)# 奇数维度用cosreturnpe# [seq_len, d_model]可视化位置编码矩阵位置1: [sin(1×ω₁), cos(1×ω₁), sin(1×ω₂), cos(1×ω₂), ...] 位置2: [sin(2×ω₁), cos(2×ω₁), sin(2×ω₂), cos(2×ω₂), ...] 位置3: [sin(3×ω₁), cos(3×ω₁), sin(3×ω₂), cos(3×ω₂), ...] ... 其中 ω_k 1/10000^(2k/d_model)为什么用正弦/余弦相对位置可学习PE(posk) 可以表示为 PE(pos) 的线性函数 便于模型学习相对位置关系长度外推可以处理比训练时更长的序列周期性但不同每个位置编码都不同 在Transformer中的完整流程输入处理流水线classTransformerInput(nn.Module):def__init__(self,vocab_size,d_model,max_len):super().__init__()self.word_embeddingnn.Embedding(vocab_size,d_model)self.position_encodingget_positional_encoding(max_len,d_model)defforward(self,input_ids):# 1. 词嵌入word_embedsself.word_embedding(input_ids)# [batch, seq, d_model]# 2. 位置编码seq_leninput_ids.size(1)pos_embedsself.position_encoding[:seq_len,:]# [seq, d_model]# 3. 相加combinedword_embedspos_embeds# [batch, seq, d_model]returncombined例子处理句子 “I love NLP”输入索引: [101, 1045, 2293, 17953] # [CLS], I, love, NLP 步骤1 - 词嵌入 [CLS] → [0.1, 0.2, ..., 0.9] I → [0.3, 0.1, ..., 0.4] love→ [0.8, 0.6, ..., 0.2] NLP → [0.2, 0.7, ..., 0.5] 步骤2 - 位置编码 位置0 → [sin(0), cos(0), sin(0.01), cos(0.01), ...] 位置1 → [sin(1), cos(1), sin(1.01), cos(1.01), ...] 位置2 → [sin(2), cos(2), sin(2.01), cos(2.01), ...] 位置3 → [sin(3), cos(3), sin(3.01), cos(3.01), ...] 步骤3 - 相加 love的最终表示 love的词义([0.8,0.6,...,0.2]) 位置2的信息([sin(2),cos(2),...]) 位置编码的演进1.绝对位置编码原始Transformer正弦/余弦函数固定不可学习2.可学习位置编码BERT等使用self.pos_embeddingnn.Embedding(max_len,d_model)# 像学习词嵌入一样学习位置嵌入更灵活但无法外推到更长的序列3.相对位置编码T5、DeBERTa等使用不编码绝对位置第几个词编码词对之间的相对距离如“相邻”、相隔2个词等4.旋转位置编码RoPELlama、GPT-NeoX使用# 通过旋转矩阵编码相对位置# 在复数空间进行旋转更好的长度外推性现在的SOTA选择 词嵌入 vs 位置编码对比总结方面词嵌入位置编码目的编码语义信息编码位置信息性质可学习参数固定函数/可学习维度与模型维度相同与模型维度相同组合方式相加与词嵌入相加例子猫→[0.8,0.2,0.9]位置3→[sin(3),cos(3)…]关键特性相似词向量相近相对位置可线性表示 为什么这个设计如此重要词嵌入解决了离散到连续符号→向量语义相似性“猫≈猫咪”多义词“苹果”(公司)和苹果(水果)不同向量位置编码解决了顺序感知知道狗咬人≠人咬狗距离建模近的词通常更相关结构信息句法树、依赖关系 一个生动的比喻想象你在一个巨大的图书馆词嵌入 每本书的内容摘要物理学书有力、能量等词小说有爱情、冒险等词位置编码 每本书的书架位置三楼A区5排2架告诉你在图书馆的绝对位置相加后 你知道这本书的内容位置但Transformer还能通过位置推测相邻的书可能相关同一主题特定位置可能是参考书区这就是Transformer理解语言的开始它看到的不是孤立的词而是带有位置信息的语义向量这让自注意力能够建立词与词之间的精确关系。没有位置编码Transformer只是词袋模型有了位置编码它才真正理解了语言的结构

更多文章