一杯咖啡的时间学习大模型(LLM):LLaMA解读之旋转编码RoPE(含代码实现)

上下文窗口不是越大越好:LLM部署中的工程变量建模 上下文窗口是大语言模型(LLM)推理能力的关键载体,但其本质并非静态参数,而是受RoPE位置编码、GQA分组注意力、词表规模等底层架构约束的动态工程变量。理解其n²计算复杂度、注意力衰减机制与收益递减规律,是实现高质量RAG系统的基础。技术价值体现在平衡事实性(Factuality)与推理成本,避免‘丢失在中间’和恶意指令注入等长上下文特有风险。典型应用场景包括技术文档问答、法律合同审查与多跳知识推理,而本文聚焦decoder-only架构下可复现、可量化的context优化方法论。 阅读详情

一、LLaMA的核心改进全景

Meta开源的LLaMA模型凭借其卓越的性能表现成为大模型发展的重要里程碑。相较于标准Transformer架构,LLaMA主要在以下几个方面进行了关键改进:

  1. 位置编码升级:采用旋转位置编码(Rotary Position Embedding, RoPE)
  2. 归一化革新:对每个 Transformer 子层的输入进行归一化(Pre-normalization)而非传统Transformer结构中对输出进行归一化(Post - normalization),并使用RMS-Norm替代传统LayerNorm。
  3. 激活函数优化:引入 SwiGLU 激活函数取代 ReLU 非线性函数,以提高性能。
  4. 注意力优化(LLaMA 2):引入分组查询注意力(Grouped Query Attention)

这些改进显著提升了模型的计算效率和长文本处理能力,今天我们来学习一下旋转位置编码(Rotary Position Embedding, RoPE)。

其余部件的学习链接持续更新中,欢迎关注:

  1. 一杯咖啡的时间学习大模型(LLM):LLaMA解读之旋转编码RoPE(含代码实现)
  2. 一杯咖啡的时间学习大模型(LLM):LLaMA解读之均方根误差标准化RMSNorm(含代码实现)
  3. 一杯咖啡的时间学习大模型(LLM):LLaMA解读之SwiGLU激活函数(含代码实现)
  4. 一杯咖啡的时间学习大模型(LLM):LLaMA解读之分组查询注意力(Grouped Query Attention)(含代码实现)

二、旋转位置编码(RoPE)

2.1 改进动机

首先来谈谈 Embedding 的作用。Embedding 在自然语言处理(NLP)等任务中扮演着关键角色,它本质上是一种将离散的符号(比如单词)映射到连续向量空间的技术。对于文本来说,单词经过 Embedding 后会被表示为一个低维向量,这些向量能够捕捉单词的语义信息。例如,具有相似语义的单词(如 “big” 和 “large”)在向量空间中的距离会比较近,这样模型就能利用这些向量更好地理解文本的语义。同时,Embedding 还为后续的模型运算提供了合适的数据形式,使得模型可以对这些向量进行诸如加法、乘法等数学运算,以完成对文本信息的提取和处理。

传统Transformer使用绝对位置编码存在长度外推困难,而RoPE通过旋转矩阵将相对位置信息编码到注意力计算中,实现了更好的长度外推性。

我们通过两个具体场景来观察RoPE的特点:
在这里插入图片描述
假设我们用一个二维词向量来表示单词dog,为了表示出现在不同位置的dog,可以将该词向量旋转不同的角度来添加位置信息,同时不受句子长度的干扰——无论The dog后面是十个单词还是一百个单词,因为dog还是在该句话的第二个位置,故词向量不会改变。

