旋转位置编码(ROPE)详解:从Transformer到现代前沿

旋转位置编码(ROPE)详解:从Transformer到现代前沿

标签:NLP, Transformer, 位置编码, ROPE, 深度学习, 机器学习

摘要:本文详细介绍了旋转位置编码(ROPE)在Transformer模型中的应用,包括其数学原理、代码实现以及与传统位置编码的对比。ROPE通过旋转嵌入向量来编码位置信息,能够自然捕捉相对位置关系,特别适用于长序列任务。文中提供了ROPE的PyTorch实现和使用示例,旨在帮助读者深入理解并应用这一先进技术。

引言

在自然语言处理(NLP)领域,Transformer模型因其强大的并行计算能力和对长距离依赖的捕捉而成为主流。然而,Transformer中的自注意力机制(Self-Attention)天生无序,无法感知输入序列中词语的相对位置。为了解决这一问题,研究者们提出了多种位置编码(Positional Encoding)方案,其中旋转位置编码(Rotary Position Embedding, ROPE)凭借其独特的旋转机制和在长序列任务中的优异表现,成为近年来备受关注的技术。

本文将从基础概念出发,逐步深入ROPE的数学原理、实现细节及其在Transformer模型中的应用,旨在为读者提供一篇最详细的中文博客。无论您是NLP初学者还是资深研究者,本文都将帮助您全面理解ROPE的精髓。我们将涵盖从简单概念到复杂结论的介绍,包括数学推导和代码实现。


1. 为什么需要位置编码?

在介绍ROPE之前,我们首先需要理解为什么Transformer模型需要位置编码。

1.1 Transformer的自注意力机制

Transformer模型的核心是自注意力机制,它通过计算输入序列中每个词与其他词的注意力权重,来捕捉词与词之间的关系。自注意力机制的计算公式如下:

Attention ( Q , K , V ) = softmax ( Q K T d k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V Attention(Q,K,V)=softmax(dk QKT)V

其中:

  • ( Q Q Q):查询(Query)矩阵
  • ( K K K):键(Key)矩阵
  • ( V V V):值(Value)矩阵
  • ( d k d_k dk):键向量的维度

关键点:自注意力机制是无序的,即对输入序列的位置信息不敏感。这意味着,如果我们将输入序列中的词语打乱顺序,自注意力机制的输出不会改变。这在NLP任务中是致命的,因为词语的顺序对语义至关重要。例如,“我喜欢你”和“你喜欢我”在自注意力机制中无法区分。

1.2 传统的位置编码方法

为了弥补这一缺陷,Vaswani等人在2017年的原始Transformer论文《Attention is All You Need》中提出了正弦/余弦位置编码(Sinusoidal Positional Encoding)。这种方法为每个位置生成一个固定的编码向量,并将其到词嵌入向量上,以提供位置信息。

正弦/余弦位置编码的公式

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):嵌入向量的总维度

