3. 相对位置编码详解
好,咱们接着聊位置编码。上一节讲了绝对位置编码,说白了就是把每个位置打上一个固定的标签。但我在实际做Transformer模型的时候,发现一个问题——绝对位置编码在处理长序列时,有点「死板」。你想想看,模型真的需要知道「第5个词」这个绝对概念吗?其实它更关心的是「这个词离我有多远」。
这就是相对位置编码的动机所在。
3.1 为什么需要相对位置编码?
我举个例子你就明白了。假设有这么两句话:
- 「我今天去银行存钱」
- 「我昨天去银行取钱」
对于「存」和「取」这两个词,它们和「银行」的相对距离是一样的——都是紧挨着。但绝对位置编码会把它们标记成不同的位置(位置5和位置5?不对,其实是不同句子里的不同位置)。模型需要学习的是「银行」后面这个词的语义关系,而不是它具体在第几个位置。
我个人习惯把这个问题总结为三点:
- 泛化能力差:训练时见过的最大长度是512,推理时来了个600的序列,绝对位置编码直接懵了
- 缺乏平移不变性:同样的语义关系,换个位置就要重新学
- 长距离依赖捕捉困难:位置越远,绝对编码的区分度反而下降
核心洞察:注意力机制本质上是在计算「词与词之间的关系」,而这个关系主要取决于它们的相对距离,而不是绝对坐标。
3.2 Shaw等人提出的方法
说到相对位置编码,最早被广泛引用的工作是Shaw et al. 2018年的论文。我记得当时读这篇论文时,第一反应是「原来可以这样玩」。
他们的思路很直接:在计算注意力分数时,把位置信息加到Query和Key的交互中。具体来说,标准注意力公式是:
Attention(Q, K, V) = softmax(QK^T / sqrt(d)) V
Shaw的做法是,在QK^T这一步里加入一个相对位置偏置项:
e_ij = (x_i W_Q)(x_j W_K + a_{ij}^K)^T / sqrt(d)
这里a_{ij}^K是一个可学习的向量,表示位置i和位置j之间的相对距离。说白了,就是给每个可能的相对距离(比如-3, -2, -1, 0, 1, 2, 3)都分配一个专属的向量。
嗯,这里要注意一个细节:相对距离是有范围的。你不能让模型去学无限多种距离,所以通常会设置一个截断窗口k。比如k=3,那就只考虑[-3, 3]这个范围内的相对位置,超出部分统一用边界值表示。
我的经验:k的取值很关键。我在做文本生成任务时试过k=16和k=64,发现k=32左右效果最好。太小了捕捉不到长距离依赖,太大了参数量暴增而且容易过拟合。
3.3 Transformer-XL中的相对位置编码
接下来要聊的是Transformer-XL,这个工作把相对位置编码推到了一个新高度。说实话,我第一次看Transformer-XL的论文时,被它的设计惊艳到了——它解决了两个痛点:长序列建模和上下文碎片问题。
Transformer-XL的核心改进有两点:
- 片段级循环机制:把上一个片段的隐状态缓存下来,给当前片段用
- 全新的相对位置编码:彻底抛弃绝对位置,全部用相对位置表示
我们重点看第二点。Transformer-XL的注意力分数计算长这样:
A_{i,j}^{rel} = (q_i^T k_j) + (q_i^T R_{i-j}) + (u^T k_j) + (v^T R_{i-j})
别被这个公式吓到,我来拆解一下:
- 第一项 q_i^T k_j:标准的content-based attention,只看词义不看位置
- 第二项 q_i^T R_{i-j}:query和相对位置编码的交互,告诉模型「这个词离我多远」
- 第三项 u^T k_j:全局的key偏置,u是可学习的向量,对所有位置都一样
- 第四项 v^T R_{i-j}:全局的位置偏置,v也是可学习的
这里R_{i-j}用的是正弦编码,但注意——它不是绝对位置的正弦编码,而是相对距离的正弦编码。也就是说,R_3表示「距离为3」的编码,不管你是从位置5到位置2,还是从位置100到位置97,R_3都是一样的。
我曾经踩过的坑:在实现Transformer-XL时,我一开始把R_{i-j}的索引搞反了。i-j和j-i的区别很大,前者表示「j相对于i的位置」,后者相反。这个符号问题让我debug了整整两天,最后发现是索引方向错了。大家实现时一定要确认清楚。
3.4 相对位置编码的SVG结构图
下面我用一张图来总结相对位置编码的核心逻辑,方便你理解整个知识体系:
3.5 实际应用中的选择建议
好了,理论讲完了,我来说点实际的。你在项目中到底该选哪种?
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 短文本分类(长度<128) | 绝对位置编码 | 够用,实现简单,训练快 |
| 长文本生成(长度>512) | Transformer-XL相对编码 | 外推性好,支持超长序列 |
| 机器翻译 | Shaw相对编码 | 窗口适中,效果稳定 |
| 代码生成/数学推理 | 相对编码(窗口大一些) | 需要精确捕捉符号间的相对关系 |
一句话总结:相对位置编码的核心思想,就是让模型关注「词与词之间的距离」,而不是「词在序列中的绝对坐标」。这个思路后来被RoPE(旋转位置编码)进一步发扬光大,下一章我们会详细聊。
我个人在实际项目中,除非是特别短的序列任务,否则都会优先考虑相对位置编码。它带来的泛化能力提升,绝对值回票价。
公众号:蓝海资料掘金营,微信deep3321