Module 1 · Transformer Lesson 06 给朴素版松绑

Query / Key / Value

上一课的朴素注意力有个死板之处:每个词只用一个向量同时干三件事。这一课把这三件事拆成三个专门的向量——这就是 Q / K / V。

TopicQuery / Key / Value 三个投影
Objectives理解朴素版的两个毛病;看 Q/K/V 如何各修一个;知道它们是学出来的
Prerequisites朴素注意力 ✅(点积打分 → softmax → 加权和)
Outcome能说清为什么要三个投影,而不是直接用 embedding
WarningQ/K/V 是同一个词的三个"角色向量",不是三个词

① 先回顾:朴素版哪里不好?

朴素注意力里,每个词的同一个向量 xᵢ 被拿去做了三件不同的事:

发起比较"我在找什么样的词"(当它是主动方时)
被人比较"我是什么样的词,好让别人来匹配我"(当它是被查方时)
提供内容"匹配上之后,我把什么信息交出去"

三个角色被硬绑在一个向量上,带来两个具体毛病:

② 解法:把一个向量拆成三个角色

给每个词的向量 xᵢ三个学出来的矩阵 W_Q, W_K, W_V,投影出三个专门的向量:

Query qᵢ = xᵢ·W_Q"我在找什么" —— 当主动方时用(像搜索词)
Key kᵢ = xᵢ·W_K"我是关于什么的" —— 当被查方时用(像索引标签)
Value vᵢ = xᵢ·W_V"我能提供的信息" —— 匹配上后交出去的内容(像正文)

三个矩阵全模型共用、由训练学出。于是打分和混合都用专门的向量:

打分 sᵢⱼ = qᵢ · kⱼ  →  softmax  →  新(xᵢ) = Σⱼ wᵢⱼ · vⱼ

对比朴素版:xᵢ·xⱼqᵢ·kⱼ;混合 xⱼ → 混合 vⱼ

同一个词向量 xᵢ → 三个角色向量 xᵢ(embedding) ×W_Q ×W_K ×W_V qᵢ 我在找什么 kᵢ 我是什么 vᵢ 我提供什么 每个词都同时拥有自己的 q、k、v
W_Q/W_K/W_V 把一个词向量投影成三个专门角色。三个矩阵是训练学出来的参数。

③ 这样怎么就修好了?

一句话:Q/K/V = 把"找 / 被找 / 给"三个角色各配一个专用、可学习的向量。

⚠️ 别误解: Q、K、V 不是三个 token,而是同一个 token 的三个投影。句中每个词都各自算出自己的 q、k、v。所谓"self"就是 q 和 k、v 都来自同一句话里的这些词。

💬 q / k / v 和原始 x 是什么关系?k 和 v 既然都来自 x,凭什么不一样?(讨论补充)

三者平级——都是 x 经一个学出来的矩阵投影出的"视角":

x ×W_Q → q(我在找什么)
x ×W_K → k(我展示给别人的"标签")
x ×W_V → v(我匹配上后交出的内容)

每个都可以从"几乎等于 x"到"很不一样",由训练决定。k 和 v 的差别不在它们与 x 的关系类型(都是投影),而在用途不同 → 被训练成不同的样子

k去和别人的 q 做点积(打分)→ 被训练成"便于被正确匹配的标签"(广告词)
v匹配后被加权求和进输出 → 被训练成"值得传给别人的内容"(货)

例(it → animal): k(animal) 装"我是可作主语的生物名词"(便于被搜到);v(animal) 装"那只具体的动物:单数、非人称、话题主体"(搜到后真正吸收的内容)。像搜索:你用关键词匹配标题(k),但真正要的是正文(v)

更极端的例(功能词): 逗号 / the 的原始 x 几乎没语义,但模型可让它的 v 交出"句子结构/边界"信号 —— 体现 x(我是谁)和 v(我能给你什么)可以差很远。

收口:q/k/v 是 x 的三个平级投影视角,各因用途(找 / 被找 / 给)被训练成不同样子。诚实边界:浅层里 v 常和 x 差别不大——"分工"是模型可用的自由度,用不用由"怎样预测更准"决定。

💬 模型存的是 W_Q/W_K/W_V 还是投影结果 q/k/v?为什么不预投影好、以空间换时间?(讨论补充)

存 W_Q/W_K/W_V(和 embedding 表),不存 q/k/v。 q/k/v 是运行时用 x·W 现算的中间结果。

为什么不能预存 q/k/v:因为它依赖的 x 不是固定的。 第 1 层的 x 是 embedding(固定),但第 2 层及以后的 x 是上一层 attention 现算出的"带上下文的新向量",取决于整句话、每句不同。所以"某个词的 k"没有一个固定值可存——同一个词在不同句子/不同层,x 都不同。

embedding 表✅ 可存:输入是固定整数 id,查表,组合有限(词表大小)
W_Q/W_K/W_V✅ 可存:学出来的固定参数
q/k/v❌ 不存:依赖运行时的 x,x 随上下文/层变化,无固定值

就算只对第 1 层预存也不划算:词表 ~10 万 × 3 个向量 × 几百维 = 空间爆炸,省下的只是一次矩阵乘法(GPU 最便宜的操作);推理瓶颈是内存带宽,多搬数据反而更慢。

收口:不是"不愿以空间换时间",而是"要换的量不是常量,根本没得换"。真正值得缓存的是一次生成过程中已算出的 k/v(叫 KV Cache,Module 3 讲),不是预先为所有词算好的 k/v。

④ 🅿️ 还差两块(预告,不展开)

不展开,只留名:(1)打分 qᵢ·kⱼ 后面还会除以 √d 再 softmax(缩放,稳定数值);(2)实际会并行开多组 Q/K/V 捕捉不同关系,叫 Multi-head。这两个都在待讲清单里,下面几课讲。

✅ 快速检查(用自己的话答)

  1. 朴素注意力的哪个"死板之处",是 Q/K/V 要解决的?用一句话说。
  2. Query、Key、Value 分别扮演什么角色?为什么打分用 q·k,而混合用 v?
  3. 朴素版打分 xᵢ·xⱼ 是对称的(i 对 j = j 对 i)。为什么换成 qᵢ·kⱼ 后就不对称了?(提示:W_Q 和 W_K 是不是同一个矩阵)

答完这 3 题,下一课 D. 缩放点积(÷√d)——一个很小的数值稳定技巧,然后是 Multi-head。