绝对位置编码 vs 相对位置编码:概念辨析与核心差异
好,咱们今天来聊聊位置编码里最核心的一个分水岭——绝对位置编码和相对位置编码。说实话,我刚入行那会儿,也经常把这两个概念搞混。你想想看,Transformer 本身是不带时序感的,它看一句话就像看一袋豆子,分不清谁先谁后。那怎么让模型知道「词序」呢?这就引出了两种完全不同的思路。
一、绝对位置编码:给每个词发一个「身份证号」
绝对位置编码的思路很直接——我给序列里的每个位置,都分配一个独一无二的向量。位置 1 用向量 A,位置 2 用向量 B,位置 3 用向量 C…… 模型看到这些向量,就知道「哦,这个词是第 5 个出现的」。
最经典的例子就是 Transformer 原论文里的 Sinusoidal 位置编码。它用正弦和余弦函数,生成一组固定长度的向量。每个位置的编码都是唯一的,而且不同维度有不同的频率。
核心公式(以 Sinusoidal 为例)
PE(pos, 2i) = sin(pos / 10000^(2i/d_model))
PE(pos, 2i+1) = cos(pos / 10000^(2i/d_model))
其中 pos 是位置索引,i 是维度索引,d_model 是模型维度。
嗯,这里要注意一点:绝对位置编码是 直接加到词向量上 的。也就是说,模型看到的输入是「词向量 + 位置向量」。我个人习惯把这种加法理解为「给每个词贴上一个位置标签」。
二、相对位置编码:我只在乎「你离我有多远」
相对位置编码的思路就完全不一样了。它不关心「你是第几个」,只关心「你相对于我是第几个」。说白了,就是模型在计算注意力分数时,考虑的是两个词之间的 距离,而不是它们的绝对坐标。
举个例子:句子「我今天吃了苹果」。在绝对位置编码下,「我」是位置 1,「苹果」是位置 5。但在相对位置编码下,「苹果」相对于「我」的距离是 +4。模型只需要知道这个偏移量就够了。
为什么会这样?因为很多 NLP 任务中,真正重要的是词与词之间的相对关系。比如在命名实体识别里,「北京」和「上海」出现在句子的哪个位置不重要,重要的是它们和前后词的关系。
我的经验之谈
我在做长文本分类项目时遇到过一个问题:用绝对位置编码的模型,在训练集上表现很好,但换到不同长度的测试集上就崩了。后来换成相对位置编码,泛化能力明显提升。说白了,绝对位置编码容易「记住」位置,而相对位置编码更关注「关系」。
三、核心差异对比:一张表说清楚
| 对比维度 | 绝对位置编码 | 相对位置编码 |
|---|---|---|
| 编码对象 | 每个位置的绝对索引 | 两个位置之间的相对偏移 |
| 输入方式 | 直接加到词向量上 | 融入注意力分数计算中 |
| 外推能力 | 弱(超出训练长度效果差) | 强(可处理更长序列) |
| 典型代表 | Sinusoidal、可学习位置编码 | Transformer-XL、T5、ALiBi |
| 计算复杂度 | 低(O(n)) | 较高(O(n²) 或需优化) |
| 对序列长度的敏感度 | 高 | 低 |
四、为什么相对位置编码越来越流行?
你可能会问:既然绝对位置编码简单又好用,为什么现在大家都在搞相对位置编码?
原因其实很现实。我记得有一次做 GPT 风格的语言模型,训练时序列长度是 512,但推理时用户输入了 1024 个 token。用绝对位置编码的模型直接懵了——它没见过位置 513 到 1024 的编码。这就是所谓的 外推问题。
相对位置编码天然解决了这个问题。因为无论序列多长,相对偏移的范围是有限的(比如 -128 到 +128),模型只需要学会处理这些偏移量就够了。你想想看,这就像一个人只需要知道「左边 3 米有棵树」,而不需要知道「我在第 100 米处有棵树」——后者换个地方就失效了。
避坑指南
我曾经在项目中踩过一个坑:把绝对位置编码和相对位置编码混用。当时想着「双保险」,结果模型训练不稳定,收敛特别慢。后来才明白,这两种编码方式对注意力分布的建模方式完全不同,强行叠加反而会互相干扰。所以我的建议是:选一种,用到底。
五、知识结构图:两种编码的演进脉络
下面我用一张 SVG 图来梳理一下这两种编码的核心逻辑和代表方法。你可以把它当作一个「选型地图」来用。
六、选型建议:什么时候用哪种?
说了这么多,到底该怎么选?我根据自己的项目经验,给你几个实用的建议:
- 短序列任务(长度 < 128):比如文本分类、情感分析,用绝对位置编码就够了。简单、稳定、训练快。
- 长序列任务(长度 > 512):比如文档摘要、长文本生成,强烈建议用相对位置编码。否则外推问题会让你头疼。
- 需要外推的场景:比如推理时序列长度可能超过训练长度,直接选相对位置编码,别犹豫。
- 计算资源有限:绝对位置编码计算量小,适合在边缘设备上部署。
一句话总结
绝对位置编码是「我在哪」,相对位置编码是「你离我多远」。前者简单但死板,后者灵活但复杂。选哪个,取决于你的任务对「位置」的敏感程度。
好了,这一章的内容就到这里。下一章我们会深入对比 RoPE 和 ALiBi 这两种具体实现,看看它们是怎么把「相对」的思想玩出花的。