热闻岛
返回全网热点

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?

1小时前8 阅读
大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图
Transformer 很强,但它有一个天然短板:Self-Attention 只擅长计算 token 之间的相关性,并不自带“第几个词在前、第几个词在后”的概念。位置编码就是为了解决这个问题。 1. Transformer 为什么需要位置
大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

Transformer 很强,但它有一个天然短板:Self-Attention 只擅长计算 token 之间的相关性,并不自带“第几个词在前、第几个词在后”的概念。位置编码就是为了解决这个问题。

1. Transformer 为什么需要位置编码?

如果不给模型位置信号,Transformer 看到的更像是一袋词,而不是一句有顺序的话。

例如“我爱北京”和“北京爱我”,三个 token 基本相同,但语义完全不同。人一眼就能看出顺序差异,是因为人知道“谁在前、谁在后”。Self-Attention 只计算 token 之间的关系,如果没有额外位置输入,它很难稳定获得这种顺序信息。

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

提示:位置编码不是为了让模型背第几个 token,而是让模型在计算 Attention 时知道 token 之间的先后和距离。

2. sin/cos 绝对位置编码:给每个位置发“身份证”

原始 Transformer 使用的是 sin/cos 位置编码。它的做法很直接:用多组不同频率的正弦和余弦函数,为每个位置生成一个固定向量,然后把这个位置向量加到 token embedding 上。

可以把它理解成位置身份证:第 0 个位置有一张身份证,第 1 个位置也有一张身份证。模型输入时拿到的是“词向量 + 位置身份证”,然后自己学习如何利用这些位置信息。

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

它的优点是简单、零参数、容易实现;缺点是绝对位置味道比较重。模型想要知道两个词相隔多远,需要自己从两个“位置身份证”里推断出来。短上下文场景还能接受,到了长上下文就容易暴露问题。

import torch
import math

class SinusoidalPositionEmbedding(torch.nn.Module):
def __init__(self, max_len: int, dim: int):
super().__init__()
position = torch.arange(max_len).unsqueeze(1)
div_term = torch.exp(
torch.arange(0, dim, 2) * (-math.log(10000.0) / dim)
)

pe = torch.zeros(max_len, dim)
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
self.register_buffer("pe", pe)

def forward(self, x):
# x: [batch, seq_len, dim]
seq_len = x.size(1)
return x + self.pe[:seq_len]

3. 绝对位置和相对位置,差别在哪里?

绝对位置像座位号:第 1 个、第 2 个、第 3 个。相对位置像距离关系:这个词在那个词前面 2 个位置,这个词离那个词很近。

语言理解更关心相对关系。比如主语和动词之间隔了几个词、修饰语离中心词有多近,这些通常比“它在整句话第几个位置”更有价值。

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

后来的很多位置编码改进,本质都是想把“相对距离”更直接地放进 Attention 计算里。RoPE 和 ALiBi 就是两个代表。

4. RoPE:把位置变成 Q/K 的旋转角度

RoPE 的思路非常巧:不再把位置向量加到 token embedding 上,而是在 Attention 里对 Q 和 K 做旋转。

每个位置对应一个旋转角度。位置越靠后,旋转得越多。这样两个 token 的 Q/K 做点积时,点积结果会自然包含它们之间的相对距离。

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

RoPE 受欢迎的原因有几个:不增加参数;不改变向量长度;和 KV Cache、FlashAttention、MHA/MQA/GQA 等推理优化兼容;对长上下文也更友好。

def rotate_half(x):
x1 = x[..., ::2]
x2 = x[..., 1::2]
return torch.stack((-x2, x1), dim=-1).flatten(-2)


def apply_rope(q, k, cos, sin):
# q, k: [batch, heads, seq_len, head_dim]
# cos, sin: [seq_len, head_dim]
cos = cos[None, None, :, :]
sin = sin[None, None, :, :]

q_embed = (q * cos) + (rotate_half(q) * sin)
k_embed = (k * cos) + (rotate_half(k) * sin)
return q_embed, k_embed

