位置编码:让 AI 记住词语先后
文 / 老陈
先玩个小游戏。看这句话:「猫咬狗」。再看这句:「狗咬猫」。两个字完全一样,只是顺序颠倒,意思就完全反了——一个是猫赢,一个是狗赢。可问题是:Transformer 有个「大毛病」,它天生看不出顺序。
上一篇我们讲到,词嵌入把每个词变成一串数字。但注意:「猫」不管放在第 1 位还是第 3 位,它的数字身份证是一模一样的。对 Transformer 来说,「猫咬狗」和「狗咬猫」其实就是三串数字的排列组合,它分不清谁先谁后。这可不行。于是就有了今天的主角——位置编码(Positional Encoding)。
打个比方:座位号
想想一场演唱会。每个座位都有「座位号」(比如 A 排 15 座)。哪怕两个人都叫「小明」,坐在 A 排的和坐在 C 排的小明,你能分清他们。位置编码干的就是给每个词发一个「座位号」,让它知道自己站在句子的第几个位置。
所以 Transformer 处理的,其实是「词的向量」加上「位置的向量」——两个叠加在一起。这样每个词的信息里,既包含「我是啥」,也包含「我在哪」。
位置编码全景图:「我打你」和「你打我」词序对比,正弦曲线给每个位置贴坐标,旋转编码 RoPE 更聪明
老办法:正弦曲线(Sinusoidal)
最初的 Transformer(2017 年的论文)用的是数学上很优雅的办法:用正弦和余弦曲线给位置编号。不同位置,对应正弦曲线上不同的点。这个方法的妙处在于:它能表达「相对距离」——离得近的位置,编号也接近;离得远的,编号差得远。就像列车车厢号一样,1 号在 2 号旁边,不在 10 号旁边。
而且它是固定的,不需要额外训练,直接把公式算出来就行。简单、高效、还能处理比训练时更长的文本。
新办法:旋转位置编码(RoPE)
后来大家发现,直接用正弦曲线还是有短板。于是 2021 年左右出现了更聪明的 RoPE(Rotary Position Embedding,旋转位置编码),现在几乎所有主流大模型(LLaMA、ChatGLM、通义千问等)都用它。
RoPE 的思路很妙:它不是把位置「加」到词上,而是把词向量「旋转」一下。位置越靠后,旋转的角度越大。两个词之间的「相对位置」,就变成了它们之间的「相对旋转夹角」。这样一来,模型能天然地感知到「谁在谁前面、隔了多远」,而且对位置关系理解得特别准。
| 方案 | 怎么给位置 | 优点 | 谁在用 |
|---|---|---|---|
| 正弦编码 | 用正余弦曲线的值 | 简单、无需训练 | 早期 Transformer |
| 可学习位置编码 | 把位置编号当参数训练 | 灵活 | BERT 早期 |
| 旋转编码 RoPE | 旋转词向量 | 相对位置理解强、外推好 | 今天的多数大模型 |
下一篇预告
现在词有了「身份证」(嵌入)、位置有了「座位号」(位置编码)。还差最后一块最关键的核心拼图,就是上一篇的「注意力」怎么和这些结合起来,做成真正的「多头注意力」,最终变成一整座 Transformer 大楼。下一篇《Transformer 整座大楼:零件怎么拼》我们就把所有零件装成一台完整的机器。
老陈打码