工作原理

  • 通过不同频率的正弦和余弦函数,为每个位置生成独特的编码。
  • 将 ( P E PE PE ) 加到词嵌入向量 ( x \mathbf{x} x ) 上:( x ′ = x + P E \mathbf{x}' = \mathbf{x} + PE x=x+PE )。

局限性

  1. 绝对位置依赖:正弦/余弦位置编码主要捕捉绝对位置信息,难以直接反映词与词之间的相对位置关系。
  2. 长序列表现欠佳:在处理超长序列时,位置编码的频率设计可能不适应,导致性能下降。
  3. 静态编码:位置编码是预先计算好的,无法动态适应不同序列长度。

为了克服这些局限,研究者们探索了多种改进方案,其中ROPE作为一种创新的位置编码方法,凭借其旋转机制和对相对位置的自然捕捉,逐渐成为Transformer模型中的首选技术。


2. 旋转位置编码(ROPE)简介

ROPE(Rotary Position Embedding)最早由Su等人在2021年的论文《RoFormer: Enhanced Transformer with Rotary Position Embedding》中提出。它与传统的加性位置编码不同,通过旋转嵌入向量来编码位置信息,具体是将位置信息融入到自注意力机制的查询(Query)和键(Key)向量中。

2.1 ROPE的核心思想

ROPE的核心思想是:通过旋转矩阵对嵌入向量进行旋转,使得旋转后的向量在计算点积时,能够自然地反映出词与词之间的相对位置关系。

具体来说,ROPE将嵌入向量视为复数空间中的向量,并通过旋转矩阵对这些向量进行旋转。旋转的角度与词在序列中的位置成正比,从而将位置信息编码到向量的方向中。

独特优势:ROPE不仅能编码绝对位置,还能自然捕捉相对位置关系。例如,两个词之间的注意力得分会随着它们在序列中的相对距离而变化,这在处理长距离依赖时尤为重要。


3. ROPE的数学原理

要深入理解ROPE,我们需要从数学上推导其工作机制。

3.1 旋转矩阵与复数表示

ROPE的关键在于使用旋转矩阵来编码位置信息。首先,我们将嵌入向量的每一对维度(例如,第0和1维、第2和3维等)视为一个复数。假设嵌入维度 ( d d d) 为偶数,我们可以将嵌入向量 ( x ∈ R d \mathbf{x} \in \mathbb{R}^d xRd ) 分成 ( d / 2 d/2 d/2 ) 个复数对。

例如,对于 ( d = 4 d = 4 d=4 ),嵌入向量 ( x = [ x 0 , x 1 , x 2 , x 3 ] \mathbf{x} = [x_0, x_1, x_2, x_3] x=[x0,x1,x2,x3] ) 可以表示为两个复数:

  • ( x 0 + x 1 i x_0 + x_1 i x0+x1i )
  • ( x 2 + x 3 i x_2 + x_3 i x2+x3i )

在复数空间中,旋转一个复数 ( z = a + b i z = a + b i z=a+bi ) 可以通过乘以 ( e i θ e^{i \theta} eiθ ) 实现:

z ′ = z ⋅ e i θ = ( a + b i ) ( cos ⁡ θ + i sin ⁡ θ ) z' = z \cdot e^{i \theta} = (a + b i)(\cos \theta + i \sin \theta) z=zeiθ=(a+bi)(cosθ+isinθ)

展开后:

z ′ = ( a cos ⁡ θ − b sin ⁡ θ ) + i ( a sin ⁡ θ + b cos ⁡ θ ) z' = (a \cos \theta - b \sin \theta) + i (a \sin \theta + b \cos \theta) z=(acosθbsinθ)+i(asinθ+bcosθ)

这等价于对向量 ( [ a , b ] [a, b] [a,b] ) 应用旋转矩阵:

[ cos ⁡ θ − sin ⁡ θ sin ⁡ θ cos ⁡ θ ] [ a b ] = [ a cos ⁡ θ − b sin ⁡ θ a sin ⁡ θ + b cos ⁡ θ ] \begin{bmatrix} \cos \theta & -\sin \theta \\ \sin \theta & \cos \theta \end{bmatrix} \begin{bmatrix} a \\ b\end{bmatrix}= \begin{bmatrix} a \cos \theta - b \sin \theta \\ a \sin \theta + b \cos \theta \end{bmatrix} [cosθsinθsinθcosθ][ab]=[acosθbsinθasinθ+bcosθ]

因此,对于每个复数对(即每两个维度),我们可以通过旋转矩阵来编码位置信息。

3.2 ROPE的旋转角度设计

在ROPE中,旋转角度 ( θ \theta θ ) 由词的位置 ( p p p ) 和预定义的频率决定。具体地,对于第 ( k k k ) 个复数对(对应第 ( 2 k 2k 2k ) 和 ( 2 k + 1 2k+1 2k+1 ) 维),旋转角度为:

θ k = p ⋅ ω k \theta_k = p \cdot \omega_k θk=pωk

其中,频率 ( ω k \omega_k ωk ) 定义为:

ω k = 1 1000 0 2 k / d , k = 0 , 1 , … , d / 2 − 1 \omega_k = \frac{1}{10000^{2k / d}}, \quad k = 0, 1, \dots, d/2 - 1 ωk=100002k/d1,k=0,1,,d/21

注意:这里的频率设计与正弦/余弦位置编码中的频率类似,但ROPE将其用于旋转角度,而不是直接加到嵌入向量上。

3.3 ROPE的旋转公式

对于位置 ( p p p ) 处的嵌入向量 ( x ∈ R d \mathbf{x} \in \mathbb{R}^d xRd ),ROPE通过以下方式旋转它:

x rot = [ x 0 cos ⁡ θ 0 − x 1 sin ⁡ θ 0 x 0 sin ⁡ θ 0 + x 1 cos ⁡ θ 0 x 2 cos ⁡ θ 1 − x 3 sin ⁡ θ 1 x 2 sin ⁡ θ 1 + x 3 cos ⁡ θ 1 ⋮ x d − 2 cos ⁡ θ d / 2 − 1 − x d − 1 sin ⁡ θ d / 2 − 1 x d − 2 sin ⁡ θ d / 2 − 1 + x d − 1 cos ⁡ θ d / 2 − 1 ] \mathbf{x}_{\text{rot}} = \begin{bmatrix} x_0 \cos \theta_0 - x_1 \sin \theta_0 \\ x_0 \sin \theta_0 + x_1 \cos \theta_0 \\ x_2 \cos \theta_1 - x_3 \sin \theta_1 \\ x_2 \sin \theta_1 + x_3 \cos \theta_1 \\ \vdots \\ x_{d-2} \cos \theta_{d/2-1} - x_{d-1} \sin \theta_{d/2-1} \\ x_{d-2} \sin \theta_{d/2-1} + x_{d-1} \cos \theta_{d/2-1} \end{bmatrix} xrot= x0cosθ0x1sinθ0x0sinθ0+x1cosθ0x2cosθ1x3sinθ1x2sinθ1+x3cosθ1xd2cosθd/21xd1sinθd/21xd2sinθd/21+xd1cosθd/21

简言之,ROPE对嵌入向量的每一对维度应用一个旋转矩阵,旋转角度由位置 ( p p p ) 和频率 ( ω k \omega_k ωk ) 决定。

3.4 ROPE在自注意力中的应用

在Transformer的自注意力机制中,ROPE被应用于查询(Query)和键(Key)向量。具体地,对于序列中的每个位置 ( i i i ),我们旋转其查询向量 ( q i \mathbf{q}_i qi ) 和键向量 ( k i \mathbf{k}_i ki ):

q i rot = R ( p i ) q i , k i rot = R ( p i ) k i \mathbf{q}_i^{\text{rot}} = R(p_i) \mathbf{q}_i, \quad \mathbf{k}_i^{\text{rot}} = R(p_i) \mathbf{k}_i qirot=R(pi)qi,kirot=R(pi)ki

其中,( R ( p i ) R(p_i) R(pi) ) 是位置 ( p i p_i pi ) 对应的旋转矩阵。

然后,注意力得分计算为:

score i j = q i rot ⋅ k j rot d k \text{score}_{ij} = \frac{\mathbf{q}_i^{\text{rot}} \cdot \mathbf{k}_j^{\text{rot}}}{\sqrt{d_k}} scoreij=dk qirotkjrot

关键洞察:由于旋转矩阵的性质,( q i rot ⋅ k j rot \mathbf{q}_i^{\text{rot}} \cdot \mathbf{k}_j^{\text{rot}} qirotkjrot ) 可以表示为原始向量 ( q i \mathbf{q}_i qi ) 和 ( k j \mathbf{k}_j kj ) 的点积,乘以一个与相对位置 ( p i − p j p_i - p_j pipj ) 相关的旋转项。这使得注意力得分自然地依赖于词与词之间的相对位置。


4. ROPE的相对位置编码特性

ROPE的一个显著优势是它能够自然地捕捉相对位置信息。让我们通过数学推导来理解这一点。

4.1 旋转后的点积

考虑两个位置 ( m m m ) 和 ( n n n ),对应的旋转查询和键向量为:

q m rot = R ( m ) q m , k n rot = R ( n ) k n \mathbf{q}_m^{\text{rot}} = R(m) \mathbf{q}_m, \quad \mathbf{k}_n^{\text{rot}} = R(n) \mathbf{k}_n qmrot=R(m)qm,knrot=R(n)kn

它们的点积为:

q m rot ⋅ k n rot = ( R ( m ) q m ) T ( R ( n ) k n ) = q m T R ( m ) T R ( n ) k n \mathbf{q}_m^{\text{rot}} \cdot \mathbf{k}_n^{\text{rot}} = (R(m) \mathbf{q}_m)^T (R(n) \mathbf{k}_n) = \mathbf{q}_m^T R(m)^T R(n) \mathbf{k}_n qmrotknrot=(R(m)qm)T(R(n)kn)=qmTR(m)TR(n)kn

由于旋转矩阵 ( R ( θ ) R(\theta) R(θ) ) 是正交矩阵,满足 ( R ( θ ) T = R ( − θ ) R(\theta)^T = R(-\theta) R(θ)T=R(θ) ),因此:

R ( m ) T R ( n ) = R ( − m ) R ( n ) = R ( n − m ) R(m)^T R(n) = R(-m) R(n) = R(n - m) R(m)TR(n)=R(m)R(n)=R(nm)

(后文有推导过程。)

所以:

q m rot ⋅ k n rot = q m T R ( n − m ) k n \mathbf{q}_m^{\text{rot}} \cdot \mathbf{k}_n^{\text{rot}} = \mathbf{q}_m^T R(n - m) \mathbf{k}_n qmrotknrot=qmTR(nm)kn

这表明,旋转后的点积等价于将键向量 ( k n \mathbf{k}_n kn ) 旋转一个与相对位置 ( n − m n - m nm ) 相关的角度后,再与查询向量 ( q m \mathbf{q}_m qm ) 做点积。

4.2 相对位置的自然捕捉

上述推导显示,注意力得分 ( q m rot ⋅ k n rot \mathbf{q}_m^{\text{rot}} \cdot \mathbf{k}_n^{\text{rot}} qmrotknrot ) 直接依赖于相对位置 ( n − m n - m nm ),而不是绝对位置 ( m m m ) 和 ( n n n )。这使得ROPE在处理序列任务时,能够更自然地捕捉词与词之间的相对位置关系,尤其是在长序列中,相对位置信息比绝对位置信息更为重要。

简单示例
假设 ( d = 2 d = 2 d=2 ),位置 ( m = 0 m = 0 m=0 ),( n = 1 n = 1 n=1 ),嵌入向量 ( q 0 = [ 1 , 0 ] \mathbf{q}_0 = [1, 0] q0=[1,0] ),( k 1 = [ 0 , 1 ] \mathbf{k}_1 = [0, 1] k1=[0,1] ),频率 ( ω 0 = 1 \omega_0 = 1 ω0=1 )。那么:

  • ( θ 0 = 0 ⋅ 1 = 0 \theta_0 = 0 \cdot 1 = 0 θ0=01=0 ),( R ( 0 ) = [ 1 0 0 1 ] R(0) = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} R(0)=[1001] )
  • ( θ 0 = 1 ⋅ 1 = 1 \theta_0 = 1 \cdot 1 = 1 θ0=11=1 ),( R ( 1 ) = [ cos ⁡ 1 − sin ⁡ 1 sin ⁡ 1 cos ⁡ 1 ] R(1) = \begin{bmatrix} \cos 1 & -\sin 1 \\ \sin 1 & \cos 1 \end{bmatrix} R(1)=[cos1sin1sin1cos1] )
  • ( q 0 rot = [ 1 , 0 ] \mathbf{q}_0^{\text{rot}} = [1, 0] q0rot=[1,0] )
  • ( k 1 rot = [ cos ⁡ 1 , sin ⁡ 1 ] \mathbf{k}_1^{\text{rot}} = [\cos 1, \sin 1] k1rot=[cos1,sin1] )
  • 点积:( q 0 rot ⋅ k 1 rot = 1 ⋅ cos ⁡ 1 + 0 ⋅ sin ⁡ 1 = cos ⁡ 1 \mathbf{q}_0^{\text{rot}} \cdot \mathbf{k}_1^{\text{rot}} = 1 \cdot \cos 1 + 0 \cdot \sin 1 = \cos 1 q0rotk1rot=1cos1+0sin1=cos1 )

