当前位置: 首页 > backend >正文

RoPE(旋转位置编码,参考:DeepSeek-V2)

RoPE(旋转位置编码)

  • 1、RoPE(旋转位置编码)原理
      • 原理
      • 举例说明
  • 2、RoPEvs 传统Transformer位置编码
        • **1. 传统Transformer位置编码**
        • **2. RoPE(Rotary Position Embedding)原理**
        • **3. 核心区别**
        • **4. 举例说明**
        • **5. 为何RoPE更高效?**
  • 3、区别
      • RoPE原理与原始Transformer位置编码的对比解析
        • 一、原始Transformer位置编码(以正弦/余弦编码为例)
        • 二、RoPE(旋转位置编码)原理
        • 三、核心差异对比
        • 四、实例对比:句子顺序变化的影响
        • 五、总结
  • 4、详细列子
      • RoPE与原始Transformer位置编码的核心差异对比(以“我爱你”和“你爱我”为例)
        • 一、原始Transformer位置编码(以正弦/余弦编码为例)
        • 二、RoPE(旋转位置编码)
        • 三、核心差异对比表
        • 四、数学层面的关键区别
        • 五、总结
  • 5、DeepSeek-V2解耦RoPE策略
      • 2.5.2. 解耦旋转位置嵌入(Dcoupled RoPE )
      • 2.5.3.MLA完整计算过程

本文参考自: 论文DeepSeek-V2

在 DeepSeek 67B (DeepSeek-AI, 2024) 之后,我们打算对 DeepSeek-V2 使用旋转位置嵌入 (RoPE) (Su et al., 2024)。但是,RoPE 与低秩 KV 压缩不兼容。具体来说,RoPE 对键和查询都是位置敏感的。如果我们将 RoPE 应用于键 k r C k_{r}^{C} krC,则公式 10 中的 W U K W^{U K} WUK 将与位置敏感的 RoPE 矩阵耦合。这样, W U K W^{U K} WUK 在推理过程中就不能再被 w Q w^{Q} wQ 吸收,因为与当前生成的令牌相关的 RoPE 矩阵将位于 w Q w^{Q} wQ W U K WUK WUK 之间,并且矩阵乘法不遵循交换定律。因此,我们必须在推理过程中重新计算所有前缀 token 的 key,这将严重阻碍推理效率。

RoPE与低秩KV压缩的冲突源于矩阵乘法的非交换性,导致推理时需重新计算所有前缀token的键。DeepSeek-V2通过(解耦RoPE策略)解耦位置敏感与低秩部分,既保留了RoPE的位置编码能力,又实现了KV缓存的极致压缩。

1、RoPE(旋转位置编码)原理

Rotary Position Embedding(RoPE)是一种用于在Transformer模型中引入位置信息的技术,它通过旋转操作来编码位置信息,使得模型能够更好地处理序列数据中的位置关系。以下是RoPE的详细原理及举例说明:

原理

  1. 位置编码的表示
    RoPE使用三角函数来表示位置编码。对于一个给定的位置 t t t 和维度 d d d,RoPE定义了一个角度 θ t , d \theta_{t,d} θt,d,其计算公式为:
    θ t , d = 1000 0 − 2 i / d \theta_{t,d} = 10000^{-2i/d} θt,d=100002i/d
    其中, i i i 是维度索引, d d d 是向量的维度。

  2. 旋转操作
    对于一个向量 x = [ x 1 , x 2 , … , x d ] x = [x_1, x_2, \ldots, x_d] x=[x1,x2,,xd],RoPE通过旋转矩阵 R ( θ t , d ) R(\theta_{t,d}) R(θt,d) 对其进行旋转操作,旋转矩阵的形式为:
    R ( θ t , d ) = [ cos ⁡ ( θ t , d ) − sin ⁡ ( θ t , d ) sin ⁡ ( θ t , d ) cos ⁡ ( θ t , d ) ] R(\theta_{t,d}) = \begin{bmatrix} \cos(\theta_{t,d}) & -\sin(\theta_{t,d}) \\ \sin(\theta_{t,d}) & \cos(\theta_{t,d}) \end{bmatrix} R(θt,d)=[cos(θt,d)sin(θt,d)sin(θt,d)cos(θt,d)]
    具体来说,RoPE将向量 x x x 的偶数维度和奇数维度分别进行旋转,得到旋转后的向量 x ′ x' x
    x ′ = [ x 1 cos ⁡ ( θ t , d ) − x 2 sin ⁡ ( θ t , d ) , x 1 sin ⁡ ( θ t , d ) + x 2 cos ⁡ ( θ t , d ) , … ] x' = [x_1 \cos(\theta_{t,d}) - x_2 \sin(\theta_{t,d}), x_1 \sin(\theta_{t,d}) + x_2 \cos(\theta_{t,d}), \ldots] x=[x1cos(θt,d)x2sin(θt,d),x1sin(θt,d)+x2cos(θt,d),]

  3. 位置信息的注入
    在Transformer模型中,RoPE通常应用于查询(query)和键(key)向量。通过对查询和键向量进行旋转操作,RoPE将位置信息注入到注意力计算中,使得模型能够更好地捕捉序列中不同位置之间的关系。

举例说明

假设我们有一个简单的Transformer模型,输入序列为 [ x 1 , x 2 , x 3 ] [x_1, x_2, x_3] [x1,x2,x3],维度为 d = 4 d = 4 d=4。我们将使用RoPE来为这个序列添加位置信息。

  1. 计算角度
    对于位置 t = 1 t = 1 t=1,维度 d = 4 d = 4 d=4,我们计算角度 θ 1 , 4 \theta_{1,4} θ1,4
    θ 1 , 4 = 1000 0 − 2 × 0 / 4 = 1 \theta_{1,4} = 10000^{-2 \times 0 / 4} = 1 θ1,4=100002×0/4=1

θ 1 , 4 = 1000 0 − 2 × 1 / 4 = 0.01 \theta_{1,4} = 10000^{-2 \times 1 / 4} = 0.01 θ1,4=100002×1/4=0.01

θ 1 , 4 = 1000 0 − 2 × 2 / 4 = 0.0001 \theta_{1,4} = 10000^{-2 \times 2 / 4} = 0.0001 θ1,4=100002×2/4=0.0001