在这里插入图片描述
在第二张图片中,呈现了以 “The pig chased the dog” 以及 “Once upon a time, the pig chased the dog” 这两句文本为示例,结合直角坐标系中分别代表 “pig” 和 “dog” 的黄色与蓝色向量。
传统的 Embedding 方法,通常只是单纯地为每个词分配一个固定的向量表示,它无法有效地反映出词与词之间的相对位置信息。例如在上述文本中,对于 “pig” 和 “dog”,传统方法只是分别赋予它们独立的向量,并不考虑它们在句子中的先后顺序以及相互之间的位置关系。
而 RoPE则有很大不同。在图中能看到代表 “pig” 和 “dog” 的向量有着不同的角度。RoPE 可以通过旋转角度来获取相对位置信息。它依据词在序列中的位置,对词向量进行旋转操作。不同的位置对应着不同的旋转角度,像 “pig” 和 “dog” 因在句子中的位置有别,其对应的向量会旋转到不同角度。这样一来,模型就能通过这些角度差异,感知到词与词之间的相对位置,进而更好地理解文本的语义和结构,比如理解 “pig” 是动作 “chased” 的发出者,“dog” 是承受者这种位置带来的语义关系。
但是我们同样注意到,即使两句话中“pig”和“dog”的绝对位置不同,但是这两个名词的相对位置是一样的,因此在这两句话中,两个词向量之间的角度也是一样的。

2.2 数学原理

由于整个推理比较复杂,这里只做简单介绍,推荐几个学习资料(由易到难):

  1. Rotary Positional Embeddings: Combining Absolute and Relative
  2. 通俗易懂-大模型的关键技术之一:旋转位置编码rope
  3. RoPE作者(苏剑林)的博客:Transformer升级之路:2、博采众长的旋转式位置编码

给定位置m的查询向量q和位置n的键向量k,旋转操作定义为:

q m T k n = ( R θ , m q ) T ( R θ , n k ) = q T R θ , n − m T k \begin{aligned} q_m^T k_n & = (R_{\theta,m}q)^T(R_{\theta,n}k) \\ & = q^T R_{\theta,n-m}^T k \end{aligned} qmT​kn​​=(Rθ,m​q)T(Rθ,n​k)=qTRθ,n−mT​k​

其中,其中, m m m 和 n n n 为位置索引,取值范围是 0 0 0 到序列长度(seq_len)。 q m q_m qm​ 表示位置为 m m m 的查询向量,其形式为 q m = { q 0 , q 1 , … , q d − 1 } q_m = \{q_0, q_1, \ldots, q_{d - 1}\} qm​={q0​,q1​,…,qd−1​},这里 d d d 是头维度(head_dim); k n k_n kn​ 表示位置为 n n n 的键向量,形式与 q m q_m qm​ 类似, k n = { k 0 , k 1 , … , k d − 1 } k_n = \{k_0, k_1, \ldots, k_{d - 1}\} kn​={k0​,k1​,…,kd−1​},同样 d d d 为头维度(head_dim)。

旋转矩阵R通过角度θ控制旋转速度,同时由于内积满足线性叠加性,因此对于任意偶数维的RoPE,我们都可以将其表示为二维情形的拼接:

R m = ( cos ⁡ m θ 0 − sin ⁡ m θ 0 0 0 ⋯ 0 0 sin ⁡ m θ 0 cos ⁡ m θ 0 0 0 ⋯ 0 0 0 0 cos ⁡ m θ 1 − sin ⁡ m θ 1 ⋯ 0 0 0 0 sin ⁡ m θ 1 cos ⁡ m θ 1 ⋯ 0 0 ⋮ ⋮ ⋮ ⋮ ⋱ ⋮ ⋮ 0 0 0 0 ⋯ cos ⁡ m θ d / 2 − 1 − sin ⁡ m θ d / 2 − 1 0 0 0 0 ⋯ sin ⁡ m θ d / 2 − 1 cos ⁡ m θ d / 2 − 1 ) R_{m} = \begin{pmatrix} \cos m\theta_0 & -\sin m\theta_0 & 0 & 0 & \cdots & 0 & 0 \\ \sin m\theta_0 & \cos m\theta_0 & 0 & 0 & \cdots & 0 & 0 \\ 0 & 0 & \cos m\theta_1 & -\sin m\theta_1 & \cdots & 0 & 0 \\ 0 & 0 & \sin m\theta_1 & \cos m\theta_1 & \cdots & 0 & 0 \\ \vdots & \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ 0 & 0 & 0 & 0 & \cdots & \cos m\theta_{d/2 - 1} & -\sin m\theta_{d/2 - 1} \\ 0 & 0 & 0 & 0 & \cdots & \sin m\theta_{d/2 - 1} & \cos m\theta_{d/2 - 1} \end{pmatrix} Rm​= ​cosmθ0​sinmθ0​00⋮00​−sinmθ0​cosmθ0​00⋮00​00cosmθ1​sinmθ1​⋮00​00−sinmθ1​cosmθ1​⋮00​⋯⋯⋯⋯⋱⋯⋯​0000⋮cosmθd/2−1​sinmθd/2−1​​0000⋮−sinmθd/2−1​cosmθd/2−1​​ ​

