资料摘要:personal chatgpt 19 — llama2 源码分析 RoPE apply_rotary_emb 从绝对位置编码到相对位置编码
本讲由真实视频转录与作者 notebook/代码交叉整理。原始层:🔒 带时间戳视频转录;课程总览:personal chatgpt — LLMs 实践系列。
本讲完成 RoPE 的关键一步:把相邻实数维度配成复数,将第 18 讲预计算的 freqs_cis 广播到 Q/K,执行复数乘法后再恢复原 dtype 和形状。旋转矩阵的乘法性质使位置 的 Q 与位置 的 K 的点积只依赖 ,从绝对位置旋转得到相对位置注意力。
1. 位置编码的作用
Section titled “1. 位置编码的作用”课程先强调 position embedding 用来破坏 Transformer 对 token 排列的完全对称性,让模型对顺序敏感。RoPE 不是把位置向量直接加到 token embedding;它把旋转乘到 attention 的 Q 和 K 上。
2. 从旋转矩阵得到相对位置
Section titled “2. 从旋转矩阵得到相对位置”令位置 的 query 旋转为 ,位置 的 key 旋转为 。由于 ,二者点积只保留相对位移。
3. apply_rotary_emb 的形状变化
Section titled “3. apply_rotary_emb 的形状变化”以 7B 示例为准:Q/K 输入 [1, 8, 32, 128]。代码把最后 128 维每两维配对,转换为复数 [1, 8, 32, 64];freqs_cis 从 [8, 64] reshape/broadcast 为 [1, 8, 1, 64];复数乘法后用 view_as_real(...).flatten(3) 恢复 [1, 8, 32, 128]。
4. 乘性位置编码与远程衰减
Section titled “4. 乘性位置编码与远程衰减”课程把 RoPE 描述为乘性编码,并在后段引用苏剑林文章讨论随相对距离增大出现的“远程衰减”趋势。Notebook 给出了复指数求和形式,但没有在本 Notebook 中完成大规模实证,因此应作为理论/参考性质说明。
公式 / 代码
Section titled “公式 / 代码”
def apply_rotary_emb(xq, xk, freqs_cis): xq_ = torch.view_as_complex( xq.float().reshape(*xq.shape[:-1], -1, 2) ) xk_ = torch.view_as_complex( xk.float().reshape(*xk.shape[:-1], -1, 2) ) freqs_cis = reshape_for_broadcast(freqs_cis, xq_) xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3) xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3) return xq_out.type_as(xq), xk_out.type_as(xk)Notebook 中的参考求和:
| 时间 | 内容 |
|---|---|
| 00:30 | position embedding 破坏 Transformer 的完全对称性 |
| 01:00 左右 | RoPE 直接作用于 Q/K,而非加到输入 embedding |
| 03:41 | 推导注意力中的 相对位置 |
| 04:47 | 进入 apply_rotary_emb |
| 06:39 | 阅读复数转换与广播代码 |
| 08:25 | 追踪 [1,8,32,128] → [1,8,32,64] 等形状 |
| 10:00 左右 | 复数乘法后恢复实数形状与 dtype |
| 14:18 | 讨论远程衰减性质 |
- 运行标签:conditional。 主体张量演示可在 CPU 运行,但 Notebook 后段从
./tokenizer.model加载 SentencePiece;该文件在主仓库tutorials/中存在,在source_bundle/code/lesson_19/中缺失。 - 需要 PyTorch、NumPy、Matplotlib、sentencepiece;无需下载大模型。
- 形状示例默认 Llama 2 7B 的
dim=4096、32 heads、head_dim=128;不能直接套用于所有架构。 - 本次未执行;静态检查确认主仓库相对资源存在。
与前后讲关系
Section titled “与前后讲关系”- 承接第 18 讲: 第 18 讲生成
freqs_cis,本讲把它真正乘到 Q/K。 - 引出第 20 讲: 旋转后的 K 与同一层的 V 会被缓存,以避免自回归解码重复投影。
- 回连第 17 讲: RMSNorm 后的 hidden states 先投影为 Q/K/V,再对 Q/K 应用 RoPE。
- 为什么 会化为只依赖 的旋转?
[1,8,32,128]为什么在view_as_complex后变成[1,8,32,64]?freqs_cis为什么要 reshape 成[1,8,1,64]?- RoPE 与经典“把 position embedding 加到输入上”的方式有何区别?
- 在
source_bundle中直接执行哪个单元会因本地资源缺失而失败?
- 视频:llama2 源码分析 RoPE apply_rotary_emb 从绝对位置编码到相对位置编码
- 转录:🔒 personal chatgpt 19 视频转录
- 课件 / 代码:🔒 llama2_src_03_RoPE_apply_rotary_emb.ipynb
- 滴答清单抓取时学习状态:已完成。
- 视频正文采用自动语音识别;关键术语已用标题、notebook 与源码校正,无法确认的口语细节不扩写。
- notebook 未执行的 CUDA、权重下载、训练或外部 API 单元,不表述为已复现实验。