θ 1 , 4 = 1000 0 − 2 × 3 / 4 = 0.000001 \theta_{1,4} = 10000^{-2 \times 3 / 4} = 0.000001 θ1,4=100002×3/4=0.000001
2. 构建旋转矩阵
根据角度 θ 1 , 4 \theta_{1,4} θ1,4,我们构建旋转矩阵 R ( θ 1 , 4 ) R(\theta_{1,4}) R(θ1,4)
R ( θ 1 , 4 ) = [ cos ⁡ ( 1 ) − sin ⁡ ( 1 ) 0 0 sin ⁡ ( 1 ) cos ⁡ ( 1 ) 0 0 0 0 cos ⁡ ( 0.01 ) − sin ⁡ ( 0.01 ) 0 0 sin ⁡ ( 0.01 ) cos ⁡ ( 0.01 ) ] R(\theta_{1,4}) = \begin{bmatrix} \cos(1) & -\sin(1) & 0 & 0 \\ \sin(1) & \cos(1) & 0 & 0 \\ 0 & 0 & \cos(0.01) & -\sin(0.01) \\ 0 & 0 & \sin(0.01) & \cos(0.01) \end{bmatrix} R(θ1,4)= cos(1)sin(1)00sin(1)cos(1)0000cos(0.01)sin(0.01)00sin(0.01)cos(0.01)
3. 应用旋转操作
假设输入向量 x = [ 1 , 2 , 3 , 4 ] x = [1, 2, 3, 4] x=[1,2,3,4],我们将其与旋转矩阵 R ( θ 1 , 4 ) R(\theta_{1,4}) R(θ1,4) 相乘,得到旋转后的向量 x ′ x' x
x ′ = R ( θ 1 , 4 ) ⋅ x = [ cos ⁡ ( 1 ) − sin ⁡ ( 1 ) 0 0 sin ⁡ ( 1 ) cos ⁡ ( 1 ) 0 0 0 0 cos ⁡ ( 0.01 ) − sin ⁡ ( 0.01 ) 0 0 sin ⁡ ( 0.01 ) cos ⁡ ( 0.01 ) ] ⋅ [ 1 2 3 4 ] x' = R(\theta_{1,4}) \cdot x = \begin{bmatrix} \cos(1) & -\sin(1) & 0 & 0 \\ \sin(1) & \cos(1) & 0 & 0 \\ 0 & 0 & \cos(0.01) & -\sin(0.01) \\ 0 & 0 & \sin(0.01) & \cos(0.01) \end{bmatrix} \cdot \begin{bmatrix} 1 \\ 2 \\ 3 \\ 4 \end{bmatrix} x=R(θ1,4)x= cos(1)sin(1)00sin(1)cos(1)0000cos(0.01)sin(0.01)00sin(0.01)cos(0.01) 1234
计算得到:
x ′ = [ 1 cos ⁡ ( 1 ) − 2 sin ⁡ ( 1 ) , 1 sin ⁡ ( 1 ) + 2 cos ⁡ ( 1 ) , 3 cos ⁡ ( 0.01 ) − 4 sin ⁡ ( 0.01 ) , 3 sin ⁡ ( 0.01 ) + 4 cos ⁡ ( 0.01 ) ] x' = [1 \cos(1) - 2 \sin(1), 1 \sin(1) + 2 \cos(1), 3 \cos(0.01) - 4 \sin(0.01), 3 \sin(0.01) + 4 \cos(0.01)] x=[1cos(1)2sin(1),1sin(1)+2cos(1),3cos(0.01)4sin(0.01),3sin(0.01)+4cos(0.01)]
通过上述步骤,我们将位置信息注入到了输入向量中。在Transformer模型的注意力计算中,使用旋转后的向量 x ′ x' x 作为查询和键向量,模型能够更好地捕捉序列中不同位置之间的关系。

需要注意的是,在实际应用中,RoPE通常是在每个注意力头中独立应用的,并且可能会对查询和键向量进行不同的旋转操作。此外,RoPE还可以与其他位置编码方法(如正弦位置编码)结合使用,以进一步提高模型的性能。

2、RoPEvs 传统Transformer位置编码

RoPE(旋转位置编码)原理 vs 传统Transformer位置编码


1. 传统Transformer位置编码

传统Transformer使用绝对位置编码,通过预定义的正弦/余弦函数为每个位置生成固定向量,并与词向量相加。公式如下:
P E ( p o s , 2 i ) = sin ⁡ ( p o s 1000 0 2 i / d ) , P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s 1000 0 2 i / d ) PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right), \quad PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right) PE(pos,2i)=sin(100002i/dpos),PE(pos,2i+1)=cos(100002i/dpos)
特点

  • 绝对性:每个位置有唯一编码,直接标记序列中的绝对位置。
  • 加性融合:位置向量与词向量直接相加,可能干扰语义信息。
  • 长序列局限:随着位置增大,高频维度(如 i i i较大时)的编码值趋近于零,导致位置信息衰减。

2. RoPE(Rotary Position Embedding)原理

RoPE通过旋转矩阵动态调整查询(Query)和键(Key)向量,将位置信息编码为向量的相位旋转,使注意力分数自然包含相对位置信息。

数学形式
对位置 m m m的查询向量 q m q_m qm和位置 n n n的键向量 k n k_n kn,RoPE通过旋转操作生成:
q m ′ = q m ⋅ e i m θ , k n ′ = k n ⋅ e i n θ q_m' = q_m \cdot e^{i m \theta}, \quad k_n' = k_n \cdot e^{i n \theta} qm=qmeimθ,kn=kneinθ
其中 θ \theta θ是与位置相关的旋转角, i i i为虚数单位。注意力得分计算为:
Attention ( q m ′ , k n ′ ) = Re ( q m ⋅ k n ∗ ⋅ e i ( m − n ) θ ) \text{Attention}(q_m', k_n') = \text{Re}(q_m \cdot k_n^* \cdot e^{i (m-n)\theta}) Attention(qm,kn)=Re(qmknei(mn)θ)
关键点

  • 相对位置编码:注意力得分仅依赖相对位置差 m − n m-n mn,而非绝对位置。
  • 旋转操作:通过复数域旋转,保持向量模长不变,避免数值不稳定。
  • 无需显式参数:位置信息通过旋转直接融入注意力计算,无需额外位置向量。

3. 核心区别
特性传统位置编码RoPE
编码方式固定向量相加(绝对位置)动态旋转(相对位置)
信息融合词向量与位置向量线性叠加通过复数乘法隐式融合
长序列适应性高频维度信息衰减旋转保持信息完整性,适合长序列
计算复杂度 O ( L ⋅ d ) O(L \cdot d) O(Ld)(存储位置向量)无需存储,计算时动态生成旋转操作
相对位置捕捉需额外设计(如相对位置编码)天然支持,直接通过相位差实现