5. ALiBi:直接给远距离注意力扣分

ALiBi 的做法更简单:不改 embedding,也不旋转 Q/K,而是在 Attention 分数进入 softmax 之前,加一个距离惩罚。两个 token 离得越远,分数被扣得越多。

它像是在告诉模型:近处信息默认更重要,远处信息要有足够理由才值得关注。不同 attention head 可以使用不同斜率,有的关注近邻,有的保留更远的视野。

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图
def build_alibi_bias(seq_len: int, slope: float, device=None):
positions = torch.arange(seq_len, device=device)
distance = positions[None, :] - positions[:, None]
distance = distance.abs()

# 距离越远,偏置越负
bias = -slope * distance
return bias

# attention_scores: [batch, heads, seq_len, seq_len]
# attention_scores = attention_scores + alibi_bias

6. 长上下文为什么离不开位置编码?

现在的大模型动不动就是 32K、128K 甚至更长上下文。这里真正难的不是把输入长度配置调大,而是模型能不能在很长文本里保持稳定的位置感。

如果训练时只见过 2K,推理时突然塞进 32K,绝对位置编码很容易遇到训练分布之外的位置。RoPE 虽然更稳,但直接外推也不是万能的,所以才有 NTK Scaling、Position Interpolation、YaRN 等扩展技巧。它们的核心都和调整 RoPE 频率、压缩或重映射位置有关。

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

提示:长上下文上线不能只看最大长度参数,还要评测长文检索、跨段引用、多跳推理、开头信息召回和结尾信息召回。

7. 几种方案放在一起怎么选?

如果是现代 Decoder-only 大模型,RoPE 基本是默认优先项;如果是实验型长上下文或强调极简实现,可以考虑 ALiBi;如果是传统 Encoder 模型或分类任务,学习式绝对位置、sin/cos、相对位置编码仍然有价值。

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

8. 面试和工程里最容易被追问的点

8.1 为什么不用“拼接”位置向量?

拼接会让维度变大,后续矩阵计算也要跟着变重。原始 Transformer 选择“相加”,是因为位置向量和词向量维度相同,工程上更省,模型也有能力从叠加后的向量里学习到两类信息。

8.2 RoPE 是绝对位置还是相对位置?

RoPE 计算时使用的是绝对位置角度,但两个旋转后的 Q/K 做点积时,会自然表现出相对位置关系。所以更准确的说法是:RoPE 用绝对位置构造旋转,但在 Attention 里体现相对距离。

8.3 ALiBi 为什么没有成为绝对主流?

ALiBi 外推简单,但它的距离惩罚比较强,会天然偏向近处 token。对于需要复杂长距离依赖的任务,表达力不如 RoPE 灵活。

8.4 长上下文扩展是不是改一个 rope_scaling 就行?

不是。配置只是第一步,真正决定能不能上线的是评测。尤其是 RAG、法律合同、代码仓库、长文总结这类任务,要看模型是否能稳定找到远处证据,而不是只看能不能塞进去。

9. 总结

大模型的位置编码干什么用的?sin/cos、RoPE、ALiBi 有什么区别?配图

位置编码解决的是 Transformer 的顺序感问题。sin/cos 给每个位置一张固定身份证,简单但长上下文外推有限;相对位置编码把距离关系直接放进计算,思路更接近语言理解;RoPE 通过旋转 Q/K,把相对距离自然写进点积,兼顾表达力、外推和工程兼容性;ALiBi 用距离惩罚实现简单外推,但表达力相对弱。

今天做大模型,尤其是 Decoder-only 模型,RoPE 已经是最常见选择。但无论用哪种方案,只要涉及长上下文,最终都要回到真实任务评测。

要点速读

Transformer 很强,但它有一个天然短板:Self-Attention 只擅长计算 token 之间的相关性,并

  • Transformer 很强,但它有一个天然短板:Self-Attention 只擅长计算 token 之间的相关性,并
  • 更多细节仍在持续更新中
  • 更多细节仍在持续更新中