如果位置变为 ( m = 1 m = 1 m=1 ),( n = 2 n = 2 n=2 ),相对位置仍为1,点积结果依然依赖 ( cos ⁡ 1 \cos 1 cos1 ) 和 ( sin ⁡ 1 \sin 1 sin1 ),体现出相对位置特性。


5. ROPE的代码实现

为了帮助读者更好地理解ROPE的实现细节,下面提供一个使用PyTorch的ROPE实现。

5.1 ROPE类定义

import torch
import torch.nn as nnclass RotaryEmbedding(nn.Module):def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None):super(RotaryEmbedding, self).__init__()self.dim = dimself.max_position_embeddings = max_position_embeddingsself.base = base# 计算频率inv_freq = 1.0 / (self.base ** (torch.arange(0, self.dim, 2).float().to(device) / self.dim))self.register_buffer("inv_freq", inv_freq)def forward(self, x, seq_len=None):if seq_len is None:seq_len = x.size(-2)# 生成位置索引position_ids = torch.arange(0, seq_len, dtype=torch.float, device=x.device).unsqueeze(-1)# 计算旋转角度angles = position_ids * self.inv_freq# 计算sin和cossin = torch.sin(angles)cos = torch.cos(angles)# 扩展到与x相同的维度sin = sin.unsqueeze(0).repeat(x.size(0), 1, 1)cos = cos.unsqueeze(0).repeat(x.size(0), 1, 1)# 应用旋转x_rot = x.clone()for i in range(0, self.dim, 2):x_rot[..., i] = x[..., i] * cos[..., i // 2] - x[..., i + 1] * sin[..., i // 2]x_rot[..., i + 1] = x[..., i] * sin[..., i // 2] + x[..., i + 1] * cos[..., i // 2]return x_rot

代码说明

  • dim:嵌入维度,必须为偶数。
  • max_position_embeddings:支持的最大序列长度。
  • base:频率计算中的基数,默认值为10000。
  • inv_freq:预计算的频率,用于生成旋转角度。
  • forward:对输入张量 ( x x x ) 应用旋转,返回旋转后的张量。

5.2 使用示例

假设我们有一个批次大小为1、序列长度为3、嵌入维度为4的输入:

dim = 4
seq_len = 3
x = torch.randn(1, seq_len, dim)  # 形状: [batch_size, seq_len, dim]
rotary_emb = RotaryEmbedding(dim)
x_rot = rotary_emb(x)
print("Rotated embeddings:", x_rot)

在Transformer模型中,我们通常在自注意力层的查询和键向量上应用ROPE:

import math
# 假设 q 和 k 是查询和键向量,形状: [batch_size, num_heads, seq_len, head_dim]
batch_size, num_heads, seq_len, head_dim = 2, 8, 10, 64
q = torch.randn(batch_size, num_heads, seq_len, head_dim)
k = torch.randn(batch_size, num_heads, seq_len, head_dim)
rotary_emb = RotaryEmbedding(head_dim)
q_rot = rotary_emb(q)
k_rot = rotary_emb(k)
# 计算注意力得分
scores = torch.einsum("bhqd,bhkd->bhqk", q_rot, k_rot) / math.sqrt(head_dim)
print("Attention scores shape:", scores.shape)  # [batch_size, num_heads, seq_len, seq_len]

6. ROPE的优势与局限性

6.1 优势

  1. 自然捕捉相对位置信息:通过旋转机制,注意力得分直接依赖于相对位置,适合处理长距离依赖。
  2. 对序列长度鲁棒:ROPE不需要为特定序列长度预先计算位置编码,可以灵活适应不同长度的输入。
  3. 计算效率高:旋转操作可以通过向量化实现,计算开销小。
  4. 与Transformer架构兼容:ROPE可以无缝集成到现有的Transformer模型中,无需大幅修改架构。

6.2 局限性

  1. 嵌入维度要求:ROPE要求嵌入维度为偶数,这在某些模型设计中可能需要调整。
  2. 超长序列下的频率调整:在处理极长序列时,可能需要调整频率参数(如NTK-aware scaled ROPE),以避免旋转角度过大导致的信息丢失。
  3. 实现复杂度:相较于简单的加性位置编码,ROPE的实现稍显复杂,需要仔细处理旋转矩阵的计算。

7. ROPE在现代大型语言模型中的应用

ROPE因其优异的性能,已被广泛应用于现代大型语言模型中,例如:

  • Llama:Meta的Llama模型系列采用了ROPE作为位置编码方案。
  • PaLM:Google的PaLM模型使用ROPE处理长序列任务。
  • RoBERTa:Fairseq中的RoBERTa实现也集成了ROPE。

在实际应用中,ROPE在文本生成、机器翻译、长文本总结等领域展现了强大的能力,尤其是在处理长序列和捕捉复杂语义关系时,优势尤为明显。


8. 总结

旋转位置编码(ROPE)作为一种创新的位置编码方法,通过旋转嵌入向量来编码位置信息,成功解决了传统位置编码在捕捉相对位置信息和处理长序列方面的不足。其数学原理巧妙地利用了旋转矩阵的性质,使得注意力机制能够自然地融入相对位置信息。ROPE的高效实现和与Transformer架构的良好兼容性,使其成为现代NLP模型的首选位置编码方案。

通过本文的详细介绍,从基础概念到数学推导,再到代码实现和实际应用,相信读者已经对ROPE有了深入的理解。ROPE不仅是理论上的突破,也是实践中的利器,在推动NLP技术发展的道路上扮演着重要角色。


补充: R ( − m ) R ( n ) = R ( n − m ) R(-m) R(n) = R(n - m) R(m)R(n)=R(nm)推导

我们来一步步推导 ( R ( m ) T R ( n ) = R ( − m ) R ( n ) = R ( n − m ) R(m)^T R(n) = R(-m) R(n) = R(n - m) R(m)TR(n)=R(m)R(n)=R(nm) ) 这个等式,深入理解旋转位置编码(ROPE)中旋转矩阵的性质。这部分推导涉及到旋转矩阵的正交性和旋转角度的加法性质,是ROPE能够捕捉相对位置信息的关键数学基础。


1. 旋转矩阵的定义

在ROPE中,旋转矩阵 ( R ( p ) R(p) R(p) ) 是为序列中位置 ( p p p ) 定义的,用于旋转嵌入向量。假设嵌入维度 ( d d d ) 为偶数,( R ( p ) R(p) R(p) ) 是分块对角矩阵,每个块是一个 2×2 的旋转矩阵,对应嵌入向量的每一对维度(例如,第0和1维、第2和3维)。对于第 ( k k k ) 个维度对,旋转矩阵定义为:

R k ( p ) = [ cos ⁡ ( p ⋅ ω k ) − sin ⁡ ( p ⋅ ω k ) sin ⁡ ( p ⋅ ω k ) cos ⁡ ( p ⋅ ω k ) ] R_k(p) = \begin{bmatrix} \cos(p \cdot \omega_k) & -\sin(p \cdot \omega_k) \\ \sin(p \cdot \omega_k) & \cos(p \cdot \omega_k) \end{bmatrix} Rk(p)=[cos(pωk)sin(pωk)sin(pωk)cos(pωk)]

其中:

  • ( p p p ) 是位置索引(整数)。
  • ( ω k = 1 1000 0 2 k / d \omega_k = \frac{1}{10000^{2k/d}} ωk=100002k/d1 ) 是第 ( k k k ) 个维度对的频率,( k = 0 , 1 , … , d / 2 − 1 k = 0, 1, \dots, d/2 - 1 k=0,1,,d/21 )。

对于整个 ( d d d ) 维嵌入向量,( R ( p ) R(p) R(p) ) 是 ( d × d d \times d d×d ) 的分块对角矩阵:

R ( p ) = diag ( R 0 ( p ) , R 1 ( p ) , … , R d / 2 − 1 ( p ) ) R(p) = \text{diag}(R_0(p), R_1(p), \dots, R_{d/2-1}(p)) R(p)=diag(R0(p),R1(p),,Rd/21(p))

但在推导中,我们只需关注单个 2×2 旋转矩阵的性质,因为整体矩阵的运算可以分解为每个块的独立运算。


2. 旋转矩阵的正交性

旋转矩阵的一个重要性质是正交性,即:

R ( p ) T R ( p ) = I R(p)^T R(p) = I R(p)TR(p)=I

其中 ( I I I ) 是单位矩阵。这意味着 ( R ( p ) T R(p)^T R(p)T ) 是 ( R ( p ) R(p) R(p) ) 的逆矩阵:

R ( p ) T = R ( p ) − 1 R(p)^T = R(p)^{-1} R(p)T=R(p)1

对于 2×2 旋转矩阵:

R ( p ) = [ cos ⁡ ( p ω k ) − sin ⁡ ( p ω k ) sin ⁡ ( p ω k ) cos ⁡ ( p ω k ) ] R(p) = \begin{bmatrix} \cos(p \omega_k) & -\sin(p \omega_k) \\ \sin(p \omega_k) & \cos(p \omega_k) \end{bmatrix} R(p)=[cos(pωk)sin(pωk)sin(pωk)cos(pωk)]

其转置为:

R ( p ) T = [ cos ⁡ ( p ω k ) sin ⁡ ( p ω k ) − sin ⁡ ( p ω k ) cos ⁡ ( p ω k ) ] R(p)^T = \begin{bmatrix} \cos(p \omega_k) & \sin(p \omega_k) \\ -\sin(p \omega_k) & \cos(p \omega_k) \end{bmatrix} R(p)T=[cos(pωk)sin(pωk)sin(pωk)cos(pωk)]

我们可以验证:

R ( p ) T R ( p ) = [ cos ⁡ ( p ω k ) sin ⁡ ( p ω k ) − sin ⁡ ( p ω k ) cos ⁡ ( p ω k ) ] [ cos ⁡ ( p ω k ) − sin ⁡ ( p ω k ) sin ⁡ ( p ω k ) cos ⁡ ( p ω k ) ] R(p)^T R(p) = \begin{bmatrix} \cos(p \omega_k) & \sin(p \omega_k) \\ -\sin(p \omega_k) & \cos(p \omega_k) \end{bmatrix} \begin{bmatrix} \cos(p \omega_k) & -\sin(p \omega_k) \\ \sin(p \omega_k) & \cos(p \omega_k) \end{bmatrix} R(p)TR(p)=[cos(pωk)sin(pωk)sin(pωk)cos(pωk)][cos(pωk)sin(pωk)sin(pωk)cos(pωk)]

计算第一行第一列:

cos ⁡ ( p ω k ) ⋅ cos ⁡ ( p ω k ) + sin ⁡ ( p ω k ) ⋅ sin ⁡ ( p ω k ) = cos ⁡ 2 ( p ω k ) + sin ⁡ 2 ( p ω k ) = 1 \cos(p \omega_k) \cdot \cos(p \omega_k) + \sin(p \omega_k) \cdot \sin(p \omega_k) = \cos^2(p \omega_k) + \sin^2(p \omega_k) = 1 cos(pωk)cos(pωk)+sin(pωk)sin(pωk)=cos2(pωk)+sin2(pωk)=1

计算完整矩阵:

  • 第一行第二列:( cos ⁡ ( p ω k ) ⋅ ( − sin ⁡ ( p ω k ) ) + sin ⁡ ( p ω k ) ⋅ cos ⁡ ( p ω k ) = − cos ⁡ ( p ω k ) sin ⁡ ( p ω k ) + sin ⁡ ( p ω k ) cos ⁡ ( p ω k ) = 0 \cos(p \omega_k) \cdot (-\sin(p \omega_k)) + \sin(p \omega_k) \cdot \cos(p \omega_k) = -\cos(p \omega_k) \sin(p \omega_k) + \sin(p \omega_k) \cos(p \omega_k) = 0 cos(pωk)(sin(pωk))+sin(pωk)cos(pωk)=cos(pωk)sin(pωk)+sin(pωk)cos(pωk)=0 )
  • 第二行第一列:( ( − sin ⁡ ( p ω k ) ) ⋅ cos ⁡ ( p ω k ) + cos ⁡ ( p ω k ) ⋅ sin ⁡ ( p ω k ) = − sin ⁡ ( p ω k ) cos ⁡ ( p ω k ) + cos ⁡ ( p ω k ) sin ⁡ ( p ω k ) = 0 (-\sin(p \omega_k)) \cdot \cos(p \omega_k) + \cos(p \omega_k) \cdot \sin(p \omega_k) = -\sin(p \omega_k) \cos(p \omega_k) + \cos(p \omega_k) \sin(p \omega_k) = 0 (sin(pωk))cos(pωk)+cos(pωk)sin(pωk)=sin(pωk)cos(pωk)+cos(pωk)sin(pωk)=0 )
  • 第二行第二列:( ( − sin ⁡ ( p ω k ) ) ⋅ ( − sin ⁡ ( p ω k ) ) + cos ⁡ ( p ω k ) ⋅ cos ⁡ ( p ω k ) = sin ⁡ 2 ( p ω k ) + cos ⁡ 2 ( p ω k ) = 1 (-\sin(p \omega_k)) \cdot (-\sin(p \omega_k)) + \cos(p \omega_k) \cdot \cos(p \omega_k) = \sin^2(p \omega_k) + \cos^2(p \omega_k) = 1 (sin(pωk))(sin(pωk))+cos(pωk)cos(pωk)=sin2(pωk)+cos2(pωk)=1 )

结果为:

R ( p ) T R ( p ) = [ 1 0 0 1 ] = I R(p)^T R(p) = \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} = I R(p)TR(p)=[1001]=I

这确认了 ( R ( p ) R(p) R(p) ) 是正交矩阵。


3. 旋转矩阵的逆与负角度

旋转矩阵的逆可以通过旋转角度的负值表示。考虑:

R ( − p ) = [ cos ⁡ ( − p ω k ) − sin ⁡ ( − p ω k ) sin ⁡ ( − p ω k ) cos ⁡ ( − p ω k ) ] R(-p) = \begin{bmatrix} \cos(-p \omega_k) & -\sin(-p \omega_k) \\ \sin(-p \omega_k) & \cos(-p \omega_k) \end{bmatrix} R(p)=[cos(pωk)sin(pωk)sin(pωk)cos(pωk)]

由于 ( cos ⁡ ( − θ ) = cos ⁡ ( θ ) \cos(-\theta) = \cos(\theta) cos(θ)=cos(θ) ) 和 ( sin ⁡ ( − θ ) = − sin ⁡ ( θ ) \sin(-\theta) = -\sin(\theta) sin(θ)=sin(θ) ):

R ( − p ) = [ cos ⁡ ( p ω k ) sin ⁡ ( p ω k ) − sin ⁡ ( p ω k ) cos ⁡ ( p ω k ) ] R(-p) = \begin{bmatrix} \cos(p \omega_k) & \sin(p \omega_k) \\ -\sin(p \omega_k) & \cos(p \omega_k) \end{bmatrix} R(p)=[cos(pωk)sin(pωk)sin(pωk)cos(pωk)]

这与 ( R ( p ) T R(p)^T R(p)T ) 完全相同,因此:

R ( p ) T = R ( − p ) R(p)^T = R(-p) R(p)T=R(p)

这表明,旋转矩阵的转置等价于反向旋转,即旋转角度取负。


4. 推导 ( R ( m ) T R ( n ) = R ( − m ) R ( n ) R(m)^T R(n) = R(-m) R(n) R(m)TR(n)=R(m)R(n) )

