跳转到内容

输入关键词开始搜索

    资料摘要:personal chatgpt 19 — llama2 源码分析 RoPE apply_rotary_emb 从绝对位置编码到相对位置编码

    视频摘要更新 2026-08-02置信度 high待阅读原始来源 ↗#深度#大模型#课程#personal-chatgpt

    本讲由真实视频转录与作者 notebook/代码交叉整理。原始层:🔒 带时间戳视频转录;课程总览:personal chatgpt — LLMs 实践系列

    本讲完成 RoPE 的关键一步:把相邻实数维度配成复数,将第 18 讲预计算的 freqs_cis 广播到 Q/K,执行复数乘法后再恢复原 dtype 和形状。旋转矩阵的乘法性质使位置 mm 的 Q 与位置 nn 的 K 的点积只依赖 nmn-m,从绝对位置旋转得到相对位置注意力。

    课程先强调 position embedding 用来破坏 Transformer 对 token 排列的完全对称性,让模型对顺序敏感。RoPE 不是把位置向量直接加到 token embedding;它把旋转乘到 attention 的 Q 和 K 上。

    令位置 mm 的 query 旋转为 RmqR_mq,位置 nn 的 key 旋转为 RnkR_nk。由于 RmTRn=RnmR_m^TR_n=R_{n-m},二者点积只保留相对位移。

    以 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]

    课程把 RoPE 描述为乘性编码,并在后段引用苏剑林文章讨论随相对距离增大出现的“远程衰减”趋势。Notebook 给出了复指数求和形式,但没有在本 Notebook 中完成大规模实证,因此应作为理论/参考性质说明。

    f(q,m)=Rmqf(q,m)=R_mq

    f(q,m)Tf(k,n)=(Rmq)T(Rnk)=qTRmTRnk=qTRnmk\begin{aligned} f(q,m)^Tf(k,n) &=(R_mq)^T(R_nk)\ &=q^TR_m^TR_nk\ &=q^TR_{n-m}k \end{aligned}

    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 中的参考求和:

    Sj=i=0j1exp(i(mn)θi),θi=100002i/dS_j=\sum_{i=0}^{j-1}\exp(i(m-n)\theta_i),\qquad \theta_i=10000^{-2i/d}

    时间 内容
    00:30 position embedding 破坏 Transformer 的完全对称性
    01:00 左右 RoPE 直接作用于 Q/K,而非加到输入 embedding
    03:41 推导注意力中的 nmn-m 相对位置
    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;不能直接套用于所有架构。
    • 本次未执行;静态检查确认主仓库相对资源存在。
    • 承接第 18 讲: 第 18 讲生成 freqs_cis,本讲把它真正乘到 Q/K。
    • 引出第 20 讲: 旋转后的 K 与同一层的 V 会被缓存,以避免自回归解码重复投影。
    • 回连第 17 讲: RMSNorm 后的 hidden states 先投影为 Q/K/V,再对 Q/K 应用 RoPE。
    1. 为什么 RmTRnR_m^TR_n 会化为只依赖 nmn-m 的旋转?
    2. [1,8,32,128] 为什么在 view_as_complex 后变成 [1,8,32,64]
    3. freqs_cis 为什么要 reshape 成 [1,8,1,64]
    4. RoPE 与经典“把 position embedding 加到输入上”的方式有何区别?
    5. source_bundle 中直接执行哪个单元会因本地资源缺失而失败?
    • 滴答清单抓取时学习状态:已完成
    • 视频正文采用自动语音识别;关键术语已用标题、notebook 与源码校正,无法确认的口语细节不扩写。
    • notebook 未执行的 CUDA、权重下载、训练或外部 API 单元,不表述为已复现实验。