游乐游手机版
首页/AI教程/文章详情

大模型位置编码深度解析:模型如何理解顺序?

时间:2026-07-01 15:28
注意力机制的“位置盲区” 上一章我们探讨了注意力机制如何借助 QKV(Query-Key-Value)矩阵计算 Token 之间的相关性。然而,其中隐藏着一个关键的问题: 注意力机制天生就像个“路痴”——它根本无法感知 Token 的前后顺序! 问题演示 我们来观察这两个句子: "猫 吃 鱼 " "鱼

注意力机制的“位置盲区”

上一章我们探讨了注意力机制如何借助 QKV(Query-Key-Value)矩阵计算 Token 之间的相关性。然而,其中隐藏着一个关键的问题:

02-大模型位置编码详解:大模型如何理解顺序?

注意力机制天生就像个“路痴”——它根本无法感知 Token 的前后顺序!

问题演示

我们来观察这两个句子:

  1. "猫 吃 鱼"
  2. "鱼 吃 猫"

对于注意力机制而言,如果仅仅交换 Token 的顺序,其计算过程如下:

...(公式不变)...

由于 QKV 均通过相同的权重矩阵 W_QW_KW_V 从 Embedding 计算得出,如果我们仅交换了 Token 的顺序,而未向模型提供任何“位置信息”,那么注意力机制会认为这两个句子是等同的。

具体来看,注意力计算公式:

Attention(Q,K,V)=softmax(Q·K^T/√d_k)·V

在这个公式中,没有任何一处体现了 Token 的位置信息。

为什么位置如此重要?

在自然语言中,位置直接决定了语义:

  • "我不喜欢你" 与 "我喜欢你不?"(语义截然不同)
  • "小明打了小红" 与 "小红打了小明"(主宾关系完全颠倒)
  • "因为下雨,所以取消" 与 "取消,所以因为下雨"(逻辑关系混乱)

从更技术的层面来看:

  1. 语法结构:主语通常在前,谓语居中,宾语在后
  2. 时间顺序:事件发生的先后次序
  3. 依赖关系:前面的 Token 会被后面的 Token 引用(即代词指代)
  4. 自回归生成:在生成第 n+1 个 Token 时,只能依赖前 n 个 Token,无法预知“未来”信息

因此,我们必须向模型注入位置信息,这正是位置编码所承担的角色。

位置编码的核心思想

位置编码的目标其实相当明确:

数学表达:

输入带位置信息的表示 = Token Embedding + Positional Encoding,即 X_with_pos[i] = X[i] + PE[i]

其中:

  • X[i] 是第 i 个 Token 的原始 Embedding(维度为 d_model)
  • PE[i] 是第 i 个位置的位置编码向量(维度同样为 d_model)
  • X_with_pos[i] 是最终输入到注意力层的表示

原始位置编码(Sinusoidal Positional Encoding)

Transformer 原始论文(Vaswani et al., 2017)提出了一种基于正弦和余弦函数的位置编码方案。

公式

对于位置 pos(即第几个 Token,从 0 开始)和维度 i(即向量的第几维,从 0 开始):

PE(pos,2i)=sin(pos/10000^{2i/d_model}),PE(pos,2i+1)=cos(pos/10000^{2i/d_model})

参数解释:

  • pos:Token 的位置索引(0, 1, 2, 3, ...)
  • i:位置编码向量的维度索引(0, 1, 2, …, d_model/2−1)
  • 2i:偶数维度采用 sin 函数
  • 2i+1:奇数维度采用 cos 函数
  • 10000:基数,用于控制频率的衰减速度
  • d_model:位置编码向量的维度(与 Token Embedding 的维度相同)

直观理解

该公式的核心思路是:运用不同频率的正弦波来编码位置。不妨想象一个时钟:秒针转动最快,分针速度中等,时针最慢。在不同的时刻,三根针的组合是独一无二的,这便能唯一地标识一个时间点。

类似地:

  • 低维度(2i 较小):采用低频正弦波,变化缓慢,能够区分远距离的位置
  • 高维度(2i 较大):采用高频正弦波,变化迅速,能够区分近距离的位置