现在推导第一个等式 ( R ( m ) T R ( n ) = R ( − m ) R ( n ) R(m)^T R(n) = R(-m) R(n) R(m)TR(n)=R(m)R(n) )。

根据旋转矩阵的正交性:

R ( m ) T = R ( − m ) R(m)^T = R(-m) R(m)T=R(m)

所以:

R ( m ) T R ( n ) = R ( − m ) R ( n ) R(m)^T R(n) = R(-m) R(n) R(m)TR(n)=R(m)R(n)

这个等式是直接成立的,因为 ( R ( m ) T R(m)^T R(m)T ) 定义为 ( R ( − m ) R(-m) R(m) )。我们可以进一步验证:

  • ( R ( m ) = [ cos ⁡ ( m ω k ) − sin ⁡ ( m ω k ) sin ⁡ ( m ω k ) cos ⁡ ( m ω k ) ] R(m) = \begin{bmatrix} \cos(m \omega_k) & -\sin(m \omega_k) \\ \sin(m \omega_k) & \cos(m \omega_k) \end{bmatrix} R(m)=[cos(mωk)sin(mωk)sin(mωk)cos(mωk)] )
  • ( R ( m ) T = [ cos ⁡ ( m ω k ) sin ⁡ ( m ω k ) − sin ⁡ ( m ω k ) cos ⁡ ( m ω k ) ] = R ( − m ) R(m)^T = \begin{bmatrix} \cos(m \omega_k) & \sin(m \omega_k) \\ -\sin(m \omega_k) & \cos(m \omega_k) \end{bmatrix} = R(-m) R(m)T=[cos(mωk)sin(mωk)sin(mωk)cos(mωk)]=R(m) )
  • ( R ( n ) = [ cos ⁡ ( n ω k ) − sin ⁡ ( n ω k ) sin ⁡ ( n ω k ) cos ⁡ ( n ω k ) ] R(n) = \begin{bmatrix} \cos(n \omega_k) & -\sin(n \omega_k) \\ \sin(n \omega_k) & \cos(n \omega_k) \end{bmatrix} R(n)=[cos(nωk)sin(nωk)sin(nωk)cos(nωk)] )

左侧 ( R ( m ) T R ( n ) R(m)^T R(n) R(m)TR(n) ) 和右侧 ( R ( − m ) R ( n ) R(-m) R(n) R(m)R(n) ) 是同一个矩阵乘法,因此:

R ( m ) T R ( n ) = R ( − m ) R ( n ) R(m)^T R(n) = R(-m) R(n) R(m)TR(n)=R(m)R(n)


5. 推导 ( R ( − m ) R ( n ) = R ( n − m ) R(-m) R(n) = R(n - m) R(m)R(n)=R(nm) )

接下来推导第二个等式 ( R ( − m ) R ( n ) = R ( n − m ) R(-m) R(n) = R(n - m) R(m)R(n)=R(nm) ),这涉及到旋转矩阵的角度加法性质

计算 ( R ( − m ) R ( n ) R(-m) R(n) R(m)R(n) ):

R ( − m ) = [ cos ⁡ ( − m ω k ) − sin ⁡ ( − m ω k ) sin ⁡ ( − m ω k ) cos ⁡ ( − m ω k ) ] = [ cos ⁡ ( m ω k ) sin ⁡ ( m ω k ) − sin ⁡ ( m ω k ) cos ⁡ ( m ω k ) ] R(-m) = \begin{bmatrix} \cos(-m \omega_k) & -\sin(-m \omega_k) \\ \sin(-m \omega_k) & \cos(-m \omega_k) \end{bmatrix} = \begin{bmatrix} \cos(m \omega_k) & \sin(m \omega_k) \\ -\sin(m \omega_k) & \cos(m \omega_k) \end{bmatrix} R(m)=[cos(mωk)sin(mωk)sin(mωk)cos(mωk)]=[cos(mωk)sin(mωk)sin(mωk)cos(mωk)]

R ( n ) = [ cos ⁡ ( n ω k ) − sin ⁡ ( n ω k ) sin ⁡ ( n ω k ) cos ⁡ ( n ω k ) ] R(n) = \begin{bmatrix} \cos(n \omega_k) & -\sin(n \omega_k) \\ \sin(n \omega_k) & \cos(n \omega_k) \end{bmatrix} R(n)=[cos(nωk)sin(nωk)sin(nωk)cos(nωk)]

矩阵乘法 ( R ( − m ) R ( n ) R(-m) R(n) R(m)R(n) ):

  • 第一行第一列:( cos ⁡ ( m ω k ) ⋅ cos ⁡ ( n ω k ) + sin ⁡ ( m ω k ) ⋅ sin ⁡ ( n ω k ) \cos(m \omega_k) \cdot \cos(n \omega_k) + \sin(m \omega_k) \cdot \sin(n \omega_k) cos(mωk)cos(nωk)+sin(mωk)sin(nωk) )
  • 第一行第二列:( cos ⁡ ( m ω k ) ⋅ ( − sin ⁡ ( n ω k ) ) + sin ⁡ ( m ω k ) ⋅ cos ⁡ ( n ω k ) \cos(m \omega_k) \cdot (-\sin(n \omega_k)) + \sin(m \omega_k) \cdot \cos(n \omega_k) cos(mωk)(sin(nωk))+sin(mωk)cos(nωk) )
  • 第二行第一列:( ( − sin ⁡ ( m ω k ) ) ⋅ cos ⁡ ( n ω k ) + cos ⁡ ( m ω k ) ⋅ sin ⁡ ( n ω k ) (-\sin(m \omega_k)) \cdot \cos(n \omega_k) + \cos(m \omega_k) \cdot \sin(n \omega_k) (sin(mωk))cos(nωk)+cos(mωk)sin(nωk) )
  • 第二行第二列:( ( − sin ⁡ ( m ω k ) ) ⋅ ( − sin ⁡ ( n ω k ) ) + cos ⁡ ( m ω k ) ⋅ cos ⁡ ( n ω k ) (-\sin(m \omega_k)) \cdot (-\sin(n \omega_k)) + \cos(m \omega_k) \cdot \cos(n \omega_k) (sin(mωk))(sin(nωk))+cos(mωk)cos(nωk) )