但是,因为旋转矩阵比较稀疏,直接做矩阵乘法太浪费算力了。因此,我们会将之优化成下面的形式(以 R θ , m q R_{\theta,m}q Rθ,m​q为例):

( 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 ) = ∑ i = 0 d / 2 − 1 ( ( q 2 i q 2 i + 1 ) ⊗ ( cos ⁡ m θ i cos ⁡ m θ i ) + ( − q 2 i + 1 q 2 i ) ⊗ ( sin ⁡ m θ i sin ⁡ m θ i ) ) = ∑ i = 0 d / 2 − 1 ( q 2 i cos ⁡ m θ i + q 2 i + 1 cos ⁡ m θ i − q 2 i + 1 sin ⁡ m θ i + q 2 i sin ⁡ m θ i ) \begin{aligned} & \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) \\ = & \sum_{i=0}^{d / 2-1}\left(\binom{q_{2 i}}{q_{2 i+1}} \otimes\binom{\cos m \theta_i}{\cos m \theta_i}+\binom{-q_{2 i+1}}{q_{2 i}} \otimes\binom{\sin m \theta_i}{\sin m \theta_i}\right) \\ = & \sum_{i=0}^{d / 2-1}\left(q_{2 i} \cos m \theta_i+q_{2 i+1} \cos m \theta_i-q_{2 i+1} \sin m \theta_i+q_{2 i} \sin m \theta_i\right) \end{aligned} ==​ ​q0​q1​q2​q3​⋮qd−2​qd−1​​ ​⊗ ​cosmθ0​cosmθ0​cosmθ1​cosmθ1​⋮cosmθd/2−1​cosmθd/2−1​​ ​+ ​−q1​q0​−q3​q2​⋮−qd−1​qd−2​​ ​⊗ ​sinmθ0​sinmθ0​sinmθ1​sinmθ1​⋮sinmθd/2−1​sinmθd/2−1​​ ​i=0∑d/2−1​((q2i+1​q2i​​)⊗(cosmθi​cosmθi​​)+(q2i​−q2i+1​​)⊗(sinmθi​sinmθi​​))i=0∑d/2−1​(q2i​cosmθi​+q2i+1​cosmθi​−q2i+1​sinmθi​+q2i​sinmθi​)​

其中⊗是逐位对应相乘,从这个实现也可以看到,RoPE可以视为是乘性位置编码的变体。

2.3 源码实现

下面是RoPE的Python代码实现,使用PyTorch框架:

def rotate_half(x):
    """
    将输入张量的最后一个维度分成两部分,并交换它们的位置,同时对前半部分取负。

    参数:
    x (torch.Tensor): 输入的张量,形状可以是任意的,但最后一个维度的长度必须是偶数。

    返回:
    torch.Tensor: 经过旋转操作后的张量,形状与输入张量相同。
    """
    # 获取输入张量x最后一个维度的一半长度
    half_length = x.shape[-1] // 2
    # 提取张量x最后一个维度的前半部分
    x1 = x[..., :half_length]
    # 提取张量x最后一个维度的后半部分
    x2 = x[..., half_length:]
    # 将后半部分取负,然后与前半部分在最后一个维度上拼接起来
    return torch.cat((-x2, x1), dim=-1)

def apply_rotary_pos_emb(q, k, freqs):
    """
    对查询(query)和键(key)张量应用旋转位置编码。

    参数:
    q (torch.Tensor): 查询张量,通常形状为 [batch_size, seq_len, num_heads, head_dim]。
    k (torch.Tensor): 键张量,通常形状为 [batch_size, seq_len, num_heads, head_dim]。
    freqs (torch.Tensor): 旋转频率张量,形状为 [seq_len, head_dim]。

    返回:
    tuple: 包含经过旋转位置编码后的查询和键张量的元组,形状与输入的q和k相同。
    """
    # 计算查询张量q应用旋转位置编码后的结果
    # q * freqs.cos() 是查询张量与旋转频率的余弦值逐元素相乘
    # rotate_half(q) * freqs.sin() 是将查询张量旋转后与旋转频率的正弦值逐元素相乘
    # 两者相加得到最终的查询嵌入
    freqs = freqs.repeat_interleave(2, dim=-1)
    q_embed = (q * freqs.cos()) + (rotate_half(q) * freqs.sin())
    # 计算键张量k应用旋转位置编码后的结果
    # 原理与查询张量的计算相同
    k_embed = (k * freqs.cos()) + (rotate_half(k) * freqs.sin())
    # 返回经过旋转位置编码后的查询和键张量
    return q_embed, k_embed

