大模型基础之位置编码RoPE

news2024/9/25 23:18:41

文章目录

    • RoPE
      • 准备知识
      • RoPE的推导
      • RoPE的代码实现
      • 参考资料

RoPE

RoPE(Rotary Position Embedding,旋转式位置编码)是一种配合Attention机制能达到“通过绝对位置编码的方式实现相对位置编码”的设计。在2021年2月由苏剑林提出,是现在的大模型最常用的位置编码。

q \mathbf{q} q k \mathbf{k} k为self-attention的q和k向量, j j j是元素索引。假设有 0 < θ ≤ π 2 N 0 < \theta\leq \frac{\pi}{2N} 0<θ2Nπ,N是最大序列长度。 i表示复数的虚数单位, ⟨ ⟩ \langle \rangle 为内积符号, z ‾ \overline{z} z表示复数z的共轭复数(注:有些地方会将共轭复数记作 z ∗ z^* z)。RoPE可表示为下述过程:
RoPE ( x , m ) = x e i m θ ⟨ RoPE ( q j , m ) , RoPE ( k j , n ) ⟩ = ⟨ q j e i m θ , k j e i n θ ⟩ = q j k j e i m θ e i n θ ‾ = q j k j e i ( m − n ) θ = RoPE ( q j k j , m − n ) \begin {aligned} \text{RoPE}(\mathbf{x}, m) &= \mathbf{x} e^{im\theta} \\ \langle \text{RoPE}(q_j, m), \text{RoPE}(k_j,n) \rangle &= \langle q_j e^{im\theta}, k_j e^{in\theta} \rangle \\ &= q_jk_j e^{im\theta} \overline{e^{in \theta}} \\ &= q_jk_j e^{i(m-n)\theta} \\ &= \text{RoPE}(q_j k_j, m-n) \end {aligned} RoPE(x,m)RoPE(qj,m),RoPE(kj,n)⟩=xeimθ=qjeimθ,kjeinθ=qjkjeimθeinθ=qjkjei(mn)θ=RoPE(qjkj,mn)

RoPE的示意图如下图(来自RoFormer论文)
在这里插入图片描述

准备知识

  • 复数的笛卡尔积形式(Cartesian form): z = a + i b z = a + ib z=a+ib

  • 复数的极坐标形式(polar form): z = r ( cos ⁡ θ + i sin ⁡ θ ) z=r(\cos \theta + i \sin \theta) z=r(cosθ+isinθ), 其中 r = ∣ z ∣ = a 2 + b 2 r=|z|=\sqrt{a^2 + b^2} r=z=a2+b2 θ = arg ⁡ ( x ) = tan ⁡ − 1 b a \theta = \arg(x) = \tan^{-1} \frac{b}{a} θ=arg(x)=tan1ab

  • 欧拉公式: e i x = cos ⁡ ( x ) + i sin ⁡ ( x ) e^{ix} = \cos(x) + i \sin(x) eix=cos(x)+isin(x)

  • 复数的指数形式(exponential form): z = r e i θ z = r \text{e}^{i\theta} z=reiθ, 其中 r = ∣ z ∣ = a 2 + b 2 r=|z|=\sqrt{a^2 + b^2} r=z=a2+b2 θ = arg ⁡ ( x ) = tan ⁡ − 1 b a \theta = \arg(x) = \tan^{-1} \frac{b}{a} θ=arg(x)=tan1ab

  • 在复数的指数形式下复数 z = r e i θ z = r \text{e}^{i\theta} z=reiθ的共轭复数为 z ‾ = r e − i θ \overline{z} = r \text{e}^{-i\theta} z=reiθ, 两个复数 z = r e i θ z = r \text{e}^{i\theta} z=reiθ w = t e i ϕ w = t \text{e}^{i\phi} w=teiϕ的乘积为 z w = r t e i ( θ + ϕ ) zw = rt \text{e}^{i(\theta + \phi)} zw=rtei(θ+ϕ)

  • 在复数的极坐标形式下两个复数 z = r ( cos ⁡ θ + i sin ⁡ θ ) z=r(\cos \theta + i \sin \theta) z=r(cosθ+isinθ) w = t ( cos ⁡ ϕ + i sin ⁡ ϕ ) w=t(\cos \phi + i \sin \phi) w=t(cosϕ+isinϕ)的乘积为 z w = r t ( cos ⁡ ( θ + ϕ ) + i sin ⁡ ( θ + ϕ ) ) zw=rt(\cos(\theta+\phi) + i\sin(\theta + \phi)) zw=rt(cos(θ+ϕ)+isin(θ+ϕ))

  • 复数 z = a + i b z = a + ib z=a+ib表示成矩阵时的形式为 ( a − b b a ) \left(\begin{array}{cc} a & -b \\ b & a \end{array}\right) (abba),而旋转矩阵形式为 [ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] \left[\begin{array}{cc} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{array}\right] [cosθsinθsinθcosθ],所以复数乘法的几何意义为将向量逆时针旋转 θ \theta θ(也可以从复数极坐标形式的乘法来理解旋转)

    在这里插入图片描述