使用三角恒等式:

  • ( cos ⁡ ( a ) cos ⁡ ( b ) + sin ⁡ ( a ) sin ⁡ ( b ) = cos ⁡ ( a − b ) \cos(a) \cos(b) + \sin(a) \sin(b) = \cos(a - b) cos(a)cos(b)+sin(a)sin(b)=cos(ab) )
  • ( cos ⁡ ( a ) ( − sin ⁡ ( b ) ) + sin ⁡ ( a ) cos ⁡ ( b ) = − sin ⁡ ( a ) cos ⁡ ( b ) + sin ⁡ ( a ) cos ⁡ ( b ) = − sin ⁡ ( a − b ) \cos(a) (-\sin(b)) + \sin(a) \cos(b) = -\sin(a) \cos(b) + \sin(a) \cos(b) = -\sin(a - b) cos(a)(sin(b))+sin(a)cos(b)=sin(a)cos(b)+sin(a)cos(b)=sin(ab) )
  • ( − sin ⁡ ( a ) cos ⁡ ( b ) + cos ⁡ ( a ) sin ⁡ ( b ) = sin ⁡ ( a − b ) -\sin(a) \cos(b) + \cos(a) \sin(b) = \sin(a - b) sin(a)cos(b)+cos(a)sin(b)=sin(ab) )

代入 ( a = m ω k a = m \omega_k a=mωk ),( b = n ω k b = n \omega_k b=nωk ):

  • 第一行第一列:( cos ⁡ ( m ω k − n ω k ) = cos ⁡ ( ( n − m ) ω k ) \cos(m \omega_k - n \omega_k) = \cos((n - m) \omega_k) cos(mωknωk)=cos((nm)ωk) )
  • 第一行第二列:( − sin ⁡ ( m ω k − n ω k ) = − sin ⁡ ( ( n − m ) ω k ) -\sin(m \omega_k - n \omega_k) = -\sin((n - m) \omega_k) sin(mωknωk)=sin((nm)ωk) )
  • 第二行第一列:( sin ⁡ ( m ω k − n ω k ) = sin ⁡ ( ( n − m ) ω k ) \sin(m \omega_k - n \omega_k) = \sin((n - m) \omega_k) sin(mωknωk)=sin((nm)ωk) )
  • 第二行第二列:( cos ⁡ ( m ω k − n ω k ) = cos ⁡ ( ( n − m ) ω k ) \cos(m \omega_k - n \omega_k) = \cos((n - m) \omega_k) cos(mωknωk)=cos((nm)ωk) )

因此:

R ( − m ) R ( n ) = [ cos ⁡ ( ( n − m ) ω k ) − sin ⁡ ( ( n − m ) ω k ) sin ⁡ ( ( n − m ) ω k ) cos ⁡ ( ( n − m ) ω k ) ] = R ( n − m ) R(-m) R(n) = \begin{bmatrix} \cos((n - m) \omega_k) & -\sin((n - m) \omega_k) \\ \sin((n - m) \omega_k) & \cos((n - m) \omega_k) \end{bmatrix} = R(n - m) R(m)R(n)=[cos((nm)ωk)sin((nm)ωk)sin((nm)ωk)cos((nm)ωk)]=R(nm)


6. 完整推导结论

结合两步:

R ( m ) T R ( n ) = R ( − m ) R ( n ) = R ( n − m ) R(m)^T R(n) = R(-m) R(n) = R(n - m) R(m)TR(n)=R(m)R(n)=R(nm)

这个等式表明,两个位置 ( m m m ) 和 ( n n n ) 的旋转矩阵相乘后,结果仅依赖于它们的相对位置 ( n − m n - m nm )。这正是ROPE能够捕捉相对位置信息的核心数学依据。


7. 在ROPE中的意义

在自注意力机制中,查询向量 ( q m \mathbf{q}_m qm ) 和键向量 ( k n \mathbf{k}_n kn ) 被旋转为:

q m rot = R ( m ) q m , k n rot = R ( n ) k n \mathbf{q}_m^{\text{rot}} = R(m) \mathbf{q}_m, \quad \mathbf{k}_n^{\text{rot}} = R(n) \mathbf{k}_n qmrot=R(m)qm,knrot=R(n)kn

点积为:

q m rot ⋅ k n rot = ( R ( m ) q m ) T ( R ( n ) k n ) = q m T R ( m ) T R ( n ) k n = q m T R ( n − m ) k n \mathbf{q}_m^{\text{rot}} \cdot \mathbf{k}_n^{\text{rot}} = (R(m) \mathbf{q}_m)^T (R(n) \mathbf{k}_n) = \mathbf{q}_m^T R(m)^T R(n) \mathbf{k}_n = \mathbf{q}_m^T R(n - m) \mathbf{k}_n qmrotknrot=(R(m)qm)T(R(n)kn)=qmTR(m)TR(n)kn=qmTR(nm)kn

这表明注意力得分依赖于相对位置 ( n − m n - m nm ),而不是绝对位置 ( m m m ) 和 ( n n n ),从而实现了ROPE的相对位置编码特性。


总结

通过旋转矩阵的正交性(( R ( m ) T = R ( − m ) R(m)^T = R(-m) R(m)T=R(m) ))和角度加法性质(( R ( − m ) R ( n ) = R ( n − m ) R(-m) R(n) = R(n - m) R(m)R(n)=R(nm) )),我们推导出了 ( R ( m ) T R ( n ) = R ( − m ) R ( n ) = R ( n − m ) R(m)^T R(n) = R(-m) R(n) = R(n - m) R(m)TR(n)=R(m)R(n)=R(nm) )。这个性质是ROPE在Transformer模型中高效编码相对位置的数学基础。

参考资料

  1. Su, J., et al. (2021). “RoFormer: Enhanced Transformer with Rotary Position Embedding.” arXiv:2104.09864
  2. Vaswani, A., et al. (2017). “Attention is All You Need.” arXiv:1706.03762
  3. Rotary Embeddings Explained | Papers With Code
  4. GitHub - lucidrains/rotary-embedding-torch
  5. Understanding Rotary Positional Encoding | Medium

后记

2025年2月23日20点19分于上海,在Grok 3 大模型辅助下完成。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【多模态处理篇三】【DeepSeek语音合成:TTS音色克隆技术揭秘】

最近帮某明星工作室做AI语音助手时遇到魔幻需求——要求用5秒的咳嗽声克隆出完整音色!传统TTS系统直接翻车,生成的语音像得了重感冒的电音怪物。直到祭出DeepSeek的TTS音色克隆黑科技,才让AI语音从"机器朗读"进化到"声临其境"。今天我们就来扒开这个声音…

IDEA使用Maven方式构建SpringBoot项目