4. 举例说明

假设两个词向量 q q q(位置 m = 2 m=2 m=2)和 k k k(位置 n = 5 n=5 n=5),维度 d = 4 d=4 d=4,旋转角 θ = 0.1 \theta=0.1 θ=0.1

传统方法

  • 生成位置编码 P E 2 PE_2 PE2 P E 5 PE_5 PE5,与词向量相加:
    q ′ = q + P E 2 , k ′ = k + P E 5 q' = q + PE_2, \quad k' = k + PE_5 q=q+PE2,k=k+PE5
  • 计算注意力得分: q ′ ⋅ k ′ T q' \cdot k'^T qkT,包含绝对位置信息,但需额外机制捕捉相对位置。

RoPE

  • q q q k k k进行旋转(以复数表示):
    q ′ = q ⋅ e i ⋅ 2 ⋅ 0.1 , k ′ = k ⋅ e i ⋅ 5 ⋅ 0.1 q' = q \cdot e^{i \cdot 2 \cdot 0.1}, \quad k' = k \cdot e^{i \cdot 5 \cdot 0.1} q=qei20.1,k=kei50.1
  • 计算注意力得分:
    Re ( q ⋅ k ∗ ⋅ e i ⋅ ( 2 − 5 ) ⋅ 0.1 ) = Re ( q ⋅ k ∗ ⋅ e − i ⋅ 0.3 ) \text{Re}(q \cdot k^* \cdot e^{i \cdot (2-5) \cdot 0.1}) = \text{Re}(q \cdot k^* \cdot e^{-i \cdot 0.3}) Re(qkei(25)0.1)=Re(qkei0.3)
    得分直接反映相对位置差 − 3 -3 3,无需显式编码。

5. 为何RoPE更高效?
  • 隐式相对位置:直接通过旋转相位差捕捉位置关系,避免复杂相对位置计算。
  • 兼容性:天然适配线性注意力(如FlashAttention),提升计算效率。
  • 长上下文优化:旋转操作不随序列长度增加而信息衰减,适合处理128K+长文本。

总结:RoPE通过旋转机制将位置信息动态融入注意力计算,相比传统加性编码,更高效地捕捉相对位置关系,尤其适合长序列和大模型场景。DeepSeek-V2通过解耦RoPE与低秩KV压缩的结合,进一步优化了推理效率。

3、区别

RoPE原理与原始Transformer位置编码的对比解析

一、原始Transformer位置编码(以正弦/余弦编码为例)

原理
原始Transformer(Vaswani et al., 2017)采用绝对位置编码,通过固定的正弦和余弦函数为每个位置生成唯一的编码向量,公式为:
P E ( p o s , 2 i ) = sin ⁡ ( p o s 1000 0 2 i / d ) , P E ( p o s , 2 i + 1 ) = cos ⁡ ( p o s 1000 0 2 i / d ) PE_{(pos, 2i)} = \sin\left(\frac{pos}{10000^{2i/d}}\right), \quad PE_{(pos, 2i+1)} = \cos\left(\frac{pos}{10000^{2i/d}}\right) PE(pos,2i)=sin(100002i/dpos),PE(pos,2i+1)=cos(100002i/dpos)
其中, p o s pos pos 是位置索引, i i i 是维度索引, d d d 是嵌入维度。这些位置向量直接加法嵌入到词向量中,使模型感知绝对位置。

核心特点

  1. 绝对位置信息:每个位置的编码是唯一的,但仅反映绝对位置,无法直接捕捉相对位置关系(如“距离3”和“距离5”的差异)。
  2. 固定编码:位置向量在预训练时固定,不参与模型学习,依赖三角函数的周期性。
  3. 加法融合:位置信息通过加法与词向量结合,独立于注意力计算过程。

举例
对于句子“我爱你”(位置1, 2, 3),每个词的嵌入是词向量 + 对应位置的正弦/余弦向量。若句子顺序变为“你爱我”,词向量顺序改变,但每个位置的编码仍为位置1、2、3,模型需依赖词向量本身区分顺序,缺乏对“你”和“我”相对距离变化的显式建模。

二、RoPE(旋转位置编码)原理

核心思想
RoPE(Su et al., 2021)通过旋转矩阵对查询(Q)和键(K)的向量进行位置相关的旋转,将位置信息嵌入到注意力计算中,公式为:
q m = W Q x m ⋅ R ( θ m ) , k n = W K x n ⋅ R ( θ n ) q_m = W^Q x_m \cdot \mathbf{R}(\theta_m), \quad k_n = W^K x_n \cdot \mathbf{R}(\theta_n) qm=WQxmR(θm),kn=WKxnR(θn)
其中, R ( θ ) = [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] \mathbf{R}(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} R(θ)=[cosθsinθsinθcosθ] 是旋转矩阵, θ p o s = pos ⋅ 1000 0 − 2 i / d \theta_{pos} = \text{pos} \cdot 10000^{-2i/d} θpos=pos100002i/d 是位置相关的角度。

关键机制

  1. 相对位置编码:旋转操作使注意力得分自然反映查询和键的相对位置差。例如,位置 m m m n n n 的点积 q m ⊤ k n q_m^\top k_n qmkn 等价于将 k n k_n kn 旋转 θ m − n \theta_{m-n} θmn 后与 q m q_m qm 相乘,隐式编码相对距离 ∣ m − n ∣ |m-n| mn
  2. 分维度旋转:将高维向量分解为多个2D子空间(如维度0-1、2-3等),每个子空间独立应用旋转,避免维度间干扰。
  3. 动态融合:位置信息在注意力计算时动态注入,而非提前加法融合,与自注意力机制深度结合。

举例
对于“我爱你”中的“我”(位置1)和“你”(位置3),RoPE计算两者的注意力时,会根据相对距离2调整旋转角度,使点积结果包含“距离2”的信息。若句子变为“你爱我”,“你”(位置1)和“我”(位置3)的相对距离仍为2,旋转角度相同,模型可显式捕捉到相同的相对位置关系,而原始编码仅能区分绝对位置1和3,无法利用相对距离的不变性。

三、核心差异对比
维度原始Transformer位置编码RoPE
编码方式加法嵌入固定位置向量(绝对位置)旋转矩阵动态调整Q/K向量(相对位置)
位置信息类型绝对位置(每个位置唯一编码)相对位置(通过角度差隐式编码距离)
与注意力结合独立于注意力,加法融合到输入层嵌入注意力计算,旋转Q/K向量影响点积结果
长序列处理周期性限制(序列过长时编码重复)无显式周期,理论支持任意长度外推
参数学习固定参数(非学习)无额外参数(仅依赖预定义频率)

