Self-Attention 中 Q、K、V 分别是什么意思?

Self-Attention 中 QKV 是什么意思?为什么要除以根号 dk?
我们已经知道,Embedding 把文字变成了一串数字向量。但问题是:这些向量拿到手里之后,下一步该做什么?
一个朴素的想法是:让它们互相"聊聊天"。
每个词向量不仅要知道"自己是谁",还要知道"我该听谁的"。这正是 Self-Attention 要解决的核心问题。
QKV 就是在回答三个灵魂拷问
Self-Attention 的公式看起来复杂:
Attention(Q, K, V) = softmax(QK^T / √dk)V
但拆开来看,它只做了三件事:查询、匹配、取值。
你要找什么?(Query)
Query 是"查询"。
每个 token 在做 Attention 的时候,心里都在问一个问题:"我需要从别人那里获取什么信息?"
比如在"我爱吃苹果"这句话里,"爱"这个字要做 Attention,它会生成一个 Query 向量,代表它此刻的需求:"我需要知道是谁在爱?爱什么?"
这个 Query 就是当前 token 对世界的"提问"。
你能提供什么?(Key)
Key 是"键"。
每个 token 同时会生成一个 Key 向量,代表"我能提供什么信息"——本质上是一种"自我介绍"或"索引标签"。
"苹果"的 Key 会描述自己:"我是一种水果"、"我是红色的"、"我可以吃"。
系统会把"爱"的 Query 和所有 token 的 Key 做比较,找到"爱"最应该关注哪些词。
最终拿到什么?(Value)
Value 是"值"。
当 Query 和 Key 匹配成功之后,系统会提取对应 token 的 Value——这是真正要被加权汇总的内容。
注意:Key 决定"要不要关注",Value 才是最终"拿到的内容"。
这两个设计是分开的。一个词可以"很擅长回答某个问题"(Value 丰富),但它的"自我介绍"可能很低调(Key 匹配度低)。

用一个生活场景来理解:你走进图书馆,想找一本关于烹饪的书。
- Query 是你填写的搜索词:"简单家常菜食谱"
- Key 是每本书的分类标签:"川菜"、"烘焙"、"快手菜"
- Value 是书的实际内容:菜谱正文
系统拿你的搜索词去匹配所有书的标签,找到最相关的几本,再把它们的正文内容呈现给你。
Query 决定"我要问什么",Key 决定"谁能回答",Value 才是"答案本身"。
QKV 从哪来?三个矩阵的诞生
现在你理解了 QKV 的含义,但新的问题来了:这些 Query、Key、Value 是怎么从输入向量变出来的?
线性变换生成三兄弟
输入的词向量 X,会分别和三个可学习的权重矩阵相乘:
Q = X × Wq
K = X × Wk
V = X × Wv
这三个权重矩阵 Wq、Wk、Wv 是模型参数,在训练过程中不断更新。

为什么要三个矩阵,而不是一个?
这是个很关键的设计问题。
你可以想象:一个演员走进化妆间,对着三面不同的镜子。
- 镜子 A 照出"我今天想演什么角色"——这是 Query
- 镜子 B 照出"我本身是什么气质"——这是 Key
- 镜子 C 照出"我有哪些特长可以展示"——这是 Value
三面镜子映出不同的自己,因为"提问者"、"被问者"、"内容贡献者"需要呈现不同的侧面。
如果只用同一个矩阵,这三个身份就混在一起了,模型就没有足够的自由度去捕捉复杂的依赖关系。
维度可以不一样
在 Multi-Head Attention 中(这是下一篇要详细讲的),不同的注意力头甚至可以使用不同的 QKV 维度。但无论如何,Query 和 Key 的维度必须保持一致,因为它们要做点积比较。
为什么要除以根号 dk?梯度消失的陷阱
现在进入最核心的问题:为什么非要在 QK^T 后面除以 √dk?
要回答这个问题,我们需要先理解不除会怎样。
当数字太大,softmax 就"躺平"了
假设输入向量经过处理后,Q 和 K 的各维度均值是 0、方差是 1(这通常由 Layer Normalization 保证)。
那么 QK^T 的点积结果,每个元素的均值也是 0,但方差是多少?
答案是 dk。
当 dk = 512 时,QK^T 的数值标准差约为 √512 ≈ 22.6。
22.6 是什么概念?这已经是非常大的数值了。
当我们把这个大数值扔进 softmax:
- 最大的那个值会"一骑绝尘",输出逼近 1
- 其他所有值都"被碾压",输出逼近 0
softmax 变成了一个"非此即彼"的阶跃函数,而不是"各有高低"的概率分布。

