跳转到内容

输入关键词开始搜索

    资料摘要:personal chatgpt 28 — 从 RoPE 到 CoPE(绝对位置编码,相对位置编码,Contextual Position Encoding)

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

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

    本讲先回答 Transformer 为什么需要位置编码,再串联三类方案:BERT/GPT 的可学习绝对位置 embedding、原始 Transformer 的固定正弦绝对位置编码、Llama 的 RoPE 相对位置编码;最后介绍 CoPE。CoPE 不再只按 token 下标计数,而是由 query-key 相似度产生 gate,累积出与上下文相关、通常非整数的“软位置”,再插值可学习位置 embedding 并加入 attention logits。

    对输入 XR×dX\in\mathbb R^{\ell\times d}

    Q=XWq,K=XWk,V=XWvQ=XW_q,\quad K=XW_k,\quad V=XW_v

    Attention(Q,K,V)=softmax(QKTdk)V\operatorname{Attention}(Q,K,V)= \operatorname{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V

    X/Q/KX/Q/K 没有任何位置信息,qiTkjq_i^Tk_j 只反映 token 内容,不能区分相同 token 的排列顺序,因此序列建模必须另行编码位置。

    • BERT/GPT:token embedding 与可学习 position embedding 相加;BERT 还叠加 token-type embedding。
    • 正弦编码:同样是绝对位置,但由固定函数生成,不参与训练:

    PE(t,2i)=sin(t100002i/d),PE(t,2i+1)=cos(t100002i/d)PE(t,2i)=\sin\left(\frac{t}{10000^{2i/d}}\right),\quad PE(t,2i+1)=\cos\left(\frac{t}{10000^{2i/d}}\right)

    两者都先为单个位置 tt 构造表示,再加到输入 embedding。

    RoPE 不直接加到 XX,而是旋转 Q/K:

    (Rmq)T(Rnk)=qTRmTRnk=qTRnmk(R_mq)^T(R_nk)=q^TR_m^TR_nk=q^TR_{n-m}k

    因此点积只依赖相对位移 nmn-m。notebook 用二维旋转块拼成高维正交矩阵,并用 PyTorch 验证 RmTRn=RnmR_m^TR_n=R_{n-m};源码则把相邻维度视为复数,通过:

    freqs = 1.0 / theta ** (torch.arange(0, dim, 2) / dim)
    freqs = torch.outer(torch.arange(end), freqs)
    freqs_cis = torch.polar(torch.ones_like(freqs), freqs)

    预计算全局旋转频率。

    普通相对位置只使用 iji-j,与句子/段落边界无关。CoPE 的 gate:

    gij=σ(qiTkj)g_{ij}=\sigma(q_i^Tk_j)

    从当前位置向左累积得到软位置:

    pij=k=jigikp_{ij}=\sum_{k=j}^{i}g_{ik}

    若所有 gate 都是 1,则退化为按 token 计数;一般 pijp_{ij} 是非整数,并随 query 与上下文改变。课程用多句文本示意:理想 gate 可让多个 token 属于同一“语义位置区间”,从而按句子或段落计数,而不只是按 token 距离衰减。

    5. 非整数位置的插值与高效实现

    Section titled “5. 非整数位置的插值与高效实现”

    对可学习 embedding e[p]e[p] 做线性插值:

    e[pij]=we[pij]+(1w)e[pij],w=pijpije[p_{ij}]=w,e[\lceil p_{ij}\rceil]+(1-w)e[\lfloor p_{ij}\rfloor], \quad w=p_{ij}-\lfloor p_{ij}\rfloor

    为避免逐 (i,j) 物化 embedding,先算:

    zi[p]=qiTe[p]z_i[p]=q_i^Te[p]

    再对标量 logits 插值,最终:

    a_{ij}=\operatorname{softmax}\left(q_i^Tk_j+z_i[p_{ij}] ight)

    notebook 代码通过 flip → cumsum → flip 从右向左累积 gate,并把 CoPE logits 加到标准 attention logits。

    gates = torch.sigmoid(attn_logits)
    pos = gates.flip(-1).cumsum(dim=-1).flip(-1)
    pos = pos.clamp(max=npos_max - 1)
    pos_ceil = pos.ceil().long()
    pos_floor = pos.floor().long()
    logits_int = torch.matmul(query, pos_emb)
    w = pos - pos_floor
    cope_logits = logits_int.gather(-1, pos_ceil) * w \
    + logits_int.gather(-1, pos_floor) * (1 - w)

    CoPE 修改的是 attention logits;value 加权流程仍是 softmax 后乘 VV

    • 00:00:提出 CoPE,并连接此前 RoPE 课程。
    • 01:00:从 attention 公式解释位置编码必要性。
    • 04:27:进入 BERT/GPT 的加性绝对位置编码。
    • 06:35:进入固定 sine/cosine 绝对位置编码。
    • 08:26:回顾 RoPE 的相对位置性质。
    • 10:18:旋转矩阵与 RmTRnR_m^TR_n
    • 13:00:查看 Llama precompute_freqs_cis 频率计算。
    • 18:00:用矩阵实验验证 RmTRn=RnmR_m^TR_n=R_{n-m}
    • 19:00:正式进入 CoPE。
    • 21:57:gate gij=σ(qiTkj)g_{ij}=\sigma(q_i^Tk_j)
    • 22:06:从右向左累积软位置。
    • 24:00:非整数位置与插值。
    • 25:41:查看 CoPE/SelfAttention 代码。
    • notebook 主要做公式、矩阵验证和论文代码阅读,没有训练 CoPE 模型,也没有复现实验指标。
    • 示例代码省略多头、batch 广播、dropout、缓存和高性能 kernel 等生产细节。
    • mask.log() 假定 mask 为 0/1;其它 mask 表示需改写。
    • “按句子/段落定位”是论文动机与示意能力,不代表 gate 一定自动学出明确语言学边界。
    • CoPE 是 2024 年研究方案;本讲没有证据表明它已成为主流 LLM 默认位置编码。
    • 前接第 18–19 讲:此前已从复数和源码讲 RoPE;本讲先复习再与 CoPE 对照。
    • 前接第 25 讲:Llama 3 仍采用 RoPE,说明 CoPE 是替代/研究方向而非该模型既有组件。
    • 后接第 29 讲:回到 Llama 2 7B 与 Llama 3 8B 的真实架构对比。
    1. 为什么不加位置编码的 self-attention 无法区分 token 排列?
    2. BERT/GPT 的 position embedding 与 RoPE 分别作用在哪个张量上?
    3. RmTRn=RnmR_m^TR_n=R_{n-m} 为什么带来相对位置?
    4. CoPE 的 pijp_{ij} 为什么通常不是整数?
    5. flip-cumsum-flip 在 CoPE 代码中实现了什么方向的累积?
    • 滴答清单抓取时学习状态:未完成
    • 视频正文采用自动语音识别;关键术语已用标题、notebook 与源码校正,无法确认的口语细节不扩写。
    • notebook 未执行的 CUDA、权重下载、训练或外部 API 单元,不表述为已复现实验。