从一条直线到大模型输出一个token(四):位置编码 RoPE
从一条直线到大模型输出一个token四位置编码 RoPE建议先看从一条直线到大模型输出一个token三隐藏层与嵌入上一篇留下两个坑嵌入矩阵不知道顺序、不知道上下文。这一篇填第一个坑——矩阵怎么知道每个词排在第几位。从一条直线到大模型输出一个token四位置编码 RoPE从一条直线到大模型输出一个token四位置编码 RoPE1. 排列等变性注意力天生是位置盲2. 位置编码的设计要求3. 第一代正弦余弦绝对位置编码20173.1 公式与直觉3.2 贯穿案例的 PE 矩阵3.3 优缺点带例子4. 第二代可学习位置编码GPT-2 / BERT5. 第三代RoPE 旋转位置编码事实标准5.1 核心思想不加数转角度5.2 数学魔法绝对旋转相对信息5.3 为什么它成了事实标准6. 贯穿案例给 6×4 矩阵做 RoPE6.1 演示规模设定6.2 为什么是 10000为什么是递减6.3 「西安」行的完整手算7. 有没有 RoPE差别到底有多大小结下一篇预告1. 排列等变性注意力天生是位置盲先看一个反直觉的事实。上一篇说过后续所有层对矩阵的处理都是逐行计算——第 1 行算第 1 行的第 3 行算第 3 行的。现在把我吃苹果和苹果吃我这两句话分别送进模型如图 4-1 所示。图4-1 排列等变性注意力是「位置盲」——这是必须补位置的根因两句话的嵌入矩阵里「我」的向量内容一模一样只是行位置不同一个在第 1 行一个在第 3 行。而后续的自注意力机制第 7 篇会看到它怎么算对每一行的处理方式完全一样——行与行怎么排列它根本不关心。这个性质在数学上叫排列等变性permutation equivariance输入行序打乱输出行序跟着打乱但内容不变。对我吃苹果和苹果吃我注意力算出的结果几乎相同——但这两句话的意思天差地别。所以必须在矩阵进 Transformer 之前把位置信息揉进向量里。这就是位置编码Position Encoding干的事。2. 位置编码的设计要求不是随便塞个数字就行。位置编码要满足三条设计要求每个位置有唯一编码——位置 0 和位置 5 的编码必须不同否则等于没加能表达相对距离——理想情况下位置 3 和位置 5 的关系应该能从编码里算出来因为语言里远近距离很重要今天和天气相邻 vs 隔了 10 个词相关性不同不受句子长度限制——训练时见过 4096 个 token推理时来了 8192 个编码最好还能用外推性三代方案对这三条要求的满足程度决定了各自的命运演进时间线如图 4-2 所示。图4-2 位置编码三代演进从绝对到可学习再到旋转3. 第一代正弦余弦绝对位置编码20173.1 公式与直觉原始 Transformer2017 年《Attention is All You Need》的做法给每个位置 m 造一个 4096 维的向量 PE(m)直接加到词向量上X p o s X P E \mathbf{X}_{pos} \mathbf{X} \mathbf{PE}Xpos​XPEPE 的每一维用不同频率的正弦/余弦波生成P E ( m , 2 i ) sin ⁡ ( m 10000 2 i / d ) , P E ( m , 2 i 1 ) cos ⁡ ( m 10000 2 i / d ) PE(m,\ 2i) \sin\left(\frac{m}{10000^{2i/d}}\right), \qquad PE(m,\ 2i1) \cos\left(\frac{m}{10000^{2i/d}}\right)PE(m,2i)sin(100002i/dm​),PE(m,2i1)cos(100002i/dm​)直觉如图 4-3 上半部分不同维度用不同频率的波。高频维度波长短像尺子的毫米刻度能分辨相邻位置低频维度波长大像厘米刻度负责分辨远距离。图4-3 第一代不同维度不同频率的波 贯穿案例的PE数值3.2 贯穿案例的 PE 矩阵用 d4 演示两对维度频率分别为 1 和 1/100我们 6 个 token 的 PE 矩阵如图 4-3 下半部分。以位置 1 为例sin ⁡ ( 1 ) 0.841 \sin(1) 0.841sin(1)0.841cos ⁡ ( 1 ) 0.540 \cos(1) 0.540cos(1)0.540——图中每个数都能套公式手算验证。3.3 优缺点带例子优点举例训练时模型只见过 8192 个位置的 PE 矩阵推理时来了 10000 个 token 的新闻稿——套公式sin ⁡ ( 10000 / 10000 2 i / d ) \sin(10000/10000^{2i/d})sin(10000/100002i/d)直接算出来就能用不用像第二代那样担心表里没有。这正是第一代论文里1 10000 2 i / d \frac{1}{10000^{2i/d}}100002i/d1​设计成几何级数衰减频率的原因外推到任意长度都合理。缺点举例以「今天」在两个不同位置的对比说明加法融合的副作用——情况原始词向量仅语义加 PE 后含义「今天」在位置 0[0.32, -1.07, 0.88, 0.05][0.32, -0.07, 0.88, 1.05]“今天”0 位置「今天」在位置 5[0.32, -1.07, 0.88, 0.05][-0.64, -0.79, 0.93, 0.75]“今天”5 位置同一个词向量加上不同的 PE得到完全不同的数字模型要从这个加好的数字里反向拆出词义位置要费不少劲。这就是第一代加法融合被第二代和第三代逐步抛弃的原因。至于相对距离机制绕——要靠三角恒等式sin ⁡ ( m n ) sin ⁡ m cos ⁡ n cos ⁡ m sin ⁡ n \sin(mn) \sin m \cos n \cos m \sin nsin(mn)sinmcosncosmsinn反推两个位置的差公式推导上不算优雅。4. 第二代可学习位置编码GPT-2 / BERTGPT-2 和 BERT 的思路更简单粗暴位置也当成词来学。给每个位置配一个可训练的 4096 维向量存成一张表最大长度 8192 行 × 4096 列训练时和嵌入表一起自动学出来。使用时位置序号当行号查表加到词向量上如图 4-4 所示。图4-4 第二代可学习位置编码——把位置也当成词来学实测效果不输第一代GPT-2 时代风光无限。但三个硬伤逐渐暴露外推死穴表只刻到 8192 行第 8193 个 token 直接没有编码上下文长度被表的大小焊死参数冗余8192×4096 ≈ 3300 万参数只干编码位置这一件事没有结构位置 100 和位置 101 的两个向量之间的距离跟位置 1 和位置 2 之间的距离没有任何规律关系——相邻这个概念在表里没有被表达5. 第三代RoPE 旋转位置编码事实标准5.1 核心思想不加数转角度RoPERotary Position Embedding2021 年 RoFormer 论文提出换了个思路不往向量里加任何数字而是把向量按自己的位置旋转一个角度如图 4-5 所示。图4-5 第三代RoPE——用旋转角表示位置规则很简单位置 0 的向量不转位置 1 的向量转θ \thetaθ位置 m 的向量转m θ m\thetamθ4096 维向量被拆成 2048 对二维平面每一对用不同的频率旋转θ i 10000 − 2 i / d , i 0 , 1 , … , 2047 \theta_i 10000^{-2i/d}, \qquad i 0, 1, \dots, 2047θi​10000−2i/d,i0,1,…,2047频率从 1第 0 对递减到 0.0001第 2047 对——和第一代正弦余弦的频率设计一脉相承只是从加波形变成了转角度。5.2 数学魔法绝对旋转相对信息RoPE 最漂亮的地方在于各自旋转后的两个向量做点积结果只取决于旋转角之差——也就是位置之差。用旋转矩阵写出来R m \mathbf{R}_mRm​表示位置 m 的旋转⟨ R m q , R n k ⟩ ⟨ R m − n q , k ⟩ \langle \mathbf{R}_m \mathbf{q},\ \mathbf{R}_n \mathbf{k} \rangle \langle \mathbf{R}_{m-n} \mathbf{q},\ \mathbf{k} \rangle⟨Rm​q,Rn​k⟩⟨Rm−n​q,k⟩左边是各自按绝对位置旋转后点积右边是只按相对位置( m − n ) (m-n)(m−n)旋转一次。这个恒等式是三角函数和角公式cos ⁡ ( m θ ) cos ⁡ ( n θ ) sin ⁡ ( m θ ) sin ⁡ ( n θ ) cos ⁡ ( ( m − n ) θ ) \cos(m\theta)\cos(n\theta) \sin(m\theta)\sin(n\theta) \cos((m{-}n)\theta)cos(mθ)cos(nθ)sin(mθ)sin(nθ)cos((m−n)θ)的矩阵版。真实算一组数验证演示向量[ 0.5 , − 0.3 ] [0.5, -0.3][0.5,−0.3]θ 1 \theta1θ1位置对相对距离点积(m1, n3)2-0.1415(m2, n4)2-0.1415(m0, n5)50.0964表4-1 RoPE 相对性质验证同距离点积相同绝对位置不同、相对距离相同 → 点积分毫不差。位置信息就这样悄悄融进了后续所有点积运算第 7 篇会看到注意力分数恰恰就是点积。5.3 为什么它成了事实标准三条设计要求逐条对答案唯一编码每个位置的旋转角组合唯一 ✓相对距离点积天然只依赖位置差表 4-1 实证比前两代都直接 ✓外推性任意位置 m 都能算m θ m\thetamθ没有表的上限 ✓再加两条工程红利零参数不用学不用存表不加数词义信息和位置信息不混在一碗里位置通过旋转作用在整个向量上。于是 2023 年之后LLaMA、Qwen、GLM、DeepSeek、Mistral……所有主流开源大模型全部采用 RoPE。DeepSeek-V3、GLM-4 系列用的还都是它的变体部分旋转 低频外推根子都是这套旋转思想。6. 贯穿案例给 6×4 矩阵做 RoPE6.1 演示规模设定最后把整个流程跑一遍。先说清楚手算的设定维度 d4拆成 2 对[d₁,d₂] 一对[d₃,d₄] 一对频率θ 1 10000 0 1 \theta_1 10000^{0} 1θ1​1000001高维用高频θ 2 10000 − 0.5 ≈ 0.01 \theta_2 10000^{-0.5} \approx 0.01θ2​10000−0.5≈0.01低维用低频真实规模d4096 时拆 2048 对频率从θ 0 1 \theta_01θ0​1递减到θ 2047 10000 − 2046 / 4096 0.0001 \theta_{2047}10000^{-2046/4096}0.0001θ2047​10000−2046/40960.00016.2 为什么是 10000为什么是递减这两个问题合并回答位置 m 转的角度是m θ m\thetamθθ \thetaθ决定多远的位置才能转一圈。θ 1 \theta1θ1表示m mm增加2 π 2\pi2π约 6.28个位置就转一整圈远距离的位置会周期重合——这正是高频维度负责近距离区分的原因θ 0.01 \theta0.01θ0.01表示m mm增加628 628628个位置才转一整圈这就是低频维度能区分几公里外的位置10000 是几何级数的最大分母控制整套频率从高频转得快到低频转得极慢“的跨度——4096 个频率形成多尺度的时间感”类比手表有秒针转一圈 60 秒分辨近距离的秒变化、分针转一圈 60 分钟、时针转一圈 12 小时跨越大尺度。多频率组合才能同时辨近处和远处。6.3 「西安」行的完整手算以「西安」位置 m1为例手算过程如图 4-6 所示。图4-6 贯穿案例给6×4矩阵做RoPE「西安」行完整手算第一对[ − 0.58 , 0.91 ] [-0.58, 0.91][−0.58,0.91]旋转1 × 1 1 1 \times 1 11×11radx ′ − 0.58 cos ⁡ 1 − 0.91 sin ⁡ 1 − 1.079 , y ′ − 0.58 sin ⁡ 1 0.91 cos ⁡ 1 0.004 x -0.58\cos 1 - 0.91\sin 1 -1.079, \qquad y -0.58\sin 1 0.91\cos 1 0.004x′−0.58cos1−0.91sin1−1.079,y′−0.58sin10.91cos10.004第二对[ 0.27 , − 0.72 ] [0.27, -0.72][0.27,−0.72]旋转1 × 0.01 0.01 1 \times 0.01 0.011×0.010.01rad几乎没转x ′ 0.27 cos ⁡ 0.01 0.72 sin ⁡ 0.01 0.277 , y ′ 0.27 sin ⁡ 0.01 − 0.72 cos ⁡ 0.01 − 0.717 x 0.27\cos 0.01 0.72\sin 0.01 0.277, \qquad y 0.27\sin 0.01 - 0.72\cos 0.01 -0.717x′0.27cos0.010.72sin0.010.277,y′0.27sin0.01−0.72cos0.01−0.717全部 6 行旋转后的结果也在图 4-6 右侧每个数都可套公式验证。真实规模下就是 4096 维拆 2048 对、6 行各转各的——量变多原理不变。到这里位置信息已经揉进矩阵。但矩阵里每个词还是各过各的——「今天」不知道「天气」在旁边「西安」不知道自己在被提问。让词和词之间产生联系就要等下一篇的主角登场Transformer Block 和注意力机制。7. 有没有 RoPE差别到底有多大前面一直在说点积依赖位置差听起来很玄乎。做个具体数字实验拿贯穿案例的「今天」和「天气」两个词向量固定「今天」在位置 0让「天气」依次出现在位置 0、1、2……8分别算点积。不用 RoPE直接把两个词向量点积X 今天 ⋅ X 天气 − 1.5708 \mathbf{X}_{今天} \cdot \mathbf{X}_{天气} -1.5708X今天​⋅X天气​−1.5708不管「天气」在第几位这个数死死定在 -1.5708 不动——没有位置信息的向量是位置盲的距离感为零。用 RoPE 后再点积「天气」的位置 k012345678点积-1.571-0.8760.4961.2770.745-0.617-1.562-1.2270.076点积随距离剧烈变化曲线如图 4-7 所示。图4-7 有无 RoPE 的天壤之别无 → 一条死水平线有 → 距离进了点积红色虚线无 RoPE始终是 -1.571 的水平直线绿色实线有 RoPE从 -1.571 出发在 k3 时冲到 1.277符号都反了到 k6 又回到 -1.562θ1 的周期 2π——点积里塞满了距离信息模型做注意力时自然就有了远近感。再做一个顺序反转实验「今天在天气前」(k1) vs「天气在今天前」(k0 但两词互换位置)顺序点积「今天」在 m0「天气」在 m1-0.8757「天气」在 m0「今天」在 m1-0.9451点积差 0.07同一个词对只是顺序换了注意力分数就不同——这下我吃苹果和苹果吃我在注意力眼里不再是同义句。小结这一篇我们填上了矩阵不知道顺序的坑排列等变性注意力逐行处理、不关心行序我吃苹果和苹果吃我它分不清——必须补位置三条设计要求唯一编码、相对距离、外推性第一代正弦余弦2017公式造波形免训练但加法融合粗暴第二代可学习GPT-2位置当词学效果好但外推死穴 无结构第三代 RoPE2021按位置旋转角度点积只依赖位置差同距离点积实测分毫不差零参数、天然外推贯穿案例6×4 矩阵逐行旋转「西安」行完整手算[ − 0.58 , 0.91 ] → [ − 1.079 , 0.004 ] [-0.58, 0.91] \to [-1.079, 0.004][−0.58,0.91]→[−1.079,0.004]表4-2 三代位置编码对比方案年份相对距离外推性参数量代表模型正弦余弦2017绕三角恒等式理论可以0原始 Transformer可学习2019无结构死穴表上限33MGPT-2 / BERTRoPE2021天然点积位置差天然支持0LLaMA/Qwen/GLM/DeepSeek 全系下一篇预告位置补完了第二个坑还在矩阵里还没有上下文。举个例子——“我今天吃了一个苹果” 和 “苹果今天发布了一款新手机”两句话里的「苹果」是同一个 tokenid 相同嵌入向量一模一样。但一句是水果、一家是公司含义天差地别——这个含义只能由旁边的词决定。而现在的矩阵里「苹果」的向量是死的旁边站着「吃」还是「发布」它自己不会有任何变化。让每个词的向量吸收周围词的信息、活起来靠的就是注意力机制。下一篇正式进入 Transformer 大厦内部先看 Block 的整体结构层归一化 → 注意力 → 残差 → 层归一化 → 前馈网络 → 残差再拆第一块砖层归一化LayerNorm——为什么每层计算前都要把数值拉回同一起跑线。系列目录从一条直线到高维空间分词与 token 表隐藏层与嵌入位置编码 RoPE当前篇Transformer Block 全景与层归一化QKV 三剑客注意力权重与多头机制残差连接与前馈网络输出矩阵与多层堆叠首 token 诞生与 KV-Cache版权声明本文为博主原创文章遵循 CC 4.0 BY-SA 版权协议转载请附上原文出处链接和本声明。