从零手写 RoPE 位置编码:原理、PyTorch 源码实现与可视化理解
深入讲解 RoPE 旋转位置编码的核心原理与 PyTorch 实现。从 2D 旋转矩阵推导相对位置编码,逐行手写代码实现 LLaMA Qwen 风格 RoPE,附热力图可视化帮助理解。适合想彻底搞懂 RoPE 位置编码的开发者。
转载提示:本文转载自 bbruceyuan 原文。原作者:bbruceyuan。原文发布日期:2026-01-01。本文已按站点规范移除原文中的推广/导流内容,仅保留技术分析与示例。0. 阅读收获 (takeaway) 本文旨在彻底搞懂 RoPE(Rotary Position Embedding)位置编码,阅读完本文你将获得:理解 RoPE 的核心思想:为什么用"旋转"来编码位置信息掌握 RoPE 的数学原理:从旋转矩阵到三角函数证明从零手写 RoPE 实现:逐行代码讲解,可直接运行bonus:可视化理解 RoPE:通过热力图和动画直观感受旋转编码 本文代码运行于: Featurize 蒜粒方块 GPU 算力平台,有 GPU 使用需求的同学希望能使用我的邀请链接注册 待更新:不喜欢看文字的同学可以看 B站视频-chaofa用代码打点酱油, YouTube-chaofa用代码打点酱油,或视频号:chaofa用代码打点酱油1. 为什么需要位置编码? 在 Transformer 架构中,Self-Attention 机制本身是位置无关的。公式如下: $$ \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$ softmax 中 QK 的乘积就是重要性权重,什么意思呢?# 假设我们有两个句子 sentence1 = "朝发 写 代码" sentence2 = "代码 写 朝发" # 对于纯 Self-Attention 来说,这两个句子的表示是一样的! # 从公式看 Attention 只关心 token 之间的权重关系,不关心它们的顺序 这显然是不对的。语言是有顺序的,顺序不同意思完全不同。因此,我们需要位置编码(Position Encoding, PE)来告诉模型每个 token 在序列中的位置。1.1 绝对位置编码 vs 相对位置编码 用一个例子来理解这两种编码方式的区别:句子: "朝发 写 代码" 位置: 0 1 2 绝对位置编码:给每个位置一个固定编号"朝发" → 位置 0 → PE_0 "写" → 位置 1 → PE_1 "代码" → 位置 2 → PE_2 备注:PE_0 表示第一个位置的 embedding 相对位置编码:关注两个 token 之间的距离计算 "朝发" 和 "代码" 的关系时: → 不关心它们分别在位置 0 和 2 → 只关心它们相距 2 个位置 同理:计算 "朝发" 和 "写" 之间的相对位置是 (1 - 0) = 1。 使用相对位置编码就是希望捕获 Token 之间位置的相对关系,保持(某些)语义的不变性,下面 「朝发」和「代码」之间的关系是一样的,尽管绝对位置不同:句子 A: "朝发 写 代码" 句子 B: "今天 朝发 写 代码" 2. RoPE 的核心思想 RoPE(Rotary Position Embedding,旋转位置编码)的核心思想非常优雅,可以阅读苏神 RoPE blog: 通过旋转变换为向量注入位置信息,使得两个向量的内积只依赖于它们的相对位置。 这句话怎么理解呢?让我们一步步拆解看。2.1 从 2D 旋转说起 假设我们在二维平面上有一个向量 $(x, y)$,将它旋转角度 $\theta$ 后得到新向量: $$ \begin{pmatrix} x' \ y' \end{pmatrix} = \begin{pmatrix} \cos\theta & -\sin\theta \ \sin\theta & \cos\theta \end{pmatrix} \begin{pmatrix} x \ y \end{pmatrix} $$ 这就是经典的 2D 旋转矩阵。下面用一张图来直观理解: 2D 向量旋转示意图 从图中可以看到:蓝色向量 $(x, y)$ 绕原点逆时针旋转角度 $\theta$ 后,变成红色向量 $(x', y')$。2.2 RoPE 的目标与解决方案 目标:我们希望找到一个位置编码函数 $f$,使得 query 向量 $\mathbf{q}_m$ 和 key 向量 $\mathbf{k}_n$ 的内积只依赖于它们的相对位置 $(m-n)$: $$ \langle f_q(\mathbf{q}, m), f_k(\mathbf{k}, n) \rangle = g(\mathbf{q}, \mathbf{k}, m-n) $$ 也就是说,无论 $m$ 和 $n$ 的绝对值是多少,只要 $m-n$ 相同,内积结果就相同。 解决方案:RoPE 发现,这个函数 $f$ 就是旋转函数!(实际上是可以通过求解出来的,可以参考:Transformer升级之路:2、博采众…
正在初始化 WebAssembly 引擎…
首次编译原生模块可能需要数秒
就绪后,页面交互将以接近原生的速度运行