可能很多人看到rotate_half方法的时候会有疑惑:为什么代码中维度的前一半取正后一半取负,而不是像公式那样一正一负交替——这是因为向量维度无序,无需严格两两组合旋转。正弦和余弦函数本质都是周期波动函数,仅相位不同。RoPE 的旋转位置编码旨在用周期波动为不同位置元素赋予独特编码。理论上,特定位置用正弦还是余弦波不重要,关键是波动有周期性,且各位置编码唯一。采用前一半取正、后一半取负的方式,既能满足周期性和编码唯一性要求,又简化计算,契合代码实现对效率和简洁性的需求,是兼顾理论与实践的有效策略。

代码中的 freqs 变量指旋转频率,它是根据位置和维度信息计算得到的。具体来说,对于位置 m m m 和维度 d d d ,旋转频率 θ d \theta_d θd​ 通常预先定义,然后根据位置 m m m 计算出在该位置上各维度对应的旋转角度 m θ d 。 m \theta_{d 。} mθd。​ 一般 θ d = 1000 0 − 2 ( d / / 2 ) d model  \theta_d=10000^{-\frac{2(d / / 2)}{d_{\text {model }}}} θd​=10000−dmodel ​2(d//2)​ ,其中 d model  d_{\text {model }} dmodel ​ 指的模型维度,在场景下与head_dim等价。以下是计算 freqs 的方法:

def precompute_freqs_cis(dim, end, theta=10000.0):
    """
    预先计算旋转频率的复数形式。

    参数:
    dim (int): 模型的维度。
    end (int): 序列的最大长度。
    theta (float): 旋转频率的基础参数,默认为 10000.0。

    返回:
    torch.Tensor: 旋转频率的复数形式,形状为 [end, dim // 2]。
    """
    # 计算每个维度对应的 theta 值
    freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))
    # 创建位置索引
    t = torch.arange(end, device=freqs.device)
    # 计算每个位置和维度组合的旋转角度
    freqs = torch.outer(t, freqs).float()
    # 将旋转角度转换为复数形式
    freqs_cis = torch.polar(torch.ones_like(freqs), freqs)
    print(freqs_cis.shape)
    return freqs_cis # [1, seq_len, 1, head_dim]

最后给出旋转编码RoPE运行调试的完整代码:

import torch

def rotate_half(x):
    """
    将输入张量的最后一个维度分成两部分,并交换它们的位置,同时对前半部分取负。

    参数:
    x (torch.Tensor): 输入的张量,形状可以是任意的,但最后一个维度的长度必须是偶数。

    返回:
    torch.Tensor: 经过旋转操作后的张量,形状与输入张量相同。
    """
    # 获取输入张量x最后一个维度的一半长度
    half_length = x.shape[-1] // 2
    # 提取张量x最后一个维度的前半部分
    x1 = x[..., :half_length]
    # 提取张量x最后一个维度的后半部分
    x2 = x[..., half_length:]
    # 将后半部分取负,然后与前半部分在最后一个维度上拼接起来
    return torch.cat((-x2, x1), dim=-1)