RoPE的推导

假设有函数f(x, l)给位置l处的元素x添加绝对位置信息,对于 q \mathbf{q} q k \mathbf{k} k用函数f编码后有:
q ~ m = f ( q , m ) , k ~ n = f ( k , n ) ( 1 ) \tilde{\mathbf{q}}_m = f(\mathbf{q}, m), \qquad \tilde{\mathbf{k}}_n = f(\mathbf{k}, n) \qquad (1) q~m=f(q,m),k~n=f(k,n)(1)
即我们希望为 q \mathbf{q} q k \mathbf{k} k设计函数 f ( ⋅ , m ) f(\cdot, m) f(,m) f ( ⋅ , n ) f(\cdot, n) f(,n),使用函数编码后, q ~ m \tilde{\mathbf{q}}_m q~m k ~ n \tilde{\mathbf{k}}_n k~n带有了位置m和n的绝对位置信息。因为self-attention的核心运算是内积,我们希望 q \mathbf{q} q k \mathbf{k} k内积的结果有相对位置信息,即我们假设存在有如下恒等关系:
⟨ f ( q , m ) , f ( k , n ) ⟩ = g ( q , k , m − n ) ( 2 ) \langle f(\mathbf{q},m),f(\mathbf{k}, n) \rangle = g(\mathbf{q}, \mathbf{k}, m-n) \qquad (2) f(q,m),f(k,n)⟩=g(q,k,mn)(2)
我们的目标是求出这个恒等式的一个解。先将求解过程中的初始条件设为 f ( q , 0 ) = q f(\mathbf{q}, 0) = \mathbf{q} f(q,0)=q f ( k , 0 ) = k f(\mathbf{k}, 0) = \mathbf{k} f(k,0)=k,这可以理解为没有位置编码信息加入的情形。

我们先考虑二维情形,并借助复数来求解。用复数的指数形式来表示函数:

f ( q , m ) = R f ( q , m ) e i Θ f ( q , m ) ( 3 a ) f ( k , n ) = R f ( k , n ) e i Θ f ( k , n ) ( 3 b ) g ( q , k , m − n ) = R g ( q , k , m − n ) e i Θ g ( q , k , m − n ) ( 3 c ) \begin{align*} f(\mathbf{q}, m) &= R_f(\mathbf{q}, m)e^{i\Theta_f(\mathbf{q}, m)} \qquad (3a)\\ f(\mathbf{k}, n) &= R_f(\mathbf{k}, n)e^{i\Theta_f(\mathbf{k}, n)} \qquad (3b) \\ g(\mathbf{q}, \mathbf{k}, m - n) &= R_g(\mathbf{q}, \mathbf{k}, m - n)e^{i\Theta_g(\mathbf{q}, \mathbf{k}, m - n)} \qquad (3c) \end{align*} f(q,m)f(k,n)g(q,k,mn)=Rf(q,m)eiΘf(q,m)(3a)=Rf(k,n)eiΘf(k,n)(3b)=Rg(q,k,mn)eiΘg(q,k,mn)(3c)

上式中的 R f R_f Rf R g R_g Rg 是f和g的径向分量(radial component), Θ f \Theta_f Θf Θ g \Theta_g Θg是f和g的幅角分量(angular components)。将它们代到恒等表达式(2)中,可以得到:

R f ( q , m ) R f ( k , n ) = R g ( q , k , m − n ) ( 4 a ) Θ f ( q , m ) − Θ f ( k , n ) = Θ g ( q , k , m − n ) ( 4 b ) \begin{align*} R_f(\mathbf{q}, m) R_f(\mathbf{k}, n) &= R_g(\mathbf{q}, \mathbf{k}, m - n) \qquad (4a) \\ \Theta_f(\mathbf{q}, m) - \Theta_f(\mathbf{k}, n) &= \Theta_g(\mathbf{q}, \mathbf{k}, m - n) \qquad (4b) \\ \end{align*} Rf(q,m)Rf(k,n)Θf(q,m)Θf(k,n)=Rg(q,k,mn)(4a)=Θg(q,k,mn)(4b)

由初始条件 f ( q , 0 ) = q f(\mathbf{q}, 0) = \mathbf{q} f(q,0)=q f ( k , 0 ) = k f(\mathbf{k}, 0) = \mathbf{k} f(k,0)=k我们有( ∣ ∣ q ∣ ∣ ||\mathbf{q}|| ∣∣q∣∣ ∣ ∣ k ∣ ∣ ||\mathbf{k}|| ∣∣k∣∣ θ q \theta_q θq θ k \theta_k θk是向量 q \mathbf{q} q k \mathbf{k} k在二维平面上的径向和幅角分量):
q = ∣ ∣ q ∣ ∣ e i θ q = R q ( q , 0 ) e i Θ q ( q , 0 ) k = ∣ ∣ k ∣ ∣ e i θ k = R q ( k , 0 ) e i Θ k ( k , 0 ) ( 5 ) \begin{aligned} \mathbf{q} = ||\mathbf{q}|| e^{i\theta_q}=R_q(\mathbf{q}, 0) e^{i \Theta_q(\mathbf{q}, 0)} \\ \mathbf{k} = ||\mathbf{k}|| e^{i\theta_k}=R_q(\mathbf{k}, 0) e^{i \Theta_k(\mathbf{k}, 0)} \end{aligned} \qquad (5) q=∣∣q∣∣eiθq=Rq(q,0)eiΘq(q,0)k=∣∣k∣∣eiθk=Rq(k,0)eiΘk(k,0)(5)
设m=n,以及考虑到初始条件 f ( x , 0 ) = x f(\mathbf{x},0)=\mathbf{x} f(x,0)=x, 由式(4a)可以得到:
R f ( q , m ) R f ( k , m ) = R g ( q , k , 0 ) = R f ( q , 0 ) R f ( k , 0 ) = ∥ q ∥ ∥ k ∥ ( 6 ) R_f(\mathbf{q}, m) R_f(\mathbf{k}, m) = R_g(\mathbf{q}, \mathbf{k}, 0) = R_f(\mathbf{q}, 0) R_f(\mathbf{k}, 0) = \parallel\mathbf{q}\parallel \parallel \mathbf{k}\parallel \qquad (6) \\ Rf(q,m)Rf(k,m)=Rg(q,k,0)=Rf(q,0)Rf(k,0)=∥q∥∥k(6)

由上式我们可以有 R f ( q , m ) = R f ( q , 0 ) = ∣ ∣ q ∣ ∣ R_f(\mathbf{q}, m)=R_f(\mathbf{q}, 0)=|| \mathbf{q} || Rf(q,m)=Rf(q,0)=∣∣q∣∣ R f ( k , m ) = R f ( k , 0 ) = ∣ ∣ k ∣ ∣ R_f(\mathbf{k}, m)=R_f(\mathbf{k}, 0)=|| \mathbf{k} || Rf(k,m)=Rf(k,0)=∣∣k∣∣ R g ( q , k , m − n ) = R g ( q , k , 0 ) = ∣ ∣ q ∣ ∣ ∣ ∣ k ∣ ∣ R_g(\mathbf{q}, \mathbf{k}, m-n)=R_g(\mathbf{q}, \mathbf{k}, 0)=|| \mathbf{q} || || \mathbf{k} || Rg(q,k,mn)=Rg(q,k,0)=∣∣q∣∣∣∣k∣∣ R f R_f Rf R g R_g Rg不依赖于位置信息。

