基础 · 06

注意力机制的几何直觉

Query、Key、Value 到底在做什么?拖动鼠标看每个 token 关注谁——一篇文章看懂 Transformer 的灵魂。

15 min read

为什么需要它

把一句话喂给模型之前,每个词会被映射成一个固定的向量——这叫 embedding。问题来了:

"bank" 这个词在 "river bank" 和 "savings bank" 里意思完全不同,但它的 embedding 一开始是同一个

要让模型理解上下文,每个词的表示就必须根据它周围的词动态调整。注意力机制就是干这件事的——它让每个 token 都能"看一眼"句子里的其他 token,然后按需融合信息。

图书馆的查询比喻

想象一个图书馆。你拿着一张提问卡(query),每本书有自己的索引标签(key)内容(value)

  1. 把你的提问卡和每本书的标签对比——算出一个相似度分数。
  2. 分数归一化成百分比(softmax),告诉你应该给每本书多少注意力。
  3. 按这个百分比加权混合所有书的内容,得到回答。

注意力机制做的就是这件事,只不过每个 token 同时扮演三个角色:作为提问者发出 query,作为被查者提供 key 和 value。这一切完全可微分——所有 query / key / value 都是 embedding 经过线性变换得到的,权重可以训练出来。

Q / K / V 的诞生

那「线性变换」具体是怎么把一个 embedding 变成三个东西的?三个学出来的权重矩阵 WQW^QWKW^KWVW^V 分别"提取"同一个 embedding 的不同侧面。点一下 Q / K / V 看效果:

input · x (embedding,dim = 8)

× WQ

Q — Query (dim = 4)

「我想找什么」—— 这个 token 的提问卡。

同一个 embedding,经过三个不同的权重矩阵,变成三种「视角」。

注意——Q、K、V 同源。它们都从同一个 embedding 出发,只是用不同的视角看自己。这就是为什么注意力是「self-attention」:每个 token 都在用自己的三种身份和句子里其他 token 的三种身份打交道。

三步算法

数学上只有三步。设句子有 nn 个 token,每个 embedding 维度是 dd

Q=XWQ,K=XWK,V=XWVQ = X W^Q, \quad K = X W^K, \quad V = X W^V

第一步:每对 (query, key) 做点积,得到 n×nn \times n 的相似度矩阵:

S=QKdkS = \frac{Q K^\top}{\sqrt{d_k}}

第二步:每一行做 softmax,把分数变成概率分布:

A=softmax(S)A = \mathrm{softmax}(S)

第三步:用 AA 给所有 value 加权求和:

Attention(Q,K,V)=AV\text{Attention}(Q, K, V) = A \cdot V

下面这张交互图就是真实跑出来的 AA——句子 "the cat sat on the mat" 里,每个 token 都在看其他 token:

q · k
the
cat
sat
on
the
mat
the
cat
sat
5
40
10
5
5
35
on
the
mat

「sat」 attends to →

the
5%
cat
40%
sat
10%
on
5%
the
5%
mat
35%
鼠标移到左侧 token → 看它在「读」句子里的谁。 默认显示动词 sat —— 它同时看主语 cat 和地点 mat

注意动词 sat——它同时关注主语 cat 和地点 mat。这就是注意力的魔法:它学会了"谁该看谁",而且这套规则是从数据里学出来的,没有人手写过。

换一种视角看同一个矩阵——这次把它画成弧线,更像句法分析图:

the
cat40%
sat
on
the
mat35%
鼠标移到任意 token,弧线宽度 = 它对其他 token 的注意力权重。

为什么除以 dk\sqrt{d_k}

公式里那个 dk\sqrt{d_k} 不是装饰。

dkd_k 很大时(GPT 里通常是 64 或 128),两个随机向量的点积方差会变大——分数会变得很极端。极端的分数喂进 softmax 之后,几乎所有概率会塌缩到最大的那一个上,其他全是 0。这会让梯度几乎消失,模型学不动。

除以 dk\sqrt{d_k} 其实就是把 softmax 的温度调高,让分布柔和。拖一下温度感受这件事:

T1.00
the0.0
5%
cat2.1
40%
sat0.7
10%
on0.0
5%
the0.0
5%
mat2.0
36%
分布的熵 H(p)2.02 bits

熵越大,分布越平均;熵越小,越尖锐。Transformer 默认除以 dk\sqrt{d_k} 就是为了把熵拉到一个梯度能流动的舒服区间。

拖动温度,看 softmax 如何把同一组分数变成完全不同的概率。

T 很小时分布尖锐,T 很大时分布均匀。Transformer 默认把温度设成 dk\sqrt{d_k},让熵落在一个梯度能稳定流动的区间。

多头注意力

一个 head 只能学一种"看"。但语言里同时存在很多关系:主谓、动宾、修饰、指代、位置……Transformer 的做法是同时跑 h 个独立的注意力,每个有自己的 WQW^QWKW^KWVW^V

Head 1

邻近:每个 token 关注前一个

the
cat
sat
mat
the
cat
sat
mat
Head 2

主谓:动词找主语

the
cat
sat
mat
the
cat
sat
mat
Head 3

动宾:动词找宾语

the
cat
sat
mat
the
cat
sat
mat
Head 4

全局:每个 token 都广播

the
cat
sat
mat
the
cat
sat
mat
同一层里 4 个 head 学到了不同的"看"。真实 GPT 模型里每层有 32-96 个 head。

最后把所有 head 的输出拼接,再用一个 WOW^O 投影回原维度。这就是 multi-head attention:用并行换表达力。

前沿里的注意力