def apply_rotary_pos_emb(q, k, freqs):
    """
    对查询(query)和键(key)张量应用旋转位置编码。

    参数:
    q (torch.Tensor): 查询张量,通常形状为 [batch_size, seq_len, num_heads, head_dim]。
    k (torch.Tensor): 键张量,通常形状为 [batch_size, seq_len, num_heads, head_dim]。
    freqs (torch.Tensor): 旋转频率张量,形状为 [seq_len, head_dim]。

    返回:
    tuple: 包含经过旋转位置编码后的查询和键张量的元组,形状与输入的q和k相同。
    """
    # 计算查询张量q应用旋转位置编码后的结果
    # q * freqs.cos() 是查询张量与旋转频率的余弦值逐元素相乘
    # rotate_half(q) * freqs.sin() 是将查询张量旋转后与旋转频率的正弦值逐元素相乘
    # 两者相加得到最终的查询嵌入
    freqs = freqs.repeat_interleave(2, dim=-1)
    q_embed = (q * freqs.cos()) + (rotate_half(q) * freqs.sin())
    # 计算键张量k应用旋转位置编码后的结果
    # 原理与查询张量的计算相同
    k_embed = (k * freqs.cos()) + (rotate_half(k) * freqs.sin())
    # 返回经过旋转位置编码后的查询和键张量
    return q_embed, k_embed

def precompute_freqs_cis(dim, end, theta=10000.0):
    """
    预先计算旋转频率的复数形式。

    参数:
    dim (int): 模型的维度。
    end (int): 序列的最大长度。
    theta (float): 旋转频率的基础参数,默认为 10000.0。

    返回:
    torch.Tensor: 旋转频率的复数形式,形状为 [end, dim // 2]。
    """
    # 计算每个维度对应的 theta 值
    freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))
    # 创建位置索引
    t = torch.arange(end, device=freqs.device)
    # 计算每个位置和维度组合的旋转角度
    freqs = torch.outer(t, freqs).float()
    # 将旋转角度转换为复数形式
    freqs_cis = torch.polar(torch.ones_like(freqs), freqs)
    print(freqs_cis.shape)
    return freqs_cis # [1, seq_len, 1, head_dim]

# 示例使用
if __name__ == "__main__":
    # 假设模型维度为 512,序列最大长度为 1024
    dim = 512
    end = 1024

    # 假设查询和键的形状
    batch_size = 2
    seq_len = 128
    num_heads = 8
    head_dim = dim // num_heads

    # 预先计算旋转频率
    freqs_cis = precompute_freqs_cis(head_dim, end)

    q = torch.randn(batch_size, seq_len, num_heads, head_dim)
    k = torch.randn(batch_size, seq_len, num_heads, head_dim)
    # 提取当前序列长度对应的旋转频率
    freqs = freqs_cis[:seq_len].unsqueeze(0).unsqueeze(2)
    print(freqs.shape)
    # 应用旋转位置编码
    q_embed, k_embed = apply_rotary_pos_emb(q, k, freqs)
    print("Encoded query shape:", q_embed.shape)
    print("Encoded key shape:", k_embed.shape)

2.4 补充

RoPE 这类周期震荡函数在处理位置信息时,随着位置距离的增加,若不进行位置衰减,远处的位置信息所呈现的震荡模式会趋近于直线 。这点受到探究RoPE(旋转位置编码)中的远程衰减性的启发,自己实现了一种RoPE的特殊情况( q q q和 k k k都是全1矩阵,探究 q 0 T k n q_0^T k_n q0T​kn​),代码如下:

import numpy
import matplotlib.pyplot as plt
dim = 128
theta = 1.0 / (10000 ** (numpy.arange(0, dim, 2)/ dim))
# print(theta)

n=1000
key_index = numpy.arange(n)
attention = []
for key in key_index:
    score = 2*numpy.sum(numpy.cos(key*theta))
    attention.append(score)


plt.plot(key_index,attention)

在这里图片描述
当n为1000时,可以看出RoPE是具有一定远程衰减的能力的,主要是因为维度 d d d越大, θ i = 1000 0 − 2 i / d \theta_i = 10000^{-2i/d} θi​=10000−2i/d的变化越缓,值越小,使得 cos ⁡ ( n θ i ) \cos(n\theta_i) cos(nθi​)周期增大。多个 cos ⁡ ( n θ i ) \cos(n\theta_i) cos(nθi​)求和构成内积,其整体函数周期也随之变大。在这较大周期的四分之一个周期内,函数存在下降趋势,叠加 θ i \theta_i θi​与 n n n作用下 cos ⁡ ( n θ i ) \cos(n\theta_i) cos(nθi​)的变化,使得位置信息在远程上呈现出衰减特性 。