类似地,设m=n,以及考虑到初始条件 Θ ( x , 0 ) = Θ ( x ) \Theta(\mathbf{x},0)=\Theta(\mathbf{x}) Θ(x,0)=Θ(x),由式(4b)可以得到( Θ ( q ) \Theta(\mathbf{q}) Θ(q) Θ ( k ) \Theta(\mathbf{k}) Θ(k)是向量 q \mathbf{q} q k \mathbf{k} k的幅角):
Θ f ( q , m ) − Θ f ( k , m ) = Θ g ( q , k , 0 ) = Θ f ( q , 0 ) − Θ f ( k , 0 ) = Θ ( q ) − Θ ( k ) ( 7 ) \Theta_f(\mathbf{q}, m) - \Theta_f(\mathbf{k}, m) = \Theta_g(\mathbf{q}, \mathbf{k}, 0) = \Theta_f(\mathbf{q}, 0) - \Theta_f(\mathbf{k}, 0) = \Theta(\mathbf{q}) - \Theta(\mathbf{k}) \qquad (7) Θf(q,m)Θf(k,m)=Θg(q,k,0)=Θf(q,0)Θf(k,0)=Θ(q)Θ(k)(7)
将上式的第一项和最后一项移位我们可得 Θ f ( q , m ) − Θ ( q ) = Θ f ( k , m ) − Θ ( k ) \Theta_f(\mathbf{q}, m)- \Theta(\mathbf{q}) = \Theta_f(\mathbf{k}, m) - \Theta(\mathbf{k}) Θf(q,m)Θ(q)=Θf(k,m)Θ(k),所以 Θ f ( q , m ) − Θ ( q ) \Theta_f(\mathbf{q}, m)- \Theta(\mathbf{q}) Θf(q,m)Θ(q)是一个只与m有关与 q \mathbf{q} q无关的函数,将其记为 φ ( m ) \varphi(m) φ(m),则有 Θ f ( q , m ) = Θ ( q ) + φ ( m ) \Theta_f(\mathbf{q}, m)= \Theta(\mathbf{q}) + \varphi(m) Θf(q,m)=Θ(q)+φ(m)。令n=m-1,将其代入到式(4b)并移项可得
φ ( m ) − φ ( m − 1 ) = Θ g ( q , k , 1 ) + Θ ( k ) − Θ ( q ) \varphi(m)-\varphi(m-1) = \Theta_g(\mathbf{q}, \mathbf{k}, 1) + \Theta(\mathbf{k}) - \Theta(\mathbf{q}) φ(m)φ(m1)=Θg(q,k,1)+Θ(k)Θ(q)
因为上式右侧与m无关,所以上式左侧也必须与m无关,因此 φ \varphi φ是一个等差数列(arithmetic progression),如果我们设等差数列的初始值 φ ( 0 ) = 0 \varphi(0)=0 φ(0)=0 φ ( 1 ) = θ \varphi(1)=\theta φ(1)=θ,那么就可得 φ ( m ) = m θ \varphi(m) = m \theta φ(m)=mθ

综上,我们得到了二维情况下用复数表示的RoPE, 它是满足恒等式2的一个解:
f ( q , m ) = R f ( q , m ) e i Θ f ( q , m ) = ∣ ∣ q ∣ ∣ e i ( Θ ( q ) + m θ ) = q e i m θ f(\mathbf{q}, m) = R_f(\mathbf{q}, m)e^{i\Theta_f(\mathbf{q}, m)}=||\mathbf{q}||e^{i(\Theta(\mathbf{q})+m\mathbf{\theta})} = \mathbf{q} e^{im \theta} f(q,m)=Rf(q,m)eiΘf(q,m)=∣∣q∣∣ei(Θ(q)+mθ)=qeimθ
根据复数乘法的几何意义,这个变换对应着向量的旋转,所以RoPE作者将其称之为”旋转式位置编码“。