数学层面对比

  • 原始编码: Attention ( Q + P E , K + P E , V ) \text{Attention}(Q+PE, K+PE, V) Attention(Q+PE,K+PE,V),位置信息通过加法独立于Q/K的交互。
  • RoPE: Attention ( Q ⋅ R ( θ m ) , K ⋅ R ( θ n ) , V ) \text{Attention}(Q \cdot \mathbf{R}(\theta_m), K \cdot \mathbf{R}(\theta_n), V) Attention(QR(θm),KR(θn),V),位置信息通过旋转矩阵融入Q/K的点积计算,满足 R ( θ m ) R ( θ n ) ⊤ = R ( θ m − θ n ) \mathbf{R}(\theta_m) \mathbf{R}(\theta_n)^\top = \mathbf{R}(\theta_m - \theta_n) R(θm)R(θn)=R(θmθn),天然编码相对位置差。
四、实例对比:句子顺序变化的影响

假设输入序列为 x = [ x 1 , x 2 ] x = [x_1, x_2] x=[x1,x2](“AB”)和 x ′ = [ x 2 , x 1 ] x' = [x_2, x_1] x=[x2,x1](“BA”):

  1. 原始编码

    • 位置编码为 P E 1 , P E 2 PE_1, PE_2 PE1,PE2,输入为 x 1 + P E 1 , x 2 + P E 2 x_1+PE_1, x_2+PE_2 x1+PE1,x2+PE2 x 2 + P E 1 , x 1 + P E 2 x_2+PE_1, x_1+PE_2 x2+PE1,x1+PE2
    • 注意力计算时,模型依赖词向量 x 1 , x 2 x_1, x_2 x1,x2 的差异区分顺序,若 x 1 = x 2 x_1 = x_2 x1=x2(同词不同位置),输出相同,无法区分顺序。
  2. RoPE

    • Q/K向量为 x 1 ⋅ R ( θ 1 ) , x 2 ⋅ R ( θ 2 ) x_1 \cdot \mathbf{R}(\theta_1), x_2 \cdot \mathbf{R}(\theta_2) x1R(θ1),x2R(θ2) x 2 ⋅ R ( θ 1 ) , x 1 ⋅ R ( θ 2 ) x_2 \cdot \mathbf{R}(\theta_1), x_1 \cdot \mathbf{R}(\theta_2) x2R(θ1),x1R(θ2)
    • 计算“AB”中A(位置1)对B(位置2)的注意力: q 1 ⊤ k 2 = ( x 1 R ( θ 1 ) ) ⊤ ( x 2 R ( θ 2 ) ) = x 1 ⊤ x 2 cos ⁡ ( θ 2 − θ 1 ) q_1^\top k_2 = (x_1 \mathbf{R}(\theta_1))^\top (x_2 \mathbf{R}(\theta_2)) = x_1^\top x_2 \cos(\theta_2 - \theta_1) q1k2=(x1R(θ1))(x2R(θ2))=x1x2cos(θ2θ1)
    • 计算“BA”中B(位置1)对A(位置2)的注意力: q 1 ⊤ k 2 = ( x 2 R ( θ 1 ) ) ⊤ ( x 1 R ( θ 2 ) ) = x 2 ⊤ x 1 cos ⁡ ( θ 2 − θ 1 ) q_1^\top k_2 = (x_2 \mathbf{R}(\theta_1))^\top (x_1 \mathbf{R}(\theta_2)) = x_2^\top x_1 \cos(\theta_2 - \theta_1) q1k2=(x2R(θ1))(x1R(θ2))=x2x1cos(θ2θ1),若 x 1 = x 2 x_1 = x_2 x1=x2,点积依赖相对角度 θ 2 − θ 1 = θ − 1 = − θ 1 \theta_2 - \theta_1 = \theta_{-1} = -\theta_1 θ2θ1=θ1=θ1,仍能区分顺序(因余弦为偶函数,实际通过正弦分量区分方向)。
五、总结

RoPE通过旋转操作动态编码相对位置,克服了原始编码的绝对位置局限,与自注意力机制深度融合,在长序列处理和相对位置建模上具有显著优势。其核心创新在于将位置信息嵌入到Q/K的交互过程中,而非独立加法融合,使模型能够更自然地捕捉序列中的距离和顺序关系,这也是其在现代大模型(如LLaMA、DeepSeek-V2)中广泛应用的关键原因。

4、详细列子

RoPE与原始Transformer位置编码的核心差异对比(以“我爱你”和“你爱我”为例)

一、原始Transformer位置编码(以正弦/余弦编码为例)

原理:为每个位置生成唯一的固定向量(绝对位置编码),通过加法嵌入到词向量中。
示例:句子“我爱你”(位置1, 2, 3)和“你爱我”(位置1, 2, 3)

  1. 词向量与位置编码

    • 词向量:假设“我”= x 1 \mathbf{x}_1 x1,“爱”= x 2 \mathbf{x}_2 x2,“你”= x 3 \mathbf{x}_3 x3
    • 位置向量:位置1的编码为 P E 1 \mathbf{PE}_1 PE1,位置2为 P E 2 \mathbf{PE}_2 PE2,位置3为 P E 3 \mathbf{PE}_3 PE3
    • 输入向量:
      • “我爱你”: x 1 + P E 1 , x 2 + P E 2 , x 3 + P E 3 \mathbf{x}_1+\mathbf{PE}_1, \mathbf{x}_2+\mathbf{PE}_2, \mathbf{x}_3+\mathbf{PE}_3 x1+PE1,x2+PE2,x3+PE3
      • “你爱我”: x 3 + P E 1 , x 2 + P E 2 , x 1 + P E 3 \mathbf{x}_3+\mathbf{PE}_1, \mathbf{x}_2+\mathbf{PE}_2, \mathbf{x}_1+\mathbf{PE}_3 x3+PE1,x2+PE2,x1+PE3
  2. 注意力计算

    • 计算“我”(位置1)对“你”(位置3)的注意力时,依赖词向量 x 1 \mathbf{x}_1 x1 x 3 \mathbf{x}_3 x3 的差异,以及位置向量 P E 1 \mathbf{PE}_1 PE1 P E 3 \mathbf{PE}_3 PE3 的绝对差。
    • x 1 = x 3 \mathbf{x}_1 = \mathbf{x}_3 x1=x3(同词不同位置),模型仅通过 P E 1 \mathbf{PE}_1 PE1 P E 3 \mathbf{PE}_3 PE3 区分位置,但无法直接捕捉“距离2”的相对关系。
  3. 关键缺陷

    • 绝对位置依赖:位置信息是静态加法嵌入,无法显式建模“你”和“我”的相对距离(如“距离2”在两个句子中相同,但模型视为不同绝对位置)。
    • 长序列局限性:位置向量的周期性导致长序列中位置编码重复,无法区分超过周期长度的相对距离(如位置100和200可能因周期重复被视为相同)。