在这里插入图片描述
但当n为10000时,注意力信息震荡近似一条直线,意味着不同位置的编码值差异变得极小。例如在文本序列中,原本应该代表不同位置的编码难以有效区分,模型就难以利用这些编码准确识别长序列中不同位置的元素,导致位置信息混淆。当遇到比训练数据更长的序列时,RoPE 无法像在合适长度范围内那样为模型提供清晰准确的位置信息,外推能力受限。

ChatGPT解Mensa逻辑题:约束满足问题的提示工程实战 逻辑推理题本质上是约束满足问题(CSP),其核心在于多变量、多条件下的确定性消解,而非自然语言问答。理解这一原理,是突破大模型在符号推理中幻觉频发、步骤跳跃等瓶颈的关键。当前主流AI虽具备强大模式识别与语言生成能力,但在显式建模约束关系、处理相对位置与否定线索等任务上仍存在系统性短板。通过结构化解析、约束原子化和分步验证三层提示工程,可将ChatGPT在Mensa类逻辑题上的准确率从68%提升至94%以上,显著释放其作为‘推理协作者’的技术价值。本文聚焦CSP建模范式与token级操作实践,适用于教育科技、 阅读详情

相关推荐

【LLM基础回顾】LLama2(RMSNorm、SwiGLU、RoPE位置编码)

预训练语言模型除了自回归(Autoregressive)模型GPT,还有自编码模型(Autoencoding)BERT[1]、编-解码(Encoder-Decoder)模型BART[67],以及融合上述三种方法的自回归填空(Autoregressive Blank Infilling)模型GLM(General Language Model)[68]。 ChatGPT的出现,使得目前几乎所有大语言模型神经网络结构趋同,采用自回归模型,基础架构与GPT-2相同,但在归一化函数、激活函数及位置编码等细节方面有所

发现问题,并解决问题,批判性思维 4119

【AI大模型面试题】Llama为何要采用RoPE旋转位置编码?

RoPE(Rotary Position Embedding),是苏剑林大神在 2021 年就提出的一种 Transformer 模型的位置编码。 RoPE 是一种可以以绝对位置编码形式实现的相对位置编码,兼顾了模型性能和效率。 2023 年上半年的时候,大模型位置编码尚有 Alibi 和 RoPE 在相互比拼,而到了 2023 年下半年,及今 2024 年,新开源出来的模型,大部分都是使用 RoPE 了。当然 Alibi 也有其优势,这个在讲 Alibi 的时候来说。

Android23333的博客 1628

Llama改进之——RoPE旋转位置编码

旋转位置编码从理论到实战。

日积月累,天道酬勤 3392

RoPE旋转编码以及在LLAMA中的应用

补充说明:LayerNorm,Pre-Norm,Post-Norm,RMSNorm,DeepNormLayerNorm:在单个样本的整个序列上的全部特征做归一化BatchNorm:在一个批次的样本整个序列上每个特征做归一化为什么transformer使用LayerNorm而不是BatchNorm?因为在做归一化时,我们需要确保参与归一化的数据点在本质上是可比的。

qq_45778335的博客 1281

全在这了!全国分省90米、30米、12.5米、5米DEM高程模型数据下载方式汇总

全在这了!全国分省90米、30米、12.5米、5米DEM高程模型数据下载方式汇总 SRTM15(450米)免费下载 https://pan.baidu.com/s/1eO0U6wfzs7YSe2EQdxRJ2Q提取码:o7am GMTED(250米)免费下载 https://pan.baidu.com/share/init?surl=nrbbdbhyNVQV46XwqzqLlg 提取码:V7X9 SRTM3 (90米)免费下载 https://pan.baidu.com/share/..

TuxinyunGIS的博客 1万+

瑞萨RZN2L工业以太网开发避坑指南:EtherCAT从入门到通信调试全流程

本文详细解析了瑞萨RZN2L MPU在工业以太网开发中的EtherCAT从站配置与通信优化全流程。通过硬件设计关键点、协议栈选型、PDO映射策略及DC同步精度优化等实战技巧,帮助开发者快速搭建高效通信框架并解决调试中的常见问题,特别适合工业自动化领域的实时通信需求。

aitie1479的博客 461

深入理解LLaMA, Alpaca, ColossalChat 系列模型

