自注意力:让每个词自己去看全文
约 14 分钟
第一章讲过注意力机制。这一节讲它的关键变形——自注意力(self-attention),这是 Transformer 的全部起点。
先说 RNN 的两个死穴
处理一句话时,RNN 从左到右一个词一个词地读,把信息压进一个隐状态里传下去。这带来两个无法回避的问题:
① 长距离依赖会衰减。 「我小时候住在法国……(中间几十个词)……所以我会说流利的 ___」。要填「法语」,必须记住几十步之前的「法国」,但信息在逐步传递中不断稀释。LSTM 缓解了这个问题,没有根治。
② 无法并行。 第 步必须等第 步算完。句子有多长,就得串行多少步——这在 GPU 时代是致命的,因为 GPU 的强项恰恰是同时算一大批。
自注意力的解法:每个词直接看所有词
不再逐步传递,而是让句子里任意两个词直接建立联系。「法语」和「法国」之间的距离,从几十步变成一步。
而且所有词的计算可以同时进行——两个问题一起解决了。
Q、K、V:一次「查资料」的过程
每个词的向量分别乘三个可学习的矩阵,得到三个角色:
| 角色 | 含义 | 类比 |
|---|---|---|
| Query(查询) | 我想找什么 | 你在搜索框里输入的词 |
| Key(键) | 我是什么 | 每篇文档的标题 |
| Value(值) | 我的实际内容 | 文档正文 |
计算过程:
- 用我的 Q 去和所有词的 K 算点积 → 得到「我和每个词有多相关」
- 除以 ,再过 softmax → 变成一组和为 1 的权重
- 用这组权重去加权求和所有词的 V → 就是我的新表示
这一个公式就是 Transformer 的核心。
为什么要除以
这个细节常被忽略,但很重要。
当向量维度 很大时, 的点积结果方差也会很大,数值被推向两端。softmax 遇到很大的输入会变得极其「尖锐」——几乎全部概率集中在一个位置,其余接近 0。
后果是梯度消失:softmax 在饱和区的梯度接近 0,模型学不动。
除以 把方差拉回到 1 附近,让 softmax 工作在敏感区间。所以它的全名叫缩放点积注意力。
代价:计算量是平方的
每个词都要和所有词算相关性, 个词就是 次计算。
序列翻倍,计算量变四倍。 这就是为什么早期模型的上下文长度受限,也是后来大量研究要解决的核心瓶颈——稀疏注意力、线性注意力、滑动窗口等等,都是在攻这个 。
一个直观的例子
The animal didn't cross the street because it was too tired.
模型处理 it 时,自注意力会给 animal 分配很高的权重(因为「累」和动物相关)。
如果把 tired 换成 wide,it 的注意力会转向 street。
这种指代消解,自注意力是自动学会的——没有人写规则告诉它「it 指代前面的名词」。
练习:解释一下——为什么自注意力能同时解决 RNN 的「长距离依赖」和「不能并行」两个问题?
自注意力如何同时解决 RNN 的两个死穴?公式里除以 √d_k 是为了什么?
登录 后可看答案