将上式表示成矩阵形式:
f ( q , m ) = ( cos ⁡ m θ − sin ⁡ m θ sin ⁡ m θ cos ⁡ m θ ) ( q 0 q 1 ) \boldsymbol{f}(\boldsymbol{q}, m)=\left(\begin{array}{cc} \cos m \theta & -\sin m \theta \\ \sin m \theta & \cos m \theta \end{array}\right)\binom{q_0}{q_1} f(q,m)=(cosmθsinmθsinmθcosmθ)(q1q0)
由于内积满足线性叠加性,所以任意偶数维的RoPE都可以表示为二维情形的拼接。
f ( q , m ) = ( M 0 M 1 ⋱ M d / 2 − 1 ) ( q 0 q 1 ⋮ q d − 1 ) = R m q m = R m W q x m f(\mathbf{q}, m) = \begin{pmatrix} M_0 & & & \\ & M_1 & & \\ & & \ddots & \\ & & & M_{d/2-1} \end{pmatrix} \begin{pmatrix} q_0\\ q_1\\ \vdots\\ q_{d-1} \end{pmatrix} = \mathbf{R_m q_m} = \mathbf{R_m W_q x_m} f(q,m)= M0M1Md/21 q0q1qd1 =Rmqm=RmWqxm
上式中 M j = ( cos ⁡ m θ j − sin ⁡ m θ j s i n m θ j cos ⁡ m θ j ) M_j=\begin{pmatrix}\cos m\theta_j & -\sin m\theta_j \\sin m\theta_j & \cos m\theta_j\end{pmatrix} Mj=(cosmθjsinmθjsinmθjcosmθj) Θ = { θ i = 1000 0 − 2 ( i − 1 ) / d , i ∈ [ 0 , 1 , 2 , … , d / 2 − 1 ] } \Theta = \{\theta_i=10000^{-2(i-1)/d}, i \in[0,1,2, \ldots, d/2-1] \} Θ={θi=100002(i1)/d,i[0,1,2,,d/21]} R m \mathbf{R_m} Rm是对角旋转矩阵,它是一个正交矩阵, W q \mathbf{W_q} Wq是待学习的query权重, x m \mathbf{x_m} xm则是m处的token的embedding。

也就是说,给位置m的向量 q \mathbf{q} q乘上矩阵 R m \mathbf{R_m} Rm,位置为n的向量 k \mathbf{k} k乘上矩阵 R n \mathbf{R_n} Rn, 用变换后的序列做Attention,Attention就自动包含相对位置了,因为有如下恒等式:
( R m q ) T ( R n k ) = q T R m T R n k = q T R m − n k (\mathbf{R_m q})^T(\mathbf{R_n k}) = \mathbf{q^T R_m^T R_n k} = \mathbf{q^T R_{m-n} k} (Rmq)T(Rnk)=qTRmTRnk=qTRmnk
因为 R m \mathbf{R_m} Rm的稀疏性,直接用矩阵乘法来实现很浪费算法,所以RoPE作者推荐用如下方式来实现RoPE:
( q 0 q 1 q 2 q 3 ⋮ q d − 2 q d − 1 ) ⊗ ( cos ⁡ m θ 0 cos ⁡ m θ 0 cos ⁡ m θ 1 cos ⁡ m θ 1 ⋮ cos ⁡ m θ d / 2 − 1 cos ⁡ m θ d / 2 − 1 ) + ( − q 1 q 0 − q 3 q 2 ⋮ − q d − 1 q d − 2 ) ⊗ ( sin ⁡ m θ 0 sin ⁡ m θ 0 sin ⁡ m θ 1 sin ⁡ m θ 1 ⋮ sin ⁡ m θ d / 2 − 1 sin ⁡ m θ d / 2 − 1 ) \left(\begin{array}{c} q_0 \\ q_1 \\ q_2 \\ q_3 \\ \vdots \\ q_{d-2} \\ q_{d-1} \end{array}\right) \otimes\left(\begin{array}{c} \cos m \theta_0 \\ \cos m \theta_0 \\ \cos m \theta_1 \\ \cos m \theta_1 \\ \vdots \\ \cos m \theta_{d / 2-1} \\ \cos m \theta_{d / 2-1} \end{array}\right)+\left(\begin{array}{c} -q_1 \\ q_0 \\ -q_3 \\ q_2 \\ \vdots \\ -q_{d-1} \\ q_{d-2} \end{array}\right) \otimes\left(\begin{array}{c} \sin m \theta_0 \\ \sin m \theta_0 \\ \sin m \theta_1 \\ \sin m \theta_1 \\ \vdots \\ \sin m \theta_{d / 2-1} \\ \sin m \theta_{d / 2-1} \end{array}\right) q0q1q2q3qd2qd1 cosmθ0cosmθ0cosmθ1cosmθ1cosmθd/21cosmθd/21 + q1q0q3q2qd1qd2 sinmθ0sinmθ0sinmθ1sinmθ1sinmθd/21sinmθd/21
上式中的 ⊗ \otimes 是逐位对应相乘,是Numpy等中的*运算。 从这个实现也可以来解释为什么RoPE可以视为是乘性位置编码的变体。