这为什么是灾难?因为梯度消失了
神经网络的训练靠的是反向传播——Loss 对每个参数的梯度指导着更新的方向。
softmax 的梯度有一个特性:
∂softmax/∂x = softmax(x) × (1 - softmax(x))
当 softmax 输出接近 1 的时候,这个梯度值趋近于 0。
梯度等于 0 意味着什么?
意味着无论你怎么调整参数,模型都"感觉不到"自己错在哪了。
就像一道判断题只有"全对"和"全错"两种结果,没有中间地带,学生无法从错误中学习"哪里需要改进"。
这就是深度学习最头疼的问题——梯度消失。
为什么是根号 dk?一个漂亮的归一化
现在问题变成了:怎么把 QK^T 的数值缩放到合理范围?
证明它确实有效
让我们做一道数学题:
- 假设 Q 和 K 的各维度相互独立,均值 μ=0,方差 σ²=1
- QK^T 的每个元素 = Σ(qi × ki),是 dk 个独立随机变量的和
- 根据概率论,两个独立变量的乘积方差 = σ²q × σ²k = 1
- dk 个方差为 1 的变量相加,方差 = dk
所以 QK^T 的方差是 dk,标准差是 √dk。
除以 √dk 之后,方差恢复到 1,和原始输入分布一致。
这就是 √dk 的来源——它不是一个拍脑袋的参数,而是从统计学推导出来的归一化因子。

类比一下:弹簧的弹性系数
想象一根被过度拉伸的弹簧。弹簧本身没问题,只是被拉得太长了,失去了弹性。
你要做的不是把它压缩,而是让它恢复到原始长度。
√dk 的作用就是这样:它不是"减小"注意力,而是让 softmax 的输入保持在"有意义的范围"内,确保模型能够正常学习。
这不是唯一答案,但它是最佳实践
严格来说,"除以 √dk"本质上是一个"温度参数"的特殊取值。
你完全可以除以 2dk,或者乘以一个可学习的系数。√dk 只是一个经验上效果最好的选择。
Transformer 原始论文选择这个值,更多是出于"让初始化阶段保持稳定"的目的。
面试官还会追问什么
理解了 QKV 和 √dk 的原理,下面这些延伸问题也值得准备。
问题一:Q 和 K 为什么需要不同的权重矩阵?
如果 Wq 和 Wk 完全相同,Query 和 Key 就是同一个向量。这会导致什么问题?
模型会倾向于"关注自己"——因为自己的 Query 和自己的 Key 完全匹配,相似度永远是最高的。
这会让 Attention 退化成"自恋模式",每个 token 只关注自己,失去了捕获词际关系的能力。
分离 Wq 和 Wk,正是为了避免这种退化。
问题二:除以 √dk 是最优选择吗?
不是。√dk 是一个经验公式,在 Transformer 早起被证明有效。
后续的研究提出了很多变体:
- 可学习的缩放因子
- RMSNorm 替代 softmax 前的归一化
- 不同的温度参数
但 √dk 依然是默认选择,因为它简单、有效、理论基础扎实。
问题三:Attention 的计算复杂度是多少?
对于序列长度 n、维度 d,单层 Self-Attention 的复杂度是 O(n² × d)。
n² 是因为每个 token 要和所有其他 token 做比较。
这就是为什么长上下文对大模型是个挑战——序列长度翻倍,计算量不是翻倍,而是变成四倍。

理解完 QKV 和 √dk 的原理,你会发现整个 Attention 机制的设计非常优雅:
每个 token 既是提问者,也是回答者;通过 Query 询问需求,通过 Key 展示自己,通过 Value 贡献内容;而 √dk 则像一个精密的调压器,确保这个问答系统始终运转在"可以学习"的状态。
当然,一个注意力头能捕捉的信息是有限的。这就是为什么 Transformer 引入了 Multi-Head Attention——用多个注意力头并行工作,捕捉不同类型的关系。
多个注意力头是怎么协作的?每个头的 QKV 维度怎么分配?为什么大模型的 KV Cache 会成为性能瓶颈?
这些问题,我们留到下一篇继续。