1、环境准备 确保你已经安装了以下工具: Java JDK(推荐 JDK 8 或更高版本) IntelliJ IDEA(推荐使用最新版本) 2、创建 Spring Boot 项目 (1) 打开 IntelliJ IDEA。 (2&#xff09…

【Redis原理】底层数据结构 五种数据类型

文章目录 动态字符串SDS(simple dynamic string )SDS结构定义SDS动态扩容 IntSetIntSet 结构定义IntSet的升级 DictDict结构定义Dict的扩容Dict的收缩Dict 的rehash ZipListZipListEntryencoding 编码字符串整数 ZipList的连锁更新问题 QuickListQuickList源码 SkipListRedisOb…

Git Repo下如何制作一个patch文件

Git Repo下如何制作一个patch文件 1. 源由2. 步骤2.1 本地代码差异2.2 添加修改代码2.3 添加未跟踪代码2.4 确认打包文件2.5 输出打包文件2.6 自查打包文件2.7 恢复工作环境 3. 总结 1. 源由 patch分享,更好的差异化比较,减少时间浪费。同时&#xff0c…

跟着李沐老师学习深度学习(十四)

注意力机制(Attention) 引入 心理学角度 动物需要在复杂环境下有效关注值得注意的点心理学框架:人类根据随意线索和不随意线索选择注意力 注意力机制 之前所涉及到的卷积、全连接、池化层都只考虑不随意线索而注意力机制则显示的考虑随意…

STM32的“Unique device ID“能否修改?

STM32F1系列的"Unique device ID"寄存器的地址为0x1FFFF7E8。 这个寄存器是只读的。 "Unique device ID"寄存器位于“System memory”中。“System memory”地址范围为“0x1FFF F000- 0x1FFF F7FF”。 所有STM32 MCU上都存在系统引导加载程序。顾名思义&a…

模型思维 - 领域模型的应用与解析

文章目录 引言模型的核心作用与价值四大模型类型UML建模工具UML类图的核心价值类关系深度剖析企业级建模实践 领域模型(推荐) vs 数据模型(不推荐)区别联系错把领域模型当数据模型错误方案 vs 正确方案对比正确方案的实现1. 数据库…

基于GWO灰狼优化的WSN网络最优节点部署算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 无线传感器网络(Wireless Sensor Network, WSN)由大量分布式传感器节点组成,用于监测物理或环境状况。节点部署是 WSN 的关键问…

产品概念的提出

产品概念的提出 一个产品或者一个产品概念idea是怎么想到的呢?很多情况下它其实来自生活中的一些不爽、不满意、想吐槽,凡是用户抱怨的事情就是用户的强烈刚需需求是我们要去做的事情。当有了一个想法时需要弄清楚一下几个问题: 核心用户事…

3.Docker常用命令

1.Docker启动类命令 1.启动Docker systemctl start docker 2.停止Docker systemctl stop docker 3.重启Docker systemctl restart docker 4.查看Docker状态 systemctl status docker 5.设置开机自启(执行此命令后每次Linux重启后将自启动Docker) systemctl enable do…

交互编程工具之——Jupyter

Jupyter 是什么? Jupyter 是一个开源的交互式编程和数据分析工具,广泛应用于数据科学、机器学习、教育和研究领域。其核心是 Jupyter Notebook(现升级为 JupyterLab),允许用户在一个基于浏览器的界面中编写代码、运行…

使用 AIStor 和 OpenSearch 增强搜索功能

在这篇文章中,我们将探讨搜索,特别是 OpenSearch 如何帮助我们识别模式或查看不断增长的数据中的趋势。例如,如果您正在查看运营数据,如果您的服务似乎是随机的,那么您需要尽可能回溯以识别模式并找出原因。这不仅适用…

java基础学习

java基础 面向对象三大特性 特性:封装、继承、多态; 封装:对抽象的事物抽象化成一个对象,并对其对象的属性私有化,同时提供一些能被外界访问属性的方法; 继承:子类扩展新的数据域或功能&#…

MySQL | MySQL库、表的基本操作01

MySQL库、表的基本操作01 一、库操作1.1 查看数据库1.2 创建数据库1.3 选择数据库1.4 查看创建数据库的SQL语句1.5 修改数据库1.6 删除数据库 二、表操作2.1 创建数据表2.2 查看表2.3 查看表结构2.4 查看创建数据库的SQL语句2.5 修改表2.6 删除表 ⚠️MySQL版本 8.0 一、库操作…

设备唯一ID获取,支持安卓/iOS/鸿蒙Next(uni-device-id)UTS插件

设备唯一ID获取 支持安卓/iOS/鸿蒙(uni-device-id)UTS插件 介绍 获取设备唯一ID、设备唯一标识,支持安卓(AndroidId/OAID/IMEI/MEID/MacAddress/Serial/UUID/设备基础信息),iOS(Identifier/UUID),鸿蒙&am…

正点原子[第三期]Arm(iMX6U)Linux系统移植和根文件系统构建-5.3 xxx_defconfig过程

前言: 本文是根据哔哩哔哩网站上“arm(iMX6U)Linux系统移植和根文件系统构键篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。 引用: …

力扣热题 100:哈希专题三道题详细解析(JAVA)

文章目录 一、两数之和1. 题目描述2. 示例3. 解题思路4. 代码实现(Java)5. 复杂度分析 二、字母异位词分组1. 题目描述2. 示例3. 解题思路4. 代码实现(Java)5. 复杂度分析 三、最长连续序列1. 题目描述2. 示例3. 解题思路4. 代码实…

嵌入式八股文(五)硬件电路篇

一、名词概念 1. 整流和逆变 (1)整流:整流是将交流电(AC)转变为直流电(DC)。常见的整流电路包括单向整流(二极管)、桥式整流等。 半波整流:只使用交流电的正…

AI2-THOR环境下实现机器人导航、物体定位与抓取

1. 依赖安装 pip install ai2thor pip install numpy pillow opencv-python2. 验证安装 # 运行测试脚本验证安装 test_thor.py from ai2thor.controller import Controller controller Controller(scene"FloorPlan1") controller.step(action"MoveAhead"…

Nginx(详解以及如何使用)

目录 1. 什么是Nginx? 2. 为什么使用nginx? 3. 安装nginx 3.1?安装nginx的依赖插件 3.2 下载nginx ?3.3?创建一个目录作为nginx的安装路径 ?3.4?解压 ?3.5?进入解压后的目录 3.6?指定nginx的安装路径 ?3.7?编译和安装nginx 3.8 启动nginx ?…