RoPE的代码实现

按照上面RoPE作者推荐的方式实现RoPE的示例如下(来自参考资料4)

import torch
import math

def rotary_position_embedding(q, k):
    """
    Rotary Position Embedding (RoPE) for queries and keys.
    
    Args:
        q: tensor for queries of shape (batch_size, num_heads, seq_len, dim)
        k: tensor for keys of shape (batch_size, num_heads, seq_len, dim)
        
    Returns:
        Rotated queries and keys
    """
    batch_size, num_heads, seq_len, dim = q.size()
    
    # Begin of sinusoidal_position_embedding content
    # 序列对应的位置序号
    position = torch.arange(seq_len, dtype=torch.float).unsqueeze(-1).to(q.device)
    # q维度上的theta值
    div_term = torch.exp(torch.arange(0, dim, 2, dtype=torch.float) * -(math.log(10000.0) / dim)).to(q.device)
    
    pos_emb = position * div_term
    pos_emb = torch.stack([torch.sin(pos_emb), torch.cos(pos_emb)], dim=-1).flatten(-2, -1)
    pos_emb = pos_emb.unsqueeze(0).unsqueeze(1)
    pos_emb = pos_emb.expand(batch_size, num_heads, -1, -1)
    # End of sinusoidal_position_embedding content

    # Extract and duplicate cosine and sine embeddings
    cos_emb = pos_emb[..., 1::2].repeat_interleave(2, dim=-1)
    sin_emb = pos_emb[..., ::2].repeat_interleave(2, dim=-1)

    # Create alternate versions of q and k
    q_alternate = torch.stack([-q[..., 1::2], q[..., ::2]], dim=-1).reshape(q.size())
    k_alternate = torch.stack([-k[..., 1::2], k[..., ::2]], dim=-1).reshape(k.size())

    # Rotate queries and keys
    q_rotated = q * cos_emb + q_alternate * sin_emb
    k_rotated = k * cos_emb + k_alternate * sin_emb

    return q_rotated, k_rotated

llama实现RoPE的方式是先将向量转到复数域,再对两个向量进行旋转,接着将向量转回到实数域。

# 以长度为4,dim维度为6的q示意llama是如何实现RoPE的
q = torch.tensor([[1, 2, 4, 5, 6, 7], [1, 2, 5, 6, 7, 8], [2, 5, 4, 6, 7, 8], [1, 3, 5, 6, 7, 9]])
seq_len, dim = q.shape  # [4,6]

# 将q在其embedding维度分为一对一对的形式
q_per_token_split_into_pairs = q.float().view(q.shape[0], -1, 2)
q_per_token_split_into_pairs.shape  # [4,3,2]