知乎:紫气东来https://zhuanlan.zhihu.com/p/618695885一、从 LLaMA 到 Alpaca:大模型的小训练1.1 LLaMA 概要与实践LLaMA(Large Language Model Meta AI) 是由 Meta AI 发布了一款全新的大型语言模型,共有7B、13B、33B、65B 四种版本,其模型参数如下表所示:与原始的 transformer De...

zenRRan的博客 1万+

AutoCAD2014与ObjectARX开发环境搭建实战指南

本文提供了一份详细的AutoCAD2014与ObjectARX开发环境搭建实战指南。内容涵盖从AutoCAD2014、Visual Studio 2010及ObjectARX 2014 SDK的版本匹配与环境准备,到Wizard安装、编码问题解决、Visual Studio配置,并最终通过一个完整的绘图命令开发示例,手把手引导开发者创建并加载第一个可运行的ObjectARX插件,为后续深入开发奠定坚实基础。

weixin_28475533的博客 288

一杯咖啡的时间学习大模型(LLM):LLaMA解读之均方根误差标准化RMSNorm(含代码实现)

一文读懂LLaMA核心架构之均方根误差标准化RMSNorm(含代码实现)

Bug_makerACE的博客 2331

保姆级教程:用PyBullet在Windows/Mac上快速搭建你的第一个机器人仿真环境(附避坑指南)

本教程详细介绍了如何使用PyBullet在Windows和Mac上快速搭建机器人仿真环境,包括Python环境配置、依赖安装避坑指南、首个机械臂仿真实现及性能优化技巧。通过分步指导和实战代码,帮助初学者轻松入门机器人仿真技术。

weixin_42526087的博客 407

pix4d安装步骤

pix4d三维模型软件的安装步骤

Little_Bee_27000的博客 1万+

一杯咖啡的时间学习大模型(LLM):LLaMA解读之SwiGLU激活函数

一问读懂LLaMA核心架构之SwiGLU激活函数

Bug_makerACE的博客 1588

应用商店评论分析实战:Python逆向工程破解Google Play加密接口与NLP建模

在移动互联网时代,应用商店中的用户评论成为了开发者优化应用、提升用户体验的重要依据。然而,Google Play等应用商店对评论数据进行了加密处理,直接爬取难度较大。本文将介绍如何使用Python逆向工程破解Google Play的加密接口,实现对应用商店评论的实时采集,并结合NLP(自然语言处理)技术进行情感分析和主题建模,为开发者提供有价值的数据支持。

u014481728的博客 1348

一杯咖啡的时间学习大模型(LLM):LLaMA解读之分组查询注意力(Grouped Query Attention)

一文读懂LLaMA核心架构之分组查询注意力(Grouped Query Attention)

Bug_makerACE的博客 1686

【PCL点云配准】位姿估计

本文介绍了PCL(Point Cloud Library)中TransformationEstimation模块的核心算法原理和实现方法。该模块通过多种子类(如SVD、LM、双四元数等)提供点云配准功能,支持2D/3D刚性变换估计。主要内容包括:1)各类变换估计算法的数学原理和实现细节;2)点对点/点对面两种误差度量方法;3)线性闭式解和非线性迭代两种求解方式;4)变换验证机制;5)基于三点法的完整代码示例。该模块广泛应用于SLAM、三维重建等领域,为点云配准提供了高效可靠的解决方案。

yijiujiusan的博客 242

C#联合Halcon机器视觉框架源码—升级版

相较于之前的NxtVision,本软件代码架构更加合理,且新增。对源码有需求的,订阅本专栏后,私信我领取。、原来的vb脚本改为。

Z's Palace 1415

LLaMA论文+源码分享

含LLaMA论文地址+解读视频+源码地址分享!

Bug_makerACE的博客 1766

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

PandaGPT:统一跨模态token空间的多模态大模型工程实践

多模态大模型的核心挑战在于视觉、语音、文本等异构信号如何对齐与协同理解。传统双塔架构因缺乏模态间隐空间约束,在真实噪声场景(如教室环境、工业现场)中鲁棒性差、易失效。PandaGPT提出单塔全模态嵌入范式,通过统一输入维度、模态感知位置编码(MAPE)和门控注意力机制,构建共享隐空间下的跨模态token对齐能力。该设计显著提升在低照度、高噪声、小样本等资源受限条件下的感知一致性与推理稳定性,适用于教育硬件、工业质检、无障碍交互等需‘眼耳协同’决策的关键场景。

