transformer 相对位置编码详解

问题1 请说下transgormer 的相对位置编码

好的,我们来系统梳理一下 Transformer 的相对位置编码(Relative Positional Encoding, RPE)


1. 背景

原始的 Transformer(Vaswani et al., 2017)用了 绝对位置编码

  • 给定序列中第 iii 个 token 的位置 iii
  • 通过固定的正余弦函数 sin⁡,cos⁡\sin, \cossin,cos 或可学习向量,映射到一个 embedding,
  • 这个 embedding 加到输入词向量上,提供位置信息。

但是绝对位置编码有两个问题:

  1. 不自然地绑定了位置编号,序列平移后模型不具备平移不变性。
  2. 无法自然推广到更长的序列。

因此引入了 相对位置编码


2. 相对位置编码的核心思想

核心:注意力计算时,不关心 token 的绝对位置,而是关心 query 和 key 的 相对距离 k−jk-jkj

标准 self-attention 的打分是:

score(qi,kj)=qi⋅kjd \text{score}(q_i, k_j) = \frac{q_i \cdot k_j}{\sqrt{d}} score(qi,kj)=dqikj

加上相对位置编码后,可以改为:

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)=dqikj+qirijkjrij

其中 ri−jr_{i-j}rij 是和 相对位置差值 i−ji-jij 绑定的向量。

  • 如果 i−j=0i-j=0ij=0,表示当前词自己。
  • 如果 i−j=1i-j=1ij=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)=dqikj+qirij+ukj+vrij

其中:

  • qiq_iqi 是 query,kjk_jkj 是 key;
  • ri−jr_{i-j}rij 是相对位置 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)=dqikj+bij

其中 bi−jb_{i-j}bij 是根据相对距离 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 qikj=qR(ij)k

也就是说,绝对位置差转化为了向量旋转的相对差

  • 计算量不增加,
  • 并且天然支持相对位置,
  • 是现在很多大模型(LLaMA、ChatGLM)的主流方案。

4. 小结

相对位置编码的关键点:

  1. 不直接依赖 token 的绝对坐标,而是利用 query-key 的 相对距离

  2. 常见三种形式:

    • 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)=qikj

如果只用词向量,模型分不清「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)=q1k2+2

score(1,3)=q1⋅k3−1 \text{score}(1,3) = q_1 \cdot k_3 - 1 score(1,3)=q1k31


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]=[−sin⁡2θ,cos⁡2θ]q_2 = R(2\theta)[0,1] = [-\sin 2\theta, \cos 2\theta]q2=R(2θ)[0,1]=[sin2θ,cos2θ]

这样在点积时:

q1⋅k2=cos⁡θ⋅(−sin⁡2θ)+sin⁡θ⋅cos⁡2θ q_1 \cdot k_2 = \cos\theta \cdot (-\sin 2\theta) + \sin\theta \cdot \cos 2\theta q1k2=cosθ(sin2θ)+sinθcos2θ

最终结果只依赖于 位置差 (2-1),天然编码了相对位置信息。


👉 你要不要我帮你做一张 小型 3×3 attention score 矩阵,分别展示「无位置编码 / 绝对位置编码 / 相对位置编码」的区别?

### Transformer 模型中的位置编码 #### 绝对位置编码的特点和作用 为了使 Transformer 能够处理顺序信息,在输入嵌入向量的基础上加入了位置编码。这些位置编码提供了关于单词在其序列中所处位置的信息,这对于捕捉上下文非常重要[^1]。 绝对位置编码通过为每个时间步添加特定的数值来表示该时刻的位置信息。具体而言,对于长度为 \( L \) 的序列,第 i 个位置上的正弦波函数定义如下: \[ PE_{(pos,2i)} = sin\left(\frac{position}{10000^{2i/d}}\right), \] \[ PE_{(pos,2i+1)} = cos\left(\frac{position}{10000^{2i/d}}\right). \] 这里 d 表示模型维度;`position` 是词所在的位置索引;\( pos \in [0,L-1], i \in [0,d/2-1] \). 这种设计允许网络学习不同频率下的模式,并且即使在训练期间未见过较长的序列时也能推广至更长的序列上. ```python import numpy as np import matplotlib.pyplot as plt def get_positional_encoding(max_len, embed_size): pe = np.zeros((max_len, embed_size)) position = np.arange(0, max_len)[:, None] div_term = np.exp(np.arange(0, embed_size, 2) * -(np.log(10000.0) / embed_size)) pe[:, 0::2] = np.sin(position * div_term) pe[:, 1::2] = np.cos(position * div_term) return pe pe = get_positional_encoding(50, 32) plt.figure(figsize=(8, 6)) plt.imshow(pe[:50,:]) plt.colorbar() plt.title('Position Encoding Visualization') plt.show() ``` #### 相对位置编码的优势和发展 尽管最初的 Transformer 使用了固定的正弦形式作为其位置编码方案,但是研究者们很快意识到相对位置的重要性以及它所带来的潜在优势。相对于绝对位置编码,相对位置编码能够更好地反映词语间的相互关系而不受固定起始点的影响[^4]. 例如,在某些情况下,两个相隔一定距离的词汇之间的关联可能比它们各自的具体位置更重要。因此,采用相对位置编码可以增强模型捕获此类依赖性的能力。像 Transformer-XL 和 T5 这样的改进版本便引入了不同的机制来实现这一点[^2].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时空无限

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值