# 计算复数域的cos和sin的频率
zero_to_one_split_into_dim_parts = torch.tensor(range(dim//2))/(dim//2)
rope_theta = 10000.0
freqs = 1.0 / (rope_theta ** zero_to_one_split_into_dim_parts)
freqs_for_each_token = torch.outer(torch.arange(seq_len), freqs)
freqs_cis = torch.polar(torch.ones_like(freqs_for_each_token), freqs_for_each_token)
freqs_cis

# 将q转到复数域
q_per_token_as_complex_numbers = torch.view_as_complex(q_per_token_split_into_pairs)

# 进行dot product来按位置旋转q向量
q_per_token_as_complex_numbers_rotated = q_per_token_as_complex_numbers * freqs_cis
q_per_token_as_complex_numbers_rotated

# 将旋转了的q向量转回到实数域
q_per_token_split_into_pairs_rotated = torch.view_as_real(q_per_token_as_complex_numbers_rotated)
# 将维度还原
q_per_token_rotated = q_per_token_split_into_pairs_rotated.view(q.shape)

参考资料

  1. RoPE论文:Su, Jianlin, Yu Lu, Shengfeng Pan, Bo Wen, and Yunfeng Liu. 2021. “RoFormer: Enhanced Transformer with Rotary Position Embedding.” Cornell University - arXiv,Cornell University - arXiv, April.

  2. RoPE作者苏剑林的博客: 让研究人员绞尽脑汁的Transformer位置编码 ,Transformer升级之路:2、博采众长的旋转式位置编码

  3. eleuther.ai关于RoPE的博客

  4. 知乎文章 位置编码|RoPE|ALiBi

  5. 复数 wikipedia, 旋转矩阵wikipedia

  6. rotary_embedding-torch github

  7. llama3 from scratch

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

二叉树的中序遍历 - 力扣(LeetCode)C语言

94. 二叉树的中序遍历 - 力扣&#xff08;LeetCode&#xff09;&#xff08;点击前面链接即可查看题目&#xff09; 一、题目 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,…

【数据结构与算法】堆实现优先级队列

堆实现优先级队列 一.堆实现优先级队列的原理二.优先级队列结构体三.堆初始化四.入队五.出队六.销毁队列七.总结 一.堆实现优先级队列的原理 堆就是可以将最大值或者最小值,每次取出,那么刚好可以进行排序,而我们的优先级队列,就是对于优先级最高的先进行出队,也就相当于是排序…

空气净化器对去除宠物毛有效吗?小型猫毛空气净化器使用感受

作为一个养猫多年的猫奴&#xff0c;家里有两只可爱的小猫咪&#xff1a;小白和小花。虽然相处起来很开心&#xff0c;但也给生活带来了一些小麻烦。谁懂啊&#xff0c;我真的受够了&#xff0c;每天都在粘毛。猫窝的猫毛一周不清理就要堆成山&#xff0c;空气中也全是浮毛&…

JAVA线程中的安全性问题详解

多线程很难掌握&#xff0c;稍不注意&#xff0c;就容易使程序崩溃。我们以在路上开车为例&#xff1a; 在一个单向行驶的道路上&#xff0c;每辆汽车都遵守交通规则&#xff0c;这时候整体通行是正常的。『单向车道』意味着『一个线程』&#xff0c;『多辆车』意味着『多个 jo…

嵌入式学习---DAY18:shell脚本

shell脚本文件进程网络HtmlDb shell脚本是一系列shell命令的集合。 shell 命令解释器 shell编程&#xff1a;解释型语言、边翻译边执行、擅长文件处理,操作系统管理、开发效率高 cp 1 2、执、效率低、移植性好 C语言&#xff1a;编译型语言、先编译再执行、擅长数据计算…

【Linux】一篇总结!什么是重定向?输出重定向的作用是什么?什么又是追加重定向?

欢迎来到 CILMY23 的博客 &#x1f3c6;本篇主题为&#xff1a;一篇总结&#xff01;什么是重定向&#xff1f;输出重定向的作用是什么&#xff1f;什么又是追加重定向&#xff1f; &#x1f3c6;个人主页&#xff1a;CILMY23-CSDN博客 &#x1f3c6;系列专栏&#xff1a;Py…

绘制图层的图形全部都在geojson图层之下会被覆盖,同步graphic类型使用说明

### 绘制图层js const graphicLayer new mars3d.layer.GraphicLayer({zIndex: 1000000000000000000000000,hasEdit: false,isAutoEditing: false, // 绘制完成后是否自动激活编辑// addHeight: 1,allowDrillPick: false, }) 绘制方法js graphicLayer.startDraw({type: type,st…

一款免费的Windows 11/10系统常见问题修复工具

FixWin是一款功能强大的Windows系统修复工具&#xff0c;免费便携&#xff0c;无需安装即可使用。FixWin旨在帮助用户解决各种常见的Windows问题。它提供了多种修复选项和故障排除功能&#xff0c;适用于 Windows 11/10。 FixWin 主要功能&#xff1a; 系统文件检查器&#x…

深⼊理解指针(3)

1. 字符指针变量 2. 数组指针变量 3. ⼆维数组传参的本质 4. 函数指针变量 5. 函数指针数组 6. 转移表 1. 字符指针变量 在指针的类型中我们知道有⼀种指针类型为字符指针 ⼀般使⽤: char* 这两种方式都是把字符串中的首字符的地址赋值给pc。 在这串代码中 str1内容的地…

JVM高级特性

JVM高级特性 内存管理 jvm是自动内存管理的 运行时数据区域 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。这些区域 有各自的用途&#xff0c;以及创建和销毁的时间&#xff0c;有的区域随着虚拟机进程的启动而一直存在&#xff0c;有些…

基于STM32的智能仓储管理系统教程

目录 引言环境准备智能仓储管理系统基础代码实现&#xff1a;实现智能仓储管理系统 物品识别与追踪模块环境监控模块数据处理与存储模块用户界面与远程管理应用场景&#xff1a;仓储管理与优化常见问题与解决方案收尾与总结 引言 随着电子商务和物流行业的快速发展&#xff…

C++手撕简易vector

提前准备工作 由于vector跟string不同&#xff0c;vector是可以存储不同类型的变量的容器&#xff0c;因此实现类模板是肯定的 在原本的STL的vector容器中&#xff0c;主要成员变量有&#xff0c;start&#xff0c;finish&#xff0c;和 end_of_storage 所以 template<cl…

leetcode 2415.反转二叉树的奇数层

1.题目要求: 给你一棵 完美 二叉树的根节点 root &#xff0c;请你反转这棵树中每个 奇数 层的节点值。例如&#xff0c;假设第 3 层的节点值是 [2,1,3,4,7,11,29,18] &#xff0c;那么反转后它应该变成 [18,29,11,7,4,3,1,2] 。 反转后&#xff0c;返回树的根节点。完美 二叉…

SolverLearner:提升大模型在高度归纳推理的复杂任务性能,使其能够在较少的人为干预下自主学习和适应

SolverLearner&#xff1a;提升大模型在高度归纳推理的复杂任务性能&#xff0c;使其能够在较少的人为干预下自主学习和适应 提出背景归纳推理&#xff08;Inductive Reasoning&#xff09;演绎推理&#xff08;Deductive Reasoning&#xff09;反事实推理&#xff08;Counterf…

npm ERR! missing script: serve

报错原因&#xff1a;我这里是因为跑错命令了&#xff0c;我用的npm run serve 解决办法&#xff1a;去package.json文件里面找到对应的serve命令运行即可&#xff0c;每个系统都不太一样&#xff0c;如果还不行可以看看是不是项目终端搞错了&#xff0c;比如我这个项目有两个前…

行为型设计模式3:模板方法/备忘录/解释器/迭代器

设计模式&#xff1a;模板方法/备忘录/解释器/迭代器 (qq.com)

无需提示的思考链推理:深度探索大型语言模型的内在能力

人工智能咨询培训老师叶梓 转载标明出处 在人工智能领域&#xff0c;提升大模型&#xff08;LLMs&#xff09;的推理能力一直是研究的重点。传统的方法主要依赖于特定的提示技术&#xff0c;例如少量样本或零样本的思考链&#xff08;CoT&#xff09;提示。这些方法虽然有效&am…

力扣爆刷第169天之TOP200五连刷111-115(课程表、单词搜索、归并)

力扣爆刷第169天之TOP200五连刷111-115&#xff08;课程表、单词搜索、归并&#xff09; 文章目录 力扣爆刷第169天之TOP200五连刷111-115&#xff08;课程表、单词搜索、归并&#xff09;一、207. 课程表二、LCR 125. 图书整理 II三、402. 移掉 K 位数字四、79. 单词搜索五、9…

Python自动化办公2.0:重塑工作效率的未来

在现代办公环境中&#xff0c;自动化技术和数据分析已经成为提升工作效率和决策质量的关键。随着Python编程语言的发展&#xff0c;我们迎来了“Python自动化办公2.0”时代&#xff0c;这一时代不仅包括强大的数据分析工具&#xff0c;还涵盖了酷炫的可视化技术和前沿的机器学习…

【卷积神经网络】卷积层详解【数学+python代码】

1、简介 学习目标&#xff1a; 掌握卷积计算过程掌握特征图大小计算方法掌握PyTorch卷积层API 基本概念&#xff1a; ①在计算机视觉领域&#xff0c;往往我们输入的图像都很大&#xff0c;使用全连接网络的话&#xff0c;计算的代价较高。 另外图像也很 难保留原有的特征 &am…