weixin_33736832的博客 455

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Transformer架构深度拆解:从数学原理到工程落地

Transformer是一种基于自注意力机制的序列建模架构,其核心在于摒弃RNN/CNN的归纳偏置,通过QKV计算、位置编码与前馈网络实现全局依赖建模。原理上,它依赖缩放点积注意力保障梯度稳定,正弦位置编码注入序列顺序信息,并以LayerNorm和残差连接构建通畅梯度流。技术价值体现在模块化设计、并行友好性及跨模态泛化能力,广泛应用于NLP、视觉(ViT)与多模态任务。实际落地需关注多头注意力维度对齐、位置编码类型选择(如RoPE)、Pre-LN/Post-LN结构差异及FFN容量配置等关键细节。本文聚焦T

weixin_34417183的博客 328

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

大模型学习笔记------Llama 3模型架构之旋转编码(RoPE)

本文只要讲述Llama3中比较重要的旋转位置编码(RoPE)的基本原理与优点。

gz7seven 2129

LLaMa-1/2/3 原理+源码——拆解 (KV-Cache, RoPE, RMSNorm, GQA, SwiGLU)

LLama原理拆解 (KV-Cache, Rotary Positional Embedding, RMS Norm, Grouped Query Attention, SwiGLU)

ZhengrongYue的博客 1万+

LLaMA中ROPE位置编码实现源码解析

1、Attention中q,经下式,生成新的q。m为句长length,d为embedding_dim/head。2、LLaMA中RoPE源码。

跨过一座座山 3703

Llama为何要采用RoPE旋转位置编码?

最近在做 LLM 窗口外推的相关工作,因此刚好也回顾一下目前最流行的位置编码 RoPE。01RoPE(Rotary Position Embedding),是苏剑林大神在 2021 年就提出的一种 Transformer 模型的位置编码。RoPE 是一种可以以绝对位置编码形式实现的相对位置编码,兼顾了模型性能和效率。2023 年上半年的时候,大模型位置编码尚有 Alibi 和 RoPE 在相互比拼,而到了 2023 年下半年,及今 2024 年,新开源出来的模型,大部分都是使用 RoPE 了。

m0_64752471的博客 1370

【人工智能99问】LLaMA中的RoPE是什么?(35/99)

RoPE(旋转位置编码)是一种用于Transformer模型的位置编码方法,由论文《RoPE: Rotary Position Embedding》提出。其核心思想是通过旋转矩阵对词向量的不同维度进行旋转,从而将位置信息编码到向量中。与传统位置编码(如正余弦编码)不同,RoPE的设计天然满足“相对位置不变性”——即编码后的向量之间的内积仅依赖于相对位置,而非绝对位置,这更符合Transformer注意力机制对位置关系的需求。

EnHengNa的博客 1479

一文通透位置编码:从标准位置编码、复数、欧拉公式到旋转位置编码RoPE(含其推导与代码实现)

关于位置编码和RoPE为彻底解决这个位置编码/RoPE的问题,我把另外两篇文章中关于这部分的内容抽取出来,并不断深入、扩展、深入,最终成为本文。

结构之法 算法之道 8万+

LLaMA及其子孙模型概述

Alpaca是Stanford用52k指令数据微调LLaMA 7B后得到的预训练模型,作者声称在单轮指令执行的效果上,Alpaca的回复质量和openai的text-davinci-003相当,但是Alpaca的参数非常少(微调一个7B的llama需要在8张A100 80G上训练3个小时,花费至少100美元)。为了更好的评估效果,我们使用了一个包含一千个样本和九个真实场景的评估集来测试各种模型,同时通过量化分析来提供有价值的见解,以便更好地促进开源聊天模型的发展。白泽提出的训练方法。

qq_44193969的博客 2328
上一篇: 大模型(LLM)入门学习路线分享(内含计划表和时间安排)
下一篇: 一杯咖啡的时间学习大模型(LLM):LLaMA解读之均方根误差标准化RMSNorm(含代码实现)
ACEEE-1222
博客等级 码龄4年 432粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值