二、RoPE(旋转位置编码)

原理:通过旋转矩阵对查询(Q)和键(K)向量进行位置相关的旋转,动态编码相对位置信息。
示例:同上句子“我爱你”和“你爱我”,假设词向量维度 d = 4 d=4 d=4,分为2个2D子空间(维度0-1和2-3)。

  1. 旋转角度计算

    • 位置 t t t 的角度参数: θ t = pos ⋅ 1000 0 − 2 i / d \theta_t = \text{pos} \cdot 10000^{-2i/d} θt=pos100002i/d i i i 为子空间索引,此处 i = 0 , 1 i=0,1 i=0,1
    • 位置1的角度: θ 1 ( 1 ) = 1 ⋅ 1000 0 0 / 4 = 1 \theta_1^{(1)} = 1 \cdot 10000^{0/4} = 1 θ1(1)=1100000/4=1 θ 1 ( 2 ) = 1 ⋅ 1000 0 − 2 / 4 = 0.01 \theta_1^{(2)} = 1 \cdot 10000^{-2/4} = 0.01 θ1(2)=1100002/4=0.01
    • 位置3的角度: θ 3 ( 1 ) = 3 ⋅ 1 \theta_3^{(1)} = 3 \cdot 1 θ3(1)=31 θ 3 ( 2 ) = 3 ⋅ 0.01 \theta_3^{(2)} = 3 \cdot 0.01 θ3(2)=30.01
  2. 旋转矩阵应用

    • 对“我”(位置1)的查询向量 q 1 = W Q x 1 \mathbf{q}_1 = W^Q \mathbf{x}_1 q1=WQx1,拆分为2D子空间:
      q 1 = [ q 1 , 1 , q 1 , 2 , q 1 , 3 , q 1 , 4 ] → ( [ q 1 , 1 q 1 , 2 ] , [ q 1 , 3 q 1 , 4 ] ) \mathbf{q}_1 = [q_{1,1}, q_{1,2}, q_{1,3}, q_{1,4}] \rightarrow \left( \begin{bmatrix} q_{1,1} \\ q_{1,2} \end{bmatrix}, \begin{bmatrix} q_{1,3} \\ q_{1,4} \end{bmatrix} \right) q1=[q1,1,q1,2,q1,3,q1,4]([q1,1q1,2],[q1,3q1,4])
  • 应用旋转矩阵 R ( θ 1 ) \mathbf{R}(\theta_1) R(θ1)
    [ q 1 , 1 ′ q 1 , 2 ′ ] = [ cos ⁡ θ 1 ( 1 ) − sin ⁡ θ 1 ( 1 ) sin ⁡ θ 1 ( 1 ) cos ⁡ θ 1 ( 1 ) ] [ q 1 , 1 q 1 , 2 ] \begin{bmatrix} q'_{1,1} \\ q'_{1,2} \end{bmatrix} = \begin{bmatrix} \cos\theta_1^{(1)} & -\sin\theta_1^{(1)} \\ \sin\theta_1^{(1)} & \cos\theta_1^{(1)} \end{bmatrix} \begin{bmatrix} q_{1,1} \\ q_{1,2} \end{bmatrix} [q1,1q1,2]=[cosθ1(1)sinθ1(1)sinθ1(1)cosθ1(1)][q1,1q1,2]
    同理处理键向量 k 3 \mathbf{k}_3 k3(位置3)。
  1. 注意力计算

    • 旋转后的点积: q 1 ′ ⊤ k 3 ′ = ( q 1 ⋅ R ( θ 1 ) ) ⊤ ( k 3 ⋅ R ( θ 3 ) ) = q 1 ⊤ k 3 ⋅ cos ⁡ ( θ 3 − θ 1 ) \mathbf{q}_1'^\top \mathbf{k}_3' = (\mathbf{q}_1 \cdot \mathbf{R}(\theta_1))^\top (\mathbf{k}_3 \cdot \mathbf{R}(\theta_3)) = \mathbf{q}_1^\top \mathbf{k}_3 \cdot \cos(\theta_3 - \theta_1) q1′⊤k3=(q1R(θ1))(k3R(θ3))=q1k3cos(θ3θ1)
    • 相对位置差 3 − 1 = 2 3-1=2 31=2 被编码到余弦项 cos ⁡ ( θ 3 − θ 1 ) = cos ⁡ ( 2 ⋅ 1 ) \cos(\theta_3 - \theta_1) = \cos(2 \cdot 1) cos(θ3θ1)=cos(21),显式体现“距离2”的关系。
  2. 关键优势

    • 相对位置建模:无论“我”在位置1还是3,只要相对距离为2,旋转角度差固定,点积结果反映相同的相对位置关系(如“我爱你”和“你爱我”中“我”和“你”的距离均为2,模型可捕捉到相同的相对距离)。
    • 长序列适应性:角度随位置线性增长,无周期性限制,理论上支持任意长度序列的相对位置编码(如位置100和102的距离2与位置1和3的距离2编码方式一致)。
三、核心差异对比表
维度原始Transformer位置编码RoPE
编码方式加法嵌入固定位置向量(绝对位置)旋转矩阵动态调整Q/K向量(相对位置)
位置信息类型绝对位置(每个位置唯一编码)相对位置(通过角度差隐式编码距离)
与注意力结合独立于注意力,加法融合到输入层嵌入注意力计算,旋转Q/K向量影响点积结果
长序列处理周期性限制(序列过长时编码重复)无显式周期,理论支持任意长度外推
数学本质静态叠加位置偏移量动态旋转向量方向,点积反映相对角度差
示例对比“我爱你”和“你爱我”被视为不同绝对位置组合两者中“我”和“你”的相对距离均为2,编码一致
四、数学层面的关键区别
  1. 原始编码的加法模式
    Input = TokenEmbed + PosEmbed \text{Input} = \text{TokenEmbed} + \text{PosEmbed} Input=TokenEmbed+PosEmbed
    位置信息与词向量独立,注意力计算为 Attention ( Q + P E , K + P E , V ) \text{Attention}(Q+PE, K+PE, V) Attention(Q+PE,K+PE,V),无法直接分离相对位置贡献。

  2. RoPE的旋转模式
    Q ′ = Q ⋅ R ( θ m ) , K ′ = K ⋅ R ( θ n ) Q' = Q \cdot \mathbf{R}(\theta_m), \quad K' = K \cdot \mathbf{R}(\theta_n) Q=QR(θm),K=KR(θn)
    注意力计算为 Q ′ ⊤ K ′ = Q ⊤ K ⋅ cos ⁡ ( θ m − θ n ) Q'^\top K' = Q^\top K \cdot \cos(\theta_m - \theta_n) Q′⊤K=QKcos(θmθn),天然编码相对位置差 ∣ m − n ∣ |m-n| mn

五、总结

RoPE通过动态旋转Q/K向量,将相对位置信息嵌入注意力计算的点积中,解决了原始编码依赖绝对位置和长序列周期性的问题。在“我爱你”和“你爱我”的例子中,RoPE能显式捕捉“我”和“你”的相对距离2,而原始编码仅能区分绝对位置1和3,无法利用相对距离的不变性。这种差异使得RoPE在长序列建模和相对位置敏感任务(如语法分析、长文本生成)中表现更优,成为现代大模型(如LLaMA、DeepSeek-V2)的主流选择。

5、DeepSeek-V2解耦RoPE策略

2.5.2. 解耦旋转位置嵌入(Dcoupled RoPE )

一、核心问题:传统RoPE与低秩KV压缩的冲突

DeepSeek-V2在设计MLA时遇到一个关键矛盾:

  1. RoPE的位置敏感性:RoPE通过旋转矩阵对键(K)和查询(Q)添加位置信息,要求键和查询在计算时携带与位置相关的参数(如不同位置的旋转矩阵 R t \mathbf{R}_t Rt)。
  2. 矩阵吸收失效:在MLA的低秩压缩中,键的生成需要将上投影矩阵 W U K W^{UK} WUK 融入查询投影矩阵 W Q W^Q WQ(见2.1.2节),以跳过显式计算键值对。但RoPE的旋转矩阵会插入在 W Q W^Q WQ W U K W^{UK} WUK 之间,导致:
    传统流程: k t C = W U K ⋅ R t ⋅ W D K V h t \text{传统流程:} \quad k_t^C = W^{UK} \cdot \mathbf{R}_t \cdot W^{DKV} h_t 传统流程:ktC=WUKRtWDKVht
    由于矩阵乘法不满足交换律, W U K W^{UK} WUK 无法与 W Q W^Q WQ 合并,必须为每个位置 t t t 单独计算 k t C k_t^C ktC,导致推理时需重新计算所有前缀token的键,计算量随序列长度呈平方级增长(例如128K序列时,每次生成新token需计算128K次键,效率极低)。

在DeepSeek-V2模型中,将旋转位置编码(RoPE)与低秩KV压缩技术结合时,由于矩阵乘法不满足交换律,导致推理过程中必须重新计算所有前缀token的键(Key),从而显著降低效率。以下是该问题的技术细节及实例分析:


核心矛盾:RoPE与低秩KV压缩的互斥性

  1. 低秩KV压缩的原理
    • 压缩过程:输入向量 h t h_t ht通过低秩矩阵 W D K V ∈ R d c × d W^{DKV} \in \mathbb{R}^{d_c \times d} WDKVRdc×d d c d_c dc为压缩维度, d d d为原始维度)压缩为潜在向量 c t K V c_t^{KV} ctKV
    c t K V = W D K V ⋅ h t c_t^{KV} = W^{DKV} \cdot h_t ctKV=WDKVht
    • 还原键值:通过上投影矩阵 W U K ∈ R d × d c W^{UK} \in \mathbb{R}^{d \times d_c} WUKRd×dc W U V W^{UV} WUV还原完整键值:
    k t C = W U K ⋅ c t K V , v t C = W U V ⋅ c t K V k_t^C = W^{UK} \cdot c_t^{KV}, \quad v_t^C = W^{UV} \cdot c_t^{KV} ktC=WUKctKV,vtC=WUVctKV
    理想情况下,推理时可通过矩阵结合律将两步合并,例如将 W U K ⋅ W D K V W^{UK} \cdot W^{DKV} WUKWDKV融入 W Q W^Q WQ,从而避免显式计算 k t C k_t^C ktC
    W Q ′ = W Q ⋅ ( W U K ⋅ W D K V ) ∈ R 512 × 512 W^{Q'} = W^Q \cdot (W^{UK} \cdot W^{DKV}) \in \mathbb{R}^{512 \times 512} WQ=WQ(WUKWDKV)R512×512

  2. RoPE的位置敏感性
    • RoPE的作用:RoPE通过旋转矩阵 R t R_t Rt对查询(Query)和键(Key)引入位置相关的相位偏移:
    q t = R t ⋅ ( W Q ⋅ h t ) , k t = R t ⋅ ( W U K ⋅ c t K V ) q_t = R_t \cdot (W^Q \cdot h_t), \quad k_t = R_t \cdot (W^{UK} \cdot c_t^{KV}) qt=Rt(WQht),kt=Rt(WUKctKV)
    • 冲突点:RoPE矩阵 R t R_t Rt与低秩矩阵 W U K W^{UK} WUK的位置耦合,导致矩阵乘法顺序不可交换。


数学推导与冲突示例

  1. 原始计算流程
    • 键的计算:
    k t C = R t ⋅ ( W U K ⋅ c t K V ) = R t ⋅ W U K ⋅ W D K V ⋅ h t k_t^C = R_t \cdot (W^{UK} \cdot c_t^{KV}) = R_t \cdot W^{UK} \cdot W^{DKV} \cdot h_t ktC=Rt(WUKctKV)=RtWUKWDKVht
    • 理想合并:若矩阵乘法可交换,可将 W U K ⋅ W D K V W^{UK} \cdot W^{DKV} WUKWDKV提前合并到 W Q W^Q WQ中:
    W Q ′ = W Q ⋅ ( W U K ⋅ W D K V ) W^{Q'} = W^Q \cdot (W^{UK} \cdot W^{DKV}) WQ=WQ(WUKWDKV)
    此时查询计算简化为 q t ′ = R t ⋅ W Q ′ ⋅ h t q_t' = R_t \cdot W^{Q'} \cdot h_t qt=RtWQht,无需显式存储 k t C k_t^C ktC

  2. 实际冲突分析
    • 交换律失效:由于 R t R_t Rt W U K W^{UK} WUK的乘法顺序不可交换,即:
    R t ⋅ W U K ≠ W U K ⋅ R t R_t \cdot W^{UK} \neq W^{UK} \cdot R_t RtWUK=WUKRt
    导致无法将 W U K W^{UK} WUK吸收到 W Q W^Q WQ中。
    • 示例:假设 W U K ∈ R 512 × 128 W^{UK} \in \mathbb{R}^{512 \times 128} WUKR512×128 R t ∈ R 512 × 512 R_t \in \mathbb{R}^{512 \times 512} RtR512×512,则:
    R t ⋅ W U K ∈ R 512 × 128 , W U K ⋅ R t ∈ R 128 × 512 ( 维度不匹配 ) R_t \cdot W^{UK} \in \mathbb{R}^{512 \times 128}, \quad W^{UK} \cdot R_t \in \mathbb{R}^{128 \times 512} \quad (\text{维度不匹配}) RtWUKR512×128,WUKRtR128×512(维度不匹配)
    即使维度匹配(如方阵),数值结果仍不同:
    若 W U K = [ 1 2 3 4 ] , R t = [ 0 1 1 0 ] , 则 R t ⋅ W U K = [ 3 4 1 2 ] ≠ W U K ⋅ R t = [ 2 1 4 3 ] \text{若} \quad W^{UK} = \begin{bmatrix}1 & 2 \\ 3 & 4\end{bmatrix}, R_t = \begin{bmatrix}0 & 1 \\ 1 & 0\end{bmatrix}, \quad \text{则} \quad R_t \cdot W^{UK} = \begin{bmatrix}3 & 4 \\ 1 & 2\end{bmatrix} \neq W^{UK} \cdot R_t = \begin{bmatrix}2 & 1 \\ 4 & 3\end{bmatrix} WUK=[1324],Rt=[0110],RtWUK=[3142]=WUKRt=[2413]


二、解耦RoPE策略:分离位置信息的“双重表示”

为解决上述问题,DeepSeek-V2提出解耦策略:将查询和键拆分为位置无关的压缩部分(用于高效计算)和位置相关的RoPE部分(用于捕获序列顺序),两者独立处理后拼接使用。

三、关键公式与实例解析
1. 符号定义(简化维度示例)

假设:

  • 输入维度 d = 512 d = 512 d=512,压缩维度 d c = 128 d_c = 128 dc=128,查询压缩维度 d c ′ = 256 d'_c = 256 dc=256
  • 注意力头数 n h = 32 n_h = 32 nh=32,每头维度 d h = 16 d_h = 16 dh=16,解耦位置维度 d h R = 8 d_h^R = 8 dhR=8(每头位置相关子空间维度)
  • c t Q c_t^Q ctQ:查询的压缩潜向量(256维,来自2.1.2节的查询压缩)
  • h t h_t ht:输入隐藏层向量(512维)
2. 位置相关查询 q t R q_t^R qtR 的生成(公式14)

[ q t , 1 R ; q t , 2 R ; … ; q t , 32 R ] = q t R = RoPE ( W Q R c t Q ) [q_{t,1}^R; q_{t,2}^R; \dots; q_{t,32}^R] = q_t^R = \text{RoPE}\left( W^{QR} c_t^Q \right) [qt,1R;qt,2R;;qt,32R]=qtR=RoPE(WQRctQ)

  • W Q R W^{QR} WQR:投影矩阵(形状 32 × 8 × 256 32 \times 8 \times 256 32×8×256,将256维压缩查询投影到32头×8维的位置子空间)
  • 实例
    • c t Q = [ x 1 , x 2 , . . . , x 256 ] c_t^Q = [x_1, x_2, ..., x_{256}] ctQ=[x1,x2,...,x256](压缩后的查询)
    • W Q R c t Q W^{QR} c_t^Q WQRctQ 生成32个8维向量(每头一个),经RoPE添加位置信息后,得到每头的位置相关查询 q t , i R ∈ R 8 q_{t,i}^R \in \mathbb{R}^8 qt,iRR8
3. 共享位置键 k t R k_t^R ktR 的生成(公式15)

k t R = RoPE ( W K R h t ) k_t^R = \text{RoPE}\left( W^{KR} h_t \right) ktR=RoPE(WKRht)

  • W K R W^{KR} WKR:投影矩阵(形状 8 × 512 8 \times 512 8×512,将512维输入投影到8维位置空间)
  • 实例
    • h t h_t ht W K R W^{KR} WKR 投影为8维向量,再经RoPE处理,得到共享的位置键 k t R ∈ R 8 k_t^R \in \mathbb{R}^8 ktRR8(所有头共用,减少参数和计算量)。
4. 查询与键的拼接(公式16-17)

q t , i = [ q t , i C ; q t , i R ] , k t , i = [ k t , i C ; k t R ] q_{t,i} = [q_{t,i}^C; q_{t,i}^R], \quad k_{t,i} = [k_{t,i}^C; k_t^R] qt,i=[qt,iC;qt,iR],kt,i=[kt,iC;ktR]

  • 实例
    • 压缩部分 q t , i C ∈ R 16 q_{t,i}^C \in \mathbb{R}^{16} qt,iCR16(每头原始维度),位置部分 q t , i R ∈ R 8 q_{t,i}^R \in \mathbb{R}^8 qt,iRR8,拼接后查询维度为 16 + 8 = 24 16+8=24 16+8=24
    • 键的压缩部分 k t , i C ∈ R 16 k_{t,i}^C \in \mathbb{R}^{16} kt,iCR16,位置部分 k t R ∈ R 8 k_t^R \in \mathbb{R}^8 ktRR8,拼接后键维度为 16 + 8 = 24 16+8=24 16+8=24
5. 注意力计算(公式18)

o t , i = ∑ j = 1 t Softmax j ( q t , i T k j , i 24 ) v j , i C o_{t,i} = \sum_{j=1}^t \text{Softmax}_j \left( \frac{q_{t,i}^T k_{j,i}}{\sqrt{24}} \right) v_{j,i}^C ot,i=j=1tSoftmaxj(24 qt,iTkj,i)vj,iC

  • 分母 d h + d h R = 16 + 8 = 24 \sqrt{d_h + d_h^R} = \sqrt{16+8} = \sqrt{24} dh+dhR =16+8 =24 是拼接后维度的归一化因子,确保注意力分数稳定。
四、核心优势:通过“分离-拼接”实现高效与位置建模的双赢
  1. 保留矩阵吸收(高效推理)

    • 压缩部分 q t C , k t C q_t^C, k_t^C qtC,ktC 不含位置信息,其投影矩阵 W U K , W U V W^{UK}, W^{UV} WUK,WUV 仍可被吸收到 W Q , W O W^Q, W^O WQ,WO 中(如 W Q = W U Q ⋅ W D Q W^Q = W^{UQ} \cdot W^{DQ} WQ=WUQWDQ),避免重新计算前缀键。
    • 实例:若序列长度为128K,传统RoPE需缓存 2 × 32 × 16 × 128 K × l 2 \times 32 \times 16 \times 128K \times l 2×32×16×128K×l 个元素,而解耦策略仅需缓存 ( 128 + 8 ) × l × 128 K (128 + 8) \times l \times 128K (128+8)×l×128K 个元素,缓存量减少93.3%(与文档表1数据一致)。
  2. 精准位置建模

    • 位置相关部分 q t R , k t R q_t^R, k_t^R qtR,ktR 专门处理序列顺序,通过RoPE捕获长距离依赖,例如:
      • 当token位置从 t t t t + 1 t+1 t+1 q t R q_t^R qtR q t + 1 R q_{t+1}^R qt+1R 的旋转矩阵不同,确保模型区分前后顺序。
  3. 计算量控制

    • 共享键 k t R k_t^R ktR 对所有头生效,无需为每个头单独计算位置键,计算量从 O ( n h d h l ) O(n_h d_h l) O(nhdhl) 降至 O ( ( d c + d h R ) l ) O((d_c + d_h^R) l) O((dc+dhR)l),支持128K长上下文高效处理(见文档图4,DeepSeek-V2在128K时性能稳定)。
五、与传统RoPE的对比(以1头为例)
步骤传统RoPE(直接应用)解耦RoPE(MLA策略)
键生成 k t = W K h t ⋅ R t k_t = W^K h_t \cdot \mathbf{R}_t kt=WKhtRt(含位置矩阵) k t = [ k t C ; k t R ] k_t = [k_t^C; k_t^R] kt=[ktC;ktR] k t C k_t^C ktC 无位置, k t R k_t^R ktR 含RoPE)
矩阵吸收不可吸收( R t \mathbf{R}_t Rt 阻断)可吸收( k t C k_t^C ktC W U K W^{UK} WUK 融入 W Q W^Q WQ
前缀键重计算每次生成新token需重算所有历史键仅需计算一次共享 k t R k_t^R ktR k t C k_t^C ktC 可快速生成
KV缓存(1层) 2 × 16 × 1 = 32 2 \times 16 \times 1 = 32 2×16×1=32 元素 128 ( d c ) + 8 ( d h R ) = 136 128(d_c) + 8(d_h^R) = 136 128dc+8dhR=136 元素(虽略增,但远低于MHA的 2 × 16 × 32 = 1024 2 \times 16 \times 32 = 1024 2×16×32=1024 元素)
六、总结:解耦策略如何让MLA“两全其美”

通过将位置信息从压缩的键/查询中分离,解耦RoPE策略实现了三大突破:

  1. 技术兼容:在低秩KV压缩的同时,保留RoPE的位置建模能力,避免传统RoPE导致的推理瓶颈。
  2. 效率提升:通过矩阵吸收和共享位置键,将键值对的计算复杂度从 O ( n 2 ) O(n^2) O(n2) 降至 O ( n ) O(n) O(n),支持128K长上下文高效生成。
  3. 性能保障:实验表明(见文档附录D.2),解耦后的MLA在保持KV缓存大幅减少的同时,性能优于传统MHA,实现了“高效+强性能”的平衡。

这一设计是DeepSeek-V2能在长上下文场景(如128K序列)中保持高吞吐量的关键技术之一,也是其架构创新的核心亮点。

2.5.3.MLA完整计算过程

为了展示MLA的完整计算过程,我们在下面给出其完整公式:
在这里插入图片描述

其中,蓝色框选的向量在生成时需要缓存。在推理过程中,原始公式需要从 c t K V c_{t}^{K V} ctKV 中恢复 k t c k_{t}^{c} ktc v t c v_{t}^{c} vtc 用于注意力计算。幸运的是,由于矩阵乘法的结合律,我们可以将 W U K W^{U K} WUK 合并到 W U Q W^{UQ} WUQ 中,将 W U V W^{U V} WUV 合并到 w o w^{o} wo 中。因此,我们无需为每个查询计算键值对。通过这种优化,我们避免了推理过程中重新计算 k r C k_{r}^{C} krC v t C v_{t}^{C} vtC 的计算开销。

http://www.xdnf.cn/news/5533.html

相关文章:

  • Linux进程9-无名管道:1.概述、创建、读写数据、2.进程间通信、3.读写规律、4.fcntl设置阻塞、5.文件描述符概述及复制函数dup,dup2
  • Robot之VideoMimic:《Visual Imitation Enables Contextual Humanoid Control》翻译与解读
  • 安卓系统APP:志愿填报(基于Android平台的志愿填报程序)
  • LVGL环形加载器
  • Linux开机后启动Oracle数据库
  • redis数据结构-06(LRANGE、LINDEX、LSET、LREM)
  • 数字化工厂中央控制室驾驶舱系统架构文档
  • Transformer LLM
  • Linux数据库篇、第零章_MySQL30周年庆典活动
  • 关于chatshare.xyz激活码使用说明和渠道指南!
  • 3D虚拟工厂vue3+three.js
  • Babel 深度解析:现代 JavaScript 开发的桥梁
  • @RequestParam @RequestHeader @RequestBody 三者详解
  • 【英语笔记(四)】诠释所有16种英语时态,介绍每种时态下的动词变形!!含有所有时态的的动词变形汇总表格
  • C语言学习记录——深入理解指针(4)
  • 单片机-STM32部分:13、PWM
  • MongoDB
  • wget、curl 命令使用场景与命令实践
  • 数据并行基础概念知识
  • openai接口参数max_tokens改名max-completion-tokens?
  • 17前端项目----支付弹框
  • 10.二叉搜索树中第k小的元素(medium)
  • 用pymysql操作数据库
  • POST请求 、响应、requests库高级用法
  • 甜蜜聊天话术库
  • Go语言标识符
  • 嵌入式STM32学习——433M无线遥控灯
  • AI-Talk开发板之驱动1.28寸圆屏
  • 深入理解 Polly:.NET Core 中的健壮错误处理策略
  • HTTP/1.1 host虚拟主机详解