transformer 相对位置编码详解
问题1 请说下transgormer 的相对位置编码
好的,我们来系统梳理一下 Transformer 的相对位置编码(Relative Positional Encoding, RPE)。
1. 背景
原始的 Transformer(Vaswani et al., 2017)用了 绝对位置编码:
- 给定序列中第 iii 个 token 的位置 iii,
- 通过固定的正余弦函数 sin,cos\sin, \cossin,cos 或可学习向量,映射到一个 embedding,
- 这个 embedding 加到输入词向量上,提供位置信息。
但是绝对位置编码有两个问题:
- 不自然地绑定了位置编号,序列平移后模型不具备平移不变性。
- 无法自然推广到更长的序列。
因此引入了 相对位置编码。
2. 相对位置编码的核心思想
核心:注意力计算时,不关心 token 的绝对位置,而是关心 query 和 key 的 相对距离 k−jk-jk−j。
标准 self-attention 的打分是:
score(qi,kj)=qi⋅kjd \text{score}(q_i, k_j) = \frac{q_i \cdot k_j}{\sqrt{d}} score(qi,kj)=dqi⋅kj
加上相对位置编码后,可以改为:
score(qi,kj)=qi⋅kjd+qi⋅ri−j或kj⋅ri−j \text{score}(q_i, k_j) = \frac{q_i \cdot k_j}{\sqrt{d}} + q_i \cdot r_{i-j} \quad \text{或} \quad k_j \cdot r_{i-j} score(qi,kj)=dqi⋅kj+qi⋅ri−j或kj⋅ri−j
其中 ri−jr_{i-j}ri−j 是和 相对位置差值 i−ji-ji−j 绑定的向量。
- 如果 i−j=0i-j=0i−j=0,表示当前词自己。
- 如果 i−j=1i-j=1i−j=1,表示 key 比 query 晚一个位置。
- 以此类推。
这样模型就能感知 相邻词的关系,而不是单纯依赖绝对坐标。
3. 典型实现方式
(1) Transformer-XL 相对位置编码
Transformer-XL (Dai et al., 2019) 的公式是:
score(qi,kj)=qi⋅kj+qi⋅ri−j+u⋅kj+v⋅ri−jd \text{score}(q_i, k_j) = \frac{q_i \cdot k_j + q_i \cdot r_{i-j} + u \cdot k_j + v \cdot r_{i-j}}{\sqrt{d}} score(qi,kj)=dqi⋅kj+qi⋅ri−j+u⋅kj+v⋅ri−j
其中:
- qiq_iqi 是 query,kjk_jkj 是 key;
- ri−jr_{i-j}ri−j 是相对位置 embedding;
- u,vu, vu,v 是全局可学习向量。
这样在打分时,模型同时考虑了内容 (content) 和位置 (position)。
(2) T5 的相对位置偏置 (Relative Position Bias)
T5 (Raffel et al., 2020) 没有对 embedding 向量做运算,而是直接在 attention score 矩阵上加一个 偏置项:
score(qi,kj)=qi⋅kjd+bi−j \text{score}(q_i, k_j) = \frac{q_i \cdot k_j}{\sqrt{d}} + b_{i-j} score(qi,kj)=dqi⋅kj+bi−j
其中 bi−jb_{i-j}bi−j 是根据相对距离 bucket 化的可学习参数。
- 例如把「距离=1,2,3,…」映射到少量 bucket,避免参数过多。
- 在长序列时效果非常好。
(3) Rotary Position Embedding (RoPE, GPT-NeoX, LLaMA)
RoPE 的做法更优雅:直接在 向量空间里通过旋转编码相对位置信息。
定义旋转矩阵 R(θ)R(\theta)R(θ),让:
qi=R(i) q,kj=R(j) k q_i = R(i)\, q, \quad k_j = R(j)\, k qi=R(i)q,kj=R(j)k
那么:
qi⋅kj=q⋅R(i−j) k q_i \cdot k_j = q \cdot R(i-j)\,k qi⋅kj=q⋅R(i−j)k
也就是说,绝对位置差转化为了向量旋转的相对差。
- 计算量不增加,
- 并且天然支持相对位置,
- 是现在很多大模型(LLaMA、ChatGLM)的主流方案。
4. 小结
相对位置编码的关键点:
-
不直接依赖 token 的绝对坐标,而是利用 query-key 的 相对距离。
-
常见三种形式:
- Transformer-XL:内容 + 相对位置 embedding;
- T5:attention score 上加 相对位置偏置;
- RoPE:向量空间旋转,天然编码相对位置信息。
要不要我给你画一个 相对位置偏置矩阵示意图,直观展示每个 query 如何对不同距离的 key 加不同偏置?
问题2 给几个词向量举例
好,我们直接用几个小的 词向量例子 来说明相对位置编码的作用。
为了直观,我用低维度(2维)表示词向量。
1. 没有位置编码的情况
假设有三个 token:
- token1(“I”) → 向量 x1=[1,0]x_1 = [1, 0]x1=[1,0]
- token2(“like”) → 向量 x2=[0,1]x_2 = [0, 1]x2=[0,1]
- token3(“apples”) → 向量 x3=[1,1]x_3 = [1, 1]x3=[1,1]
标准 self-attention 里,打分公式是:
score(i,j)=qi⋅kj \text{score}(i,j) = q_i \cdot k_j score(i,j)=qi⋅kj
如果只用词向量,模型分不清「I like apples」和「apples like I」,因为它们的向量集合是一样的。
2. 绝对位置编码
给每个位置加一个位置向量,比如:
- pos1 → [0.1,0.2][0.1, 0.2][0.1,0.2]
- pos2 → [0.2,0.3][0.2, 0.3][0.2,0.3]
- pos3 → [0.3,0.4][0.3, 0.4][0.3,0.4]
新的输入是:
- x1′=[1,0]+[0.1,0.2]=[1.1,0.2]x_1' = [1,0] + [0.1,0.2] = [1.1, 0.2]x1′=[1,0]+[0.1,0.2]=[1.1,0.2]
- x2′=[0,1]+[0.2,0.3]=[0.2,1.3]x_2' = [0,1] + [0.2,0.3] = [0.2, 1.3]x2′=[0,1]+[0.2,0.3]=[0.2,1.3]
- x3′=[1,1]+[0.3,0.4]=[1.3,1.4]x_3' = [1,1] + [0.3,0.4] = [1.3, 1.4]x3′=[1,1]+[0.3,0.4]=[1.3,1.4]
这样模型能区分「I」在第1个位置 vs 第3个位置,但还是死记绝对坐标。
3. 相对位置编码(T5式的偏置举例)
假设我们定义:
- 相对距离 = 0 → 偏置 = 0
- 相对距离 = ±1 → 偏置 = +2
- 相对距离 ≥ 2 → 偏置 = -1
那么在计算 attention score 时:
- token1 (位置1) 对 token2 (位置2),距离 = +1 → 加偏置 +2
- token1 对 token3,距离 = +2 → 加偏置 -1
这样模型会特别「偏爱」相邻的词,更符合语言结构。
举例:
score(1,2)=q1⋅k2+2 \text{score}(1,2) = q_1 \cdot k_2 + 2 score(1,2)=q1⋅k2+2
score(1,3)=q1⋅k3−1 \text{score}(1,3) = q_1 \cdot k_3 - 1 score(1,3)=q1⋅k3−1
4. 相对位置编码(RoPE举例)
假设 query/key 本来是:
- q1=[1,0],q2=[0,1]q_1 = [1,0], q_2 = [0,1]q1=[1,0],q2=[0,1]
- k1=[1,0],k2=[0,1]k_1 = [1,0], k_2 = [0,1]k1=[1,0],k2=[0,1]
RoPE 会对每个位置 iii 做旋转:
- 位置1:旋转角度 θ\thetaθ
- 位置2:旋转角度 2θ2\theta2θ
所以:
- q1=R(θ)[1,0]=[cosθ,sinθ]q_1 = R(\theta)[1,0] = [\cos\theta, \sin\theta]q1=R(θ)[1,0]=[cosθ,sinθ]
- q2=R(2θ)[0,1]=[−sin2θ,cos2θ]q_2 = R(2\theta)[0,1] = [-\sin 2\theta, \cos 2\theta]q2=R(2θ)[0,1]=[−sin2θ,cos2θ]
这样在点积时:
q1⋅k2=cosθ⋅(−sin2θ)+sinθ⋅cos2θ q_1 \cdot k_2 = \cos\theta \cdot (-\sin 2\theta) + \sin\theta \cdot \cos 2\theta q1⋅k2=cosθ⋅(−sin2θ)+sinθ⋅cos2θ
最终结果只依赖于 位置差 (2-1),天然编码了相对位置信息。
👉 你要不要我帮你做一张 小型 3×3 attention score 矩阵,分别展示「无位置编码 / 绝对位置编码 / 相对位置编码」的区别?