具体例子

假设 d_model=4(为简化说明),我们计算前 3 个位置的位置编码。

位置 pos=0:

PE[0]=[0,1,0,1]

位置 pos=1:

PE[1]=[0.841,0.540,0.01,1.0]

位置 pos=2:

PE[2]=[0.909,-0.416,0.02,0.9998]

由此可见,每个位置都拥有一个独一无二的向量表示。

Sinusoidal 编码的优势

  1. 确定性:无需学习,直接通过公式计算即可得到
  2. 外推性:即便训练时仅见过长度为 100 的序列,也能为长度为 200 的序列生成位置编码
  3. 相对位置:凭借三角函数的性质,模型可以学习到相对位置关系(数学性质:PE(pos+k) 可以表示为 PE(pos) 的线性变换)

Sinusoidal 编码的劣势

  1. 外推性有限:虽然理论上可外推,但在超长序列上实际效果会下降
  2. 位置信息弱:仅通过简单的加法融合,位置信息容易被 Embedding 所淹没
  3. 无法区分绝对位置重要性:远距离和近距离的位置采用相同的编码方式

可学习的绝对位置编码(Learned Positional Encoding)

另一种简洁的方案是:将位置编码视为模型参数,在训练过程中进行学习。

实现方式

创建一个可学习的 Embedding 矩阵:

PE_learned ∈ R^{max_seq_len × d_model}

对于位置 pos:直接查表获取 PE[pos] = PE_learned[pos]

参数解释:

  • max_seq_len:支持的最大序列长度(例如 512、2048 等)
  • PE_learned 是一个可训练的参数矩阵
  • 在训练过程中,这个矩阵会通过反向传播进行更新

优势与劣势

优势

  • 灵活性高,模型能够自主学习最优的位置表示
  • 实现简单

劣势

  • 无法外推:若训练时最大长度为 512,则无法处理长度超过 512 的序列
  • 参数量增加:需要额外存储 max_seq_len × d_model 个参数

这种方案在 BERT、GPT 等早期模型中得到应用,但现代大模型更倾向于采用 RoPE 等相对位置编码。

RoPE:旋转位置编码(Rotary Position Embedding)

RoPE(Su et al., 2021)是目前最流行的一种位置编码方案,被 LLaMA、GPT-NeoX、PaLM 等主流大模型所采用。

核心思想:直接作用于注意力计算

RoPE 与传统位置编码的最大区别在于:它并非在输入阶段添加位置信息,而是直接作用于注意力机制的计算过程。

传统方法(Sinusoidal、Learned PE):

步骤1:在输入阶段加入位置信息
X_with_pos = X + PE

步骤2:计算Q、K、V
Q = X_with_pos · W_Q
K = X_with_pos · W_K
V = X_with_pos · W_V

步骤3:计算注意力分数
Score = Q · K^T

RoPE 方法

步骤1:先计算Q、K(不含位置信息)
Q = X · W_Q
K = X · W_K
V = X · W_V

步骤2:对Q、K应用旋转矩阵(注入位置信息)
Q_with_pos[m] = R_Θ(m) · Q[m]   (位置m的Query向量)
K_with_pos[n] = R_Θ(n) · K[n]   (位置n的Key向量)

步骤3:计算注意力分数
Score(m,n) = Q_with_pos[m] · K_with_pos[n]^T

关键区别

  1. 传统方法:位置信息通过加法混入 Embedding,然后一起参与 Q、K、V 的线性变换
  2. RoPE:位置信息通过旋转变换直接作用于已计算好的 Q、K 上,在注意力分数计算时才引入位置信息

为什么这样更好?在传统加法中,位置信息和内容信息在 Embedding 层混合,不同的线性变换会破坏位置关系。而 RoPE 通过几何旋转注入位置信息,保持了相对位置的数学性质,使得 Score(m,n) 自然地仅依赖于相对位置 (m−n)。

为什么叫“旋转”?

在二维平面上,将一个向量旋转 θ 角度,可以通过旋转矩阵来表示:

[x' y']^T = [[cosθ, -sinθ],[sinθ, cosθ]] · [x y]^T

RoPE 正是将这个思想推广到了高维空间:每一对维度作为一个平面,进行不同角度的旋转。

RoPE 的数学公式

对于位置 m 的 Query 向量和位置 n 的 Key 向量,RoPE 将它们分别旋转:

q_m = R_Θ(m) · W_Q · x_m,k_n = R_Θ(n) · W_K · x_n

其中,旋转矩阵 R_Θ(pos) 是一个分块对角矩阵:

R_Θ(pos)=[[cos(pos·θ₀), -sin(pos·θ₀), 0, 0, ...],[sin(pos·θ₀), cos(pos·θ₀), 0, 0, ...],[0, 0, cos(pos·θ₁), -sin(pos·θ₁), ...],[0, 0, sin(pos·θ₁), cos(pos·θ₁), ...],[..., ..., ..., ..., ⋱]]

参数解释:

  • pos:Token 的位置(0, 1, 2, ...)
  • θ_i:第 i 对维度的旋转频率,计算方式:θ_i = 10000^{-2i/d_model}
  • 每两个维度一组,共 d_model/2 组
  • 每组使用不同的旋转频率 θ_i

简化表示(逐元素形式)

对于 Query 向量的第 2i 和 2i+1 维(即一对维度):

q_m[2i] = q[2i]·cos(m·θ_i) - q[2i+1]·sin(m·θ_i) q_m[2i+1] = q[2i]·sin(m·θ_i) + q[2i+1]·cos(m·θ_i)

对于 Key 向量同理:

k_n[2i] = k[2i]·cos(n·θ_i) - k[2i+1]·sin(n·θ_i) k_n[2i+1] = k[2i]·sin(n·θ_i) + k[2i+1]·cos(n·θ_i)

其中 θ_i = 10000^{-2i/d_model}。

RoPE 融合进注意力计算的完整流程

假设我们有一个序列:["我", "喜欢", "猫"],共 3 个 Token,位置分别为 0、1、2。我们一步步来看 RoPE 是如何运作的。

步骤1:获取 Token Embedding(不含位置信息)

X = [x₀, x₁, x₂]^T ∈ R^{3×d_model}

其中 x₀、x₁、x₂ 分别是“我”、“喜欢”、“猫”的 Embedding 向量。

步骤2:计算原始的 Q、K、V(仍不含位置信息)

Q = X·W_Q = [q₀, q₁, q₂]^T ∈ R^{3×d_k} K = X·W_K = [k₀, k₁, k₂]^T ∈ R^{3×d_k} V = X·W_V = [v₀, v₁, v₂]^T ∈ R^{3×d_v}

请注意:到这一步为止,Q、K、V 都还没有任何位置信息!

步骤3:对 Q、K 应用 RoPE 旋转(注入位置信息)

这是 RoPE 的核心步骤!对每个位置的 Q 和 K 向量应用旋转:

位置0的Token:"我"
Q_rot[0] = R_Θ(0) · q₀  (旋转0度,保持不变)
K_rot[0] = R_Θ(0) · k₀

位置1的Token:"喜欢"
Q_rot[1] = R_Θ(1) · q₁  (旋转θ角度)
K_rot[1] = R_Θ(1) · k₁

位置2的Token:"猫"
Q_rot[2] = R_Θ(2) · q₂  (旋转2θ角度)
K_rot[2] = R_Θ(2) · k₂

V 向量不进行旋转,因为 V 包含的是“内容信息”,只有 Q 和 K 需要位置信息来计算相关性。

步骤4:计算注意力分数矩阵(位置信息已融合)

现在计算所有位置对之间的注意力分数:

Scores = Q_rot · K_rot^T = [[Q_rot[0]·K_rot[0]^T, Q_rot[0]·K_rot[1]^T, Q_rot[0]·K_rot[2]^T], [Q_rot[1]·K_rot[0]^T, Q_rot[1]·K_rot[1]^T, Q_rot[1]·K_rot[2]^T], [Q_rot[2]·K_rot[0]^T, Q_rot[2]·K_rot[1]^T, Q_rot[2]·K_rot[2]^T]]

关键之处在于:每个分数 Q_rot[m]·K_rot[n]^T 自动包含了位置 m 和位置 n 之间的相对位置信息 (m−n)!

步骤5:应用 Softmax 和加权求和(标准流程)

Attention_Weights = softmax(Scores/√d_k) Output = Attention_Weights · V

对比总结:RoPE vs 传统方法

步骤传统位置编码RoPE
1. 输入X + PEX(纯内容)
2. 计算QKVQ = (X+PE)·W_QQ = X·W_Q
3. 位置注入❌(已在步骤1完成)✅ Q_rot = R_Θ(pos)·Q
4. 注意力分数Q·K^T(位置信息已稀释)Q_rot·K_rot^T(位置信息精确)

核心优势:RoPE 在注意力分数计算的关键时刻才引入位置信息,通过旋转的几何性质,确保了注意力分数仅依赖于相对位置差,而非绝对位置。

RoPE 的关键性质

性质1:注意力分数自动包含相对位置信息

当计算位置 m 和位置 n 之间的注意力分数时:

Attention_Score(m,n) = q_m^T·k_n =(展开后,对于第i对维度)= [q[2i]·k[2i] + q[2i+1]·k[2i+1]] × cos((m-n)·θ_i)

核心发现:注意力分数仅依赖于 (m−n),即相对位置差,而非绝对位置 m 或 n!

这意味着:

  • 位置0的Token看位置1的Token,与位置5的Token看位置6的Token,其注意力模式是相同的(相对位置都是+1)
  • 模型能够自然地学习到相对位置关系

性质2:远距离衰减

由于使用了不同频率的旋转:

  • 低频分量(θ_i 小):捕捉长距离依赖
  • 高频分量(θ_i 大):捕捉短距离依赖

相对位置距离越远,高频分量的点积越接近于0,注意力自然衰减。

具体例子

假设 d_model=4,我们计算位置0和位置1的 Query 向量:

步骤1:计算旋转频率

θ₀ = 10000^{-0/4} = 1 θ₁ = 10000^{-2/4} = 0.01

步骤2:对位置 m=0,旋转角度为0

q₀[0]=q[0], q₀[1]=q[1], q₀[2]=q[2], q₀[3]=q[3]

位置0不旋转,保持原样。

步骤3:对位置 m=1,旋转角度为θ

q₁[0] ≈ 0.540·q[0] - 0.841·q[1] q₁[1] ≈ 0.841·q[0] + 0.540·q[1] q₁[2] ≈ 0.99995·q[2] - 0.01·q[3] q₁[3] ≈ 0.01·q[2] + 0.99995·q[3]

可以看到:

  • 第0-1维(高频):旋转了约54度,变化明显
  • 第2-3维(低频):仅旋转了约0.57度,几乎不变

RoPE 的优势

  1. 相对位置编码:注意力分数自动包含相对位置信息,不依赖于绝对位置
  2. 外推性好:理论上可以处理任意长度的序列
  3. 长距离衰减:远距离 Token 的注意力自然衰减,符合语言学规律
  4. 无额外参数:不增加模型的参数量
  5. 高效实现:可以预计算旋转矩阵,推理时直接查表

RoPE 的实现细节

在实际代码中,RoPE 通常这样实现。下面展示完整的带 RoPE 的注意力计算流程:

import torch
import torch.nn.functional as F

# ============ 第一步:预计算RoPE的旋转矩阵(初始化时执行一次) ============
def precompute_rope_cache(d_model, max_seq_len=2048):
    """预计算RoPE需要的cos和sin值"""
    # 计算旋转频率 θ_i = 10000^(-2i/d_model)
    theta = 10000 ** (-2 * torch.arange(d_model // 2) / d_model)
    # theta shape: (d_model/2,)
    # 生成位置索引 [0, 1, 2, ..., max_seq_len-1]
    pos = torch.arange(max_seq_len)
    # pos shape: (max_seq_len,)
    # 计算所有位置和所有频率的组合:pos * θ_i
    freqs = torch.outer(pos, theta)
    # shape: (max_seq_len, d_model/2)
    # 预计算cos和sin值,推理时直接查表
    cos_cache = freqs.cos()  # shape: (max_seq_len, d_model/2)
    sin_cache = freqs.sin()  # shape: (max_seq_len, d_model/2)
    return cos_cache, sin_cache

# ============ 第二步:应用RoPE旋转(在每次forward时执行) ============
def apply_rope(x, cos, sin):
    """对Q或K向量应用RoPE旋转
    Args:
        x: shape (batch, seq_len, d_model) - Q或K矩阵
        cos: shape (seq_len, d_model/2) - 预计算的cos值
        sin: shape (seq_len, d_model/2) - 预计算的sin值
    Returns:
        旋转后的向量,shape (batch, seq_len, d_model)
    """
    # 将x分为偶数维和奇数维
    x1 = x[..., 0::2]  # shape: (batch, seq_len, d_model/2) - 第0,2,4,...维
    x2 = x[..., 1::2]  # shape: (batch, seq_len, d_model/2) - 第1,3,5,...维
    # 应用旋转公式:
    # x_rot[2i] = x[2i] * cos(pos*θ_i) - x[2i+1] * sin(pos*θ_i)
    # x_rot[2i+1] = x[2i] * sin(pos*θ_i) + x[2i+1] * cos(pos*θ_i)
    x_rotated = torch.stack([
        x1 * cos - x2 * sin,  # 偶数维
        x1 * sin + x2 * cos   # 奇数维
    ], dim=-1).flatten(-2)  # 交错拼接回 (batch, seq_len, d_model)
    return x_rotated

# ============ 第三步:完整的带RoPE的注意力计算 ============
def attention_with_rope(X, W_Q, W_K, W_V, cos_cache, sin_cache):
    """完整的注意力计算流程,展示RoPE如何融合进来
    Args:
        X: shape (batch, seq_len, d_model) - 输入的Token Embeddings(不含位置信息)
        W_Q, W_K, W_V: 权重矩阵
        cos_cache, sin_cache: 预计算的RoPE缓存
    """
    batch, seq_len, d_model = X.shape
    # 步骤1:计算原始的Q、K、V(不含位置信息)
    Q = torch.matmul(X, W_Q)  # shape: (batch, seq_len, d_k)
    K = torch.matmul(X, W_K)  # shape: (batch, seq_len, d_k)
    V = torch.matmul(X, W_V)  # shape: (batch, seq_len, d_v)
    print("步骤1完成:计算Q、K、V(纯内容,无位置信息)")

    # 步骤2:对Q、K应用RoPE旋转(注入位置信息)
    cos = cos_cache[:seq_len]  # 截取当前序列长度
    sin = sin_cache[:seq_len]
    Q_rot = apply_rope(Q, cos, sin)  # shape: (batch, seq_len, d_k)
    K_rot = apply_rope(K, cos, sin)  # shape: (batch, seq_len, d_k)
    # 注意:V不旋转!V只包含内容信息
    print("步骤2完成:对Q、K应用旋转(位置信息已注入)")

    # 步骤3:计算注意力分数(位置信息已在Q_rot和K_rot中)
    d_k = Q_rot.shape[-1]
    scores = torch.matmul(Q_rot, K_rot.transpose(-2, -1)) / torch.sqrt(torch.tensor(d_k))
    print("步骤3完成:计算注意力分数(自动包含相对位置信息)")

    # 步骤4:Softmax + 加权求和(标准流程)
    attn_weights = F.softmax(scores, dim=-1)
    output = torch.matmul(attn_weights, V)
    print("步骤4完成:加权求和得到输出")
    return output, attn_weights

# ============ 使用示例 ============
# 初始化(只需一次)
d_model = 512
max_seq_len = 2048
cos_cache, sin_cache = precompute_rope_cache(d_model, max_seq_len)

# 前向传播(每次推理)
batch_size = 2
seq_len = 10
X = torch.randn(batch_size, seq_len, d_model)  # 输入Token Embeddings
# 假设已初始化权重矩阵
W_Q = torch.randn(d_model, d_model)
W_K = torch.randn(d_model, d_model)
W_V = torch.randn(d_model, d_model)

# 执行注意力计算(RoPE在步骤2自动应用)
output, attn_weights = attention_with_rope(X, W_Q, W_K, W_V, cos_cache, sin_cache)
print(f"\n最终输出 shape: {output.shape}")  # (batch_size, seq_len, d_model)

代码关键点解释:

  1. 预计算阶段precompute_rope_cache):

    • 仅在模型初始化时执行一次
    • 计算所有可能位置的 cos(pos·θ_i) 和 sin(pos·θ_i)
    • 存储在缓存中,推理时直接查表
  2. RoPE 应用阶段apply_rope):

    • 在计算完 Q、K 后立即应用
    • 将向量的每对维度 (2i, 2i+1) 作为一个平面进行旋转
    • V 向量不旋转,因为 V 存储的是“内容”,不需要位置信息
  3. 融合进注意力计算attention_with_rope):

    • 步骤1:Q = X·W_Q(不含位置)
    • 步骤2:Q_rot = R_Θ(pos)·Q(RoPE 在这里注入位置)
    • 步骤3:Scores = Q_rot·K_rot^T(位置信息自动体现在分数中)
    • 步骤4:标准的 softmax 和加权求和

与传统方法的对比:

时间点传统位置编码RoPE
输入阶段X = X + PE(位置信息混入)X(纯内容)
计算QKVQ = X · W_Q(位置已混入)Q = X · W_Q(纯内容)
位置注入❌(已完成)Q_rot = apply_rope(Q)(在这里!)
计算分数Q · K^TQ_rot · K_rot^T

RoPE 的优势在于:位置信息在注意力分数计算的关键时刻才引入,通过旋转的几何性质精确地编码了相对位置关系。

RoPE 的长度扩展技术

虽然 RoPE 理论上可以外推,但在实际应用中,当序列长度远超训练时的长度时,性能会下降。为此,研究者提出了多种长度扩展技术。

问题:为什么需要长度扩展?

假设模型在训练时仅见过长度 ≤ 2048 的序列,当推理时输入长度 4096 的序列:

  • 位置编码会遇到“未见过”的旋转角度
  • 高频分量的旋转角度过大,导致注意力模式混乱
  • 模型性能显著下降

方法1:位置插值(Position Interpolation, PI)

核心思想:将长序列的位置“压缩”到训练时的范围内

原始位置:pos ∈ [0, L_new];压缩后:pos' = pos · (L_train / L_new)

参数解释:

  • L_train:训练时的最大序列长度(如 2048)
  • L_new:推理时的目标序列长度(如 8192)
  • pos':压缩后的位置,范围在 [0, L_train] 内

举例

  • 训练长度 2048,推理长度 8192
  • 推理时位置 4096 → 压缩为 4096×(2048/8192)=1024
  • 推理时位置 8192 → 压缩为 8192×(2048/8192)=2048

优势:简单有效,只需修改位置索引;所有位置都在训练范围内,模型“见过”。

劣势:改变了相对位置的含义(相邻 Token 的距离变小了);需要少量微调来适应。

方法2:NTK-Aware 插值

核心思想:不是简单压缩位置,而是调整旋转频率的基数(将 10000 改为更大的值)

原始频率:θ_i = 10000^{-2i/d_model} NTK频率:θ_i' = (10000·scale)^{-2i/d_model}

其中 scale = L_new / L_train。

参数解释:

  • scale:长度扩展倍数
  • 基数从 10000 增大到 10000×scale
  • 旋转频率整体降低,以适应更长的序列

举例:训练长度 2048,推理长度 8192,scale=4;基数从 10000 变为 40000;旋转速度降低 4 倍,适配 4 倍长的序列。

优势:保持了相对位置的语义;无需微调,零样本外推效果好。

劣势:理论分析较复杂;对不同频率分量的影响不均匀。

方法3:YaRN(Yet another RoPE extensioN)

核心思想:对不同频率分量采用不同的插值策略

  • 低频分量(θ小):捕捉长距离依赖,使用 NTK 插值
  • 高频分量(θ大):捕捉短距离依赖,保持不变或轻微插值
  • 中频分量:渐进式插值

这种方法在 LLaMA-2 等模型中取得了很好的效果,可以将上下文长度扩展到 32k 甚至更长。

长度扩展对比

方法是否需要微调外推效果计算开销
位置插值(PI)需要少量微调无额外开销
NTK-Aware零样本较好无额外开销
YaRN零样本或少量微调很好无额外开销

小结

  1. 位置编码的必要性:注意力机制天生无法感知位置,必须显式地注入位置信息

  2. 传统位置编码

    • Sinusoidal 编码:使用 sin/cos 函数,具有确定性和可外推性,但效果一般
    • 可学习编码:灵活,但无法外推
  3. RoPE(旋转位置编码)

    • 通过旋转矩阵将位置信息融入 Q、K
    • 注意力分数自动包含相对位置信息
    • 外推性好、无额外参数、长距离自然衰减
    • 已成为现代大模型的主流选择
  4. 长度扩展技术

    • 通过位置插值、频率调整等方法,让模型适应超长序列
    • 核心在于平衡“训练时的位置模式”与“推理时的长度需求”

位置编码看似简单,却对大模型的性能至关重要。RoPE 的成功表明,优秀的位置编码应能捕捉相对位置关系,而非绝对位置,如此才能具备良好的泛化能力。

来源:https://juejin.cn/post/7610421035332452394
上一篇深度学习从零理解Transformer模型原理与架构详解 下一篇SVD奇异值分解的三步:双对角化、Givens收敛与排序
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
RAG四标融合企业知识资产体系四库协同GEO优化实践
AI教程 · 2026-07-01

RAG四标融合企业知识资产体系四库协同GEO优化实践

生成式AI正在彻底改写信息检索的底层逻辑。传统SEO依赖关键词堆砌和外链建设的策略,在大模型的内容采信规则下已经基本失效。取而代之的,是生成式引擎优化(GEO)。它不再关注外链数量,而是重点衡量你的知识是否结构化、证据链是否坚实、信源是否可靠——这些维度才是RAG(检索增强生成)架构真正看重的核心指

一个普通上班人分享WorkBuddy使用心得与真实体验
AI教程 · 2026-07-01

一个普通上班人分享WorkBuddy使用心得与真实体验

前言 最近我开始使用WorkBuddy——这是腾讯推出的一款AI办公工作台。差不多用了一周时间,趁印象还新鲜,把真实的使用感受记录下来,给还在犹豫的朋友做个参考。不吹不黑,只说实际体验。 初印象:不只是聊天机器人 之前用过不少AI工具,大多数就是个对话框,你问它答,答完就结束了。WorkBuddy不

AI幻觉变真功能实战教程:App Inventor 2视频录制拓展一周开发实录
AI教程 · 2026-07-01

AI幻觉变真功能实战教程:App Inventor 2视频录制拓展一周开发实录

先讲一个颇具戏剧性的开端。 这件事的开端颇显荒诞——有用户前来咨询,称AI Pro版的介绍中提到我们有一款“视频录制拓展”。团队全体成员都感到困惑,翻遍产品列表,发现根本不存在该组件。AI那种“一本正经胡说八道”的能力,这次确实让我们陷入尴尬。 按常理,此事到此便可结束——一句“抱歉,暂时没有这个拓

别再混淆OLAP和SQL-on-Hadoop两者查询本质不同
AI教程 · 2026-07-01

别再混淆OLAP和SQL-on-Hadoop两者查询本质不同

OLAP和SQL-on-Hadoop虽都使用SQL查询数据,但本质不同。SQL-on-Hadoop负责海量数据批量计算与ETL,查询速度秒级至分钟级;OLAP通过预聚合实现毫秒级多维分析,适合BI报表。两者在数据平台分工协作,前者是后厨加工,后者是前台快速服务。

GEO优化深度解析:AI偏好FAQ还是长文内容?
AI教程 · 2026-07-01

GEO优化深度解析:AI偏好FAQ还是长文内容?

在GEO优化中,AI对内容形式无统一偏好:FAQ在简单查询中引用率41%,长文在复杂查询中达58%。内容应基于用户意图选择形式,FAQ适配简单事实类问题,长文建立主题权威,两者互补而非替代。