Transformer Systems · Transformer Systems
Exploring the Transformer Series (17) --- RoPE
RoPE positional encoding, derivation, properties, extrapolation, and implementation.
Exploring the Transformer Series (17) --- RoPE
0x00 Overview
RoPE encoding comes from Su Shen’s work Roformer , and it is one of the most popular PE encoding methods currently used in LLM.
The Transformer paper used Sinusoidal positional encoding, which is additive encoding, meaning the word embedding is added to the encoded position. The embedding vector for each position is fixed, regardless of its relationship to other positions. Sinusoidal positional encoding aims to introduce relative positional relationships (the positional encoding of any position can be expressed as a linear combination of the positional encodings of a known position with respect to distance), but it hasn’t been very successful; the model can only perceive relative positions to a certain extent. A common improvement to positional encoding is based on the triangular positional encoding formula, adjusting the bias of the self-attention calculation. RoPE, however, abandons this common improvement approach. Based on the triangular positional encoding formula, it uses techniques such as rotation matrices, complex multiplication, and Euler’s formula to reflect the relative positional information of two tokens in the form of a self-attention matrix bias, while also decomposing it to the feature sequence and directly encoding the absolute position of the tokens, thus combining the advantages of both absolute and relative positional encoding.
RoPR doesn’t modify the Attention structure. Instead, it works on the input layer, similar to absolute positional encoding, by directly transforming the input vector. Specifically, it performs a rotation transformation on the Query and Key vectors formed by the two input tokens, incorporating positional information into the transformed Query and Key. This allows the Attention’s inner product operation to automatically perceive relative positional information without any changes. In other words, RoPR’s starting point and strategy are based on relative positional encoding, but its implementation uses absolute positional encoding.

0x01 Overall Approach
Let’s first look at the proposed modifications or pain points for trigonometric function encoding, which have two aspects.
- In the analysis of previous chapters, we already know the calculation of the attention layer . This would destroy the desirable properties of the input layer’s positional encoding. Therefore, we naturally think of directly incorporating positional information into the attention layer, that is, directly applying the positional encoding to . This way, the excellent properties of positional coding can be maintained.
- Trigonometric function encoding directly adds positional information to the token embedding. Some argue that this pollutes semantic information with positional data and that information should be encoded without modifying the specification.
Therefore, let’s first review the attention mechanism.
1.1 Review of Attention Mechanisms
The key to the attention mechanism lies in obtaining the elements of the self-attention matrix through the inner product of vectors. For example, calculating the embedding vector of the -th word. The corresponding self-attention output is And all of the others An attention score will be calculated, and then the attention score will be multiplied by the corresponding Then sum them to get the output vector. The specific formula is as follows:
1.2 Analysis of the Approach
As can be seen from the formula above, the influence of one token on another is determined by The attention score is determined by the dot product, or in other words, it’s essentially the inner product of two feature vectors. This is where positional encoding should be our focus. Therefore, let’s look at the representation of the dot product:
Two insights can be gleaned from this:
- The dot product of two vectors can be adjusted by increasing or decreasing the angle between them.
- Rotation has no effect on the norm of a vector, which may encode the semantic information of a token.
Therefore, we only need to perform absolute positional encoding on the Query and Key vectors before they enter the attention mechanism; it has nothing to do with the Value. This allows the positional encoding information to be directly introduced. This means that we want to impose a certain penalty on this inner product calculation based on the result of :
- When is small, we want to bring it closer to the nearest . , The distance.
- When is large, we want to move it further away. , The distance.
Let’s look at how the paper demonstrates how the solution was found. RoPE’s starting point is “to achieve relative position encoding through absolute position encoding,” meaning that absolute positions are used during encoding, but the dot product reflects the relative position. Mathematically, this involves finding a suitable position encoding function such that the following formula holds true.
In layman’s terms, it means processing at position and at position to achieve the desired result. The calculation of attention scores implicitly includes the relative positional information of and . We will further explain this using the formula from the paper. RoPE aims to… and The inner product operation is encoded into a function , where the arguments of include two tokens. and And its relative position . indicates and Perform inner product operations.
Because of the properties of function , therefore and The inner product also implies the relative positions and . This allows the inner product to be larger when the two words are relatively close (smaller and ), and smaller when they are relatively far apart (larger and ). In this way, without modifying the attention structure, explicit relative position information is integrated into the self-attention calculation, enabling the attention inner product to automatically perceive relative position information, thus achieving the goal of relative position encoding in the form of absolute position encoding.
Note that only here , It is the function that needs to be solved. And for , we require that the expression contains… , , It can also be said that , The inner product is affected by the relative position 𝑚−𝑛.
1.3 Results Display
Let’s examine whether RoPE satisfies the requirement of “achieving relative position encoding through absolute position encoding”.
- Inject absolute position information. For position … and the position of RoPE will first and In each feature dimension, pairs of dimensions are grouped together, with each pair forming a complex number, corresponding to a vector in the complex plane. These vectors are then multiplied by corresponding positions using a complex rotation matrix, thus injecting absolute position information into the vector by rotating it by a certain angle. That is, for a vector at position … Multiply by matrix Given a vector at position Multiply by matrix Each of these yields a new position vector.
- Obtain the relative position information. Use the transformed Q and K sequences for attention calculation; by expanding the formula, the relative position information can be obtained during the attention calculation.
That is, the attention scores of vector at position and vector at position can be calculated by their dot product. In other words, the difference between the attention scores before and after rotation depends only on their relative positions.
A simplified proof is as follows. Assume… It is a rotation matrix.
Right now
It is an orthogonal matrix that does not change the magnitude of the vector, so it usually does not change the stability of the original model.
1.4 Problems
We currently have several issues worth considering.
- The paper mentions a function . How is implemented?
- Why can this conversion embed the token’s location information?
- Why does this transformation have extrapolation properties? Why is it said to be similar to the concept of trigonometric functions (PE)?
0x02 Principle Derivation
The next step is to find a transformation function such that the identity transformation holds. We will continue our analysis based on the ideas presented in RoFormer’s paper.
2.1 The f() function
First, the process of “adding positional information to the input word embedding and then converting it to q, k, V” is defined as a function , resulting in the following formula:
Secondly, we will conduct an in-depth analysis of the notation in the formula.
- , : The input consists of two-dimensional row vectors at positions and , which are the original word vectors without positional encoding. They are not word embeddings, but token embeddings.
- : The word vector corresponding to the -th token The query vector is generated after integrating the location information .
- : The word vector corresponding to the nth token The key vector is generated after integrating the location information .
- : The word vector corresponding to the nth token The value vector is generated after integrating the location information .
- : Adding positional information to the x vector transforms it into a function of q, k, and v. Transformer-based positional encoding methods primarily focus on constructing a suitable… , , .
As can be seen, the key to the RoPE algorithm lies in how to construct this transformation function , which, while introducing absolute positional information into the word vectors, allows It also contains relative position information. Let’s take a look at the background of .
2.2 Objectives
In this section, we will use a reverse reasoning approach for analysis.
First, let’s look at the goal that expects to achieve. We hope that for . In other words, although the input to this calculation is a vector and And the absolute positions and , but we want the result of this calculation to depend only on the vectors and itself, and vectors and The relative distance between them, without depending on their absolute positions and .
Secondly, for easier derivation, we will introduce a function to perform the derivation. We hope… . The final derived formula for the g function only includes relative distances, omitting the absolute positions and . That is, it assumes the query vector… and key vector The inner product operation between them can be grepresented by a function whose ginput is the word embedding vector. , And their relative positions :
g can be understood as a kernel function that transforms the direct operation of f() (the dot product of semantic information and absolute position information) into an interpretation using g (semantic information plus relative position information). As we will see later, g interprets the dot product using polar coordinates (converting relative distances into angles). See the diagram below for details.

The g function is introduced merely for ease of derivation; the essential goal is still to find an f function, specifically an f() function with desirable properties that incorporates explicit relative positional dependencies into the self-attention formula. In other words, we aim to find an encoding method f() for the q and k vectors such that the encoded vectors… and The dot product can be obtained by , The dot product can be expressed as (the dot product can be represented by word vectors plus relative position information).
2.3 Derivation
Now that we know the target, let’s derive step by step.
Ignoring the absolute positional parameters in the input arguments of , let’s assume that the function simply returns the original token embedding. Here, will… , , The weight matrix operation process is also included.
Let’s see how to gradually add functionality to the initial version of the function above.
Adjust the perspective
We need to adjust our perspective.
From two-dimensional vectors to complex numbers
For simplicity, let’s assume… , It’s a two-dimensional row vector, meaning we first assume the input vector is two-dimensional. For example… It is [a, b]. Since it is two-dimensional, and a complex number is equivalent to a two-dimensional vector on the complex plane, we can consider it as a complex number. Therefore, we… Convert to Why introduce complex numbers? This is because while planar rotations seem intuitive when represented by matrices, they are more elegantly represented by complex numbers.
From complex numbers to polar coordinates
Euler’s formula bridges the gap between exponential functions, trigonometric functions, and complex numbers. Some trigonometric functions are easily solved and understood using exponential form. For example, if represents any real number, is the base of the natural logarithm, and is the imaginary unit in complex numbers, then according to Euler’s formula:
The meaning of this expression is: a complex number with a real part of and an imaginary part of can be represented in an exponential form.
According to Euler’s formula, we can represent the complex number of a two-dimensional vector using polar coordinates.
here:
- Points on the unit circle are described using coordinates in the complex plane. As varies from 0 to , the complex number… It describes a complete circle of the unit circle.
- Points on the unit circle are described by the circular motion of the unit circle. Using the exponential form of complex numbers, we can view complex numbers as unit vectors rotating around the origin in the complex plane.
- for ‘r’ is semantic. It’s a location.
All three representations convey the same message: rotating a two-dimensional vector counterclockwise by an angle That is, a two-dimensional vector It can be treated as a plural number Then multiply This allows rotation to be achieved. From a complex perspective, such a rotation is simply adding an angle to the phase.
therefore, and It can be represented using polar coordinates, that is, using angle + length, which allows us to separate positional information from semantic information.

Next steps
Therefore, we will now take two approaches to see how to think about it from an exponential perspective.
- How can I add absolute position information to the function? This is the result of polar coordinate transformation.
- How can the function interact to transform relative position information into relative position information? This is the function achieved by the De Moivre formula.
Then merge the two routes together.
Introducing absolute position information
According to Euler’s formula, a complex number multiplied by It is equivalent to rotating its corresponding two-dimensional vector counterclockwise. The angle; that is, multiplying by the rotation matrix. Why does RoPE require a rotation operation? Can’t other mappings be used? For example, a linear transformation could map embedding vectors at different positions to new vector spaces. The main reason is that rotation is a linear transformation that doesn’t destroy the original vector’s geometric properties. The length and angle remain unchanged, which is particularly useful for using dot products to measure similarity in attention calculations.
Rotation matrix
Let’s briefly review the concept of a rotation matrix. In two-dimensional space, there exists a rotation matrix. When a two-dimensional vector is multiplied by a rotation matrix on the left, the vector can achieve a rotation of radians. The operation is a counterclockwise rotation. A rotation matrix is a matrix that, when multiplied by another vector, changes the direction of the vector but does not change its magnitude or chirality.
The physical meaning is: Rotate X counterclockwise The specific proof is as follows.
See also the image below.

The main characteristics of a rotation matrix are as follows:
- Preserving the magnitude : Rotation does not change the magnitude (length) of a vector, which is crucial for numerical stability in dot product calculations.
- Maintaining relative angles : Rotation does not affect the angle between two vectors. If vectors 𝑥1 and 𝑥2 have an angle of 𝜃 in space, then after rotation, the angle remains 𝜃. This is especially important for attention mechanisms that measure similarity through the dot product.
- Naturally embedded relative positional relationships : angular difference introduced by rotation The implied distance between positions 𝑝 and 𝑞 is 𝑝−𝑞, and this relationship is directly reflected in the result of the dot product.
There are two other properties of rotation matrices that also need to be noted.
- Orthogonality: The transpose of a rotation matrix is equal to its inverse matrix.
- Additivity: First around the angle Rotate, then around the angle Rotation is equivalent to revolving around an angle. Rotation, i.e. .
Absolute position encoding
The properties of the rotation matrix perfectly satisfy our requirement for encoding absolute position information. After rotating the token embedding around the origin by a certain angle, and this chosen angle being related to the absolute position value (e.g., …), … We introduced angle information into the embedding vector, thus incorporating the absolute position into the function. See the diagram below for details. It is a rotation matrix, and the function represents rotating the vector counterclockwise while preserving its magnitude. This means that by simply rotating a vector by a certain angle, the corresponding absolute position information can be added to that vector.

Let’s explain further:
- 𝜃 is a non-zero constant.
- q is the first dimension of the vector q, and m is the position.
- Give Multiplying by this rotation matrix, geometrically speaking, is equivalent to giving the inverse… The clock hand rotates by a multiple of its index q. This operation only changes the direction and does not change the modulus of q.
For example:
- dog: The word “dog” is in position 0 and does not rotate.
- The dog: The word “dog” is in the first position, rotated by angle .
- The pig chased the dog: the word “dog” is in the 4th position, rotated by an angle of .
- Once upon the time, the ping chased the dong: the word dong is in the 9th position, with a rotation angle of .

Find relative position information
At this point, has the following functionality: From a complex and exponential perspective, by multiplying the vector by a rotation matrix related to its absolute position, it injects absolute position information into the vector, thus obtaining a new… and Let’s examine whether the function is useful, specifically whether it can derive relative position information from absolute position information.
Find the interaction
Let’s first look at how to interact from our current perspective (complex numbers and exponential numbers). The foundation is De Moivre’s theorem: multiplying two complex numbers can be transformed into multiplying the radii of rotation expressed in polar coordinates, and then into adding the rotation angles. Assume… , yes , The radian representation is used. The interaction is as follows.
Find the inner product
However, our goal is This is an inner product, not a multiplication. Further investigation reveals that, according to the properties of complex multiplication, the conjugate of a complex number A (a+bi) multiplied by another complex number B (c+di) results in a product where the real part is equal to the inner product of A and B, and the imaginary part is equal to the outer product of A and B. In other words, the operation of multiplying the conjugate of the first complex number by the second perfectly satisfies the requirements of inner and outer product operations: the inner product takes the real part, and the outer product takes the imaginary part.
ac + bd yes Inside product
ad - bc yes outside product
Note:
- The coordinate representation of a complex number z is z = a + bi, where a is the real part of the complex number, b is the imaginary part of the restatement, and the conjugate of z is a - bi, that is, the real part remains unchanged, and the imaginary part takes its opposite.
- Multiplying two complex numbers is as simple as expanding and multiplying them together. If z1 = a + bi and z2 = c + di, then z1 × z2 = (ac - bd) + (bc + ad)i.
Incorporate location information into the inner product
Next, let’s see how to incorporate absolute position information into the inner product, transforming it into relative position information. In the formula below, <> indicates inner product calculation, ∗ is the conjugate complex number, R[∗] represents the real part of ∗, and the multiplication on the right-hand side is ordinary complex multiplication. The formula means that if we treat two-dimensional vectors as complex numbers, the inner product of two two-dimensional vectors is equal to the real part of the product of the conjugate of one complex number and the other.

summary
The derivation steps are summarized in the following diagram:
- First , Convert to the corresponding complex form , It can also be expressed in polar coordinates;
- By applying rotational transformation, a new complex number form is obtained. , Specifically, it means… , Multiply by respectively , , become , That would be equivalent to giving , With absolute position encoding (explicitly depending on absolute positions , ), we obtain , That is, for The result vector after applying complex multiplication , , that is The vector after matrix rotation.
- The inner product between the query and key is calculated using complex number operations to obtain the result of self-attention. Specifically, because… , It is already plural, we will conjugate multiplied by Taking the real part of the result yields the elements of the RoPE-encoded self-attention matrix. .
We will find that the inner product depends only on the relative position , which cleverly utilizes the property of addition of the arguments of complex numbers to combine the absolute position and the relative position.

and The two vectors initially only have absolute position information, so… and After rotating the two vectors by angles m and n respectively, and then calculating the dot product (allowing the absolute position information to interact), the vector dot product will automatically incorporate the relative position information.
2.4 Formal Definition
Now that the derivation is complete, let’s take a formal look at the interpretation of the and functions, that is, to sort out the above derivation in more detail.
f() introduces absolute information
f() is defined as follows, and can be understood as f() taking two input parameters (absolute position information m and word information) and processing them. The two parts are placed separately on polar coordinates, represented by length and angle respectively.
Let’s deduce it in detail.
first, It is a two-dimensional matrix. It is a two-dimensional vector. The result of multiplication is also a two-dimensional vector. .
Then, Interpreting it as a complex number allows for better subsequent processing, namely, performing the rotation operation through complex number multiplication.
Will It is also represented by a plural number. Indicated on the unit circle, with an amplitude of The vector whose endpoint is… .
therefore,
It means multiplying two complex numbers.
Next, we will re-express as a real vector.
This is essentially the query vector multiplied by a rotation matrix. That is, location information is included, but absolute location information and word information are extracted and placed in two parts of polar coordinates.
See the image below for details.

The above derivation shows that the function f() adds absolute position information to the word embedding. Let’s see how the dot product of f() introduces relative position information, that is, let’s use g() to prove that our constructed f() is correct.
The g() function verifies relative information
What we want to verify is that after obtaining the function f, we construct the query vector using the function f(). and key vector The inner product operation between two vectors can be grepresented by a function whose ginput is the word embedding vector. , And their relative positions . This proves the validity of f(): expressing relative position information through absolute position information. Position information is a high-dimensional vector, represented by polar coordinates. The relative position in polar coordinates is their angle (i.e., rotating from to by a certain angle), thus transforming position information into angular information.
The mathematical formula is as follows.
Known
To demonstrate
Re[x] represents the real part of a complex number x. Representing complex numbers . conjugate.
Next, we will prove… The left and right sides should be equal.
The equation on the right
First, deduce the information inside Re[].
Continue the derivation
The following diagram illustrates this.

left side equation
The equation on the left expands as follows.
As you can see, the left and right sides of the equation are equal. See the diagram below for a more detailed explanation.

Therefore, RoPE has achieved its intended purpose.
- Add absolute position information. Adding absolute position encoding is done by using a rotation matrix, that is, rotating the embedding of each position to a new position using a position-based rotation matrix.
- Obtaining relative position information allows the encoding of two tokens, after undergoing an inner product transformation (self-attn), to be influenced by the difference in their positions, i.e., their relative positions. This means incorporating explicit relative position dependencies into the self-attention formula. and The inner product between them is only determined by and , distance The value is determined by.
High dimension
So far, we’ve discussed two-dimensional vectors, but position encoding is typically high-dimensional vectors. How do we handle this? Instead of attempting to encode all positional information in a single rotation operation, RoPE pairs components within the same dimension and rotates them (or otherwise mixes x and y offset information). By processing each dimension independently, RoPE preserves the natural structure of space and can be generalized to any number of dimensions as needed.
Let’s analyze this carefully.
- First, let’s see how to apply different row transformations to orthogonal subspaces using diagonal matrices. Suppose we have two square matrices A and B, let… . The changes are as follows.
- Secondly, the inner product satisfies the linear superposition property, and any even-dimensional RoPE can be represented as a splicing of two-dimensional cases.
Therefore, we can split each vector (Key or Query) into element pairs, grouping them into pairs based on their two dimensions. , , … Each pair is interpreted as a two-dimensional vector. This divides the original space into independent orthogonal two-dimensional subspaces. Then RoPE uses angles… For each two-dimensional vector (dimension pair) Each subspace is rotated independently, while the other subspaces remain unchanged. The rotation angle is the same as that used in triangular position coding, that is, the sampling frequency. Multiply by the token index (). After rotating, perform the inner product, and then concatenate all the segments to obtain the feature vector containing positional information.
Because each group satisfies a function g (with a relative relationship m-n), when they are added together, they will also satisfy the function g.
here , … The frequency decreases monotonically from 0 to d/2-1, which is a decreasing process, so it can bring about a certain degree of long-range attenuation.
If join and The specifics are as follows:

It is an orthogonal matrix, which does not change the magnitude of the vectors, and therefore generally does not change the stability of the original model. Furthermore, because… Due to the sparsity of the matrix, directly implementing it using matrix multiplication would be computationally wasteful. Therefore, in practice, the calculation method shown in the figure below is recommended. It involves multiplying each digit one by one.

It can be seen that RoPE is somewhat similar to Sinusoidal positional encoding in form, except that Sinusoidal positional encoding is additive, while RoPE can be regarded as multiplicative encoding, that is, it is used to encode the high-dimensional vector of the query at position m. Multiply by matrix This corresponds to the rotation of a vector in each sub-dimension, hence the name Rotation Position Encoding (RoPE). This is because rotations are performed at different angles in independent two-dimensional subspaces. You can imagine it as a counter-clockwise clock system with hour, minute, and second hands, and even finer-grained hands. The earlier the pair, the larger the granularity. In other words, RoPE effectively distinguishes between long-range and short-range operations using trigonometric functions of different frequencies.
We will then use the figures from the paper to illustrate this further.
- For a d-dimensional q vector at position m, we set the word vector size to a multiple of 2, that is, we split it into pairs according to the dimension, and each pair is interpreted as a two-dimensional vector.
- The rotation angle of the i-th group (i.e., the elements 2i and 2i+1 in the vector) is , Related to i and the hidden size of the word vector, it is a function that gradually changes from 1 to close to 0. Therefore, the rotation of the first dimension is faster and the rotation of the later dimension is slower.
- Then rotate each of the split two-dimensional vectors.
- After rotation, all segments are spliced together to obtain a feature vector containing positional information.

2.5 Summary
Sine position encoding is essentially a position encoding method that aims to express relative position using absolute position encoding. However, this capability is compromised due to the presence of the projection matrix. Thus, the sinusoidal position encoding in the original transformer does not actually achieve its intended effect.
The concept of RoPE is somewhat similar to that of sinusoidal position coding. Both attempt to incorporate relative position information during the coding process, utilize trigonometric function transformation formulas for position transformation, and employ the same form of position transformation and rotation on a two-dimensional plane.
The difference between the two is:
-
The trigonometric function PE directly calculates each absolute position vector and then adds the absolute position vector to the token vector during input . In other words, it incorporates positional encoding into the word vector through addition.
-
RoPE performs a rotation after projection and before attention calculation. In other words, RoPE can be seen as transforming the position vector calculated by the trigonometric function PE with the input matrix after passing through the three weight matrices for query and key . It transforms the original query and key vectors into a new vector with positional information, represented by parameters m and θ, where m is the token’s position in the sentence, and θ’s index is directly related to the position of each element in the vector.
Note that rotation cannot be performed before projection, as this would prevent the merging of m and n. It’s likely that RoPE avoids the sinusoidal position encoding problem precisely because rotation is performed after projection. Furthermore, RoPE uses a product-like form similar to the Hadamard product.
-
Due to the properties of trigonometric functions, trigonometric functions (PE) inherently possess the ability to express relative distances. However, RoPE position encoding itself cannot express relative distances and requires the inner product of Attention to activate its ability to express relative distances.

In other words, compared to trigonometric PE, RoPE embeds positional information more deeply into the model structure. Formally, it’s somewhat like multiplicative absolute positional encoding; by applying this positional encoding to q and k, the effect is equivalent to relative positional encoding. Furthermore, if explicit absolute positional information is still needed, this positional encoding can also be applied to v simultaneously.
In Su Shen’s article The Transformer Upgrade Path: 12, ReRoPE with Infinite Extrapolation?, it is pointed out that RoPE is formally an absolute position encoding, but in reality, it brings relative position information to Attention, that is, the Toeplitz matrix as shown below. This form of bias reminds us of ALiBi, which does not act on the embedding but directly on the Attention. Through this construction method, both long-range decay and relative positional relationships are achieved.
In summary, RoPE achieves both absolute and relative positioning effects through operations on absolute positions. This results in a position encoding scheme that integrates both absolute and relative positioning.
In conclusion, the process of combining RoPE’s self-attention operation is as follows:
- First, for
tokeneach word embedding vector in the sequence, calculate its corresponding query and key vectors; - Then, based on the obtained query and key vectors,
tokenthe corresponding rotation position code is calculated for each position; - Next,
tokenapply rotation transformations to the elements of the query and key vectors at each position in pairs. - Finally, the inner product between
queryandkeyis calculated to obtain the result of self-attention. After calculating the inner product, the absolute position information is no longer present, and only the relative position information remains.
Furthermore, RoPE is only applicable to the embedding of queries and keys, not the embedding of values.
0x03 Properties
This section will explore some of the key features of RoPE and industry insights.
3.1 Correlation
Rotation Encoding (RoPE) has the following characteristics:
- When calculating by dot product, the relative positional information of the words is preserved. The absolute position of the words will not change, which effectively maintains the relative relationship of positional information.
- Encodings at adjacent positions exhibit a certain degree of similarity. Even after rotation, adjacent positions will still have similar embeddings. Encodings at greater distances, however, show some differences. This enhances the model’s perception and utilization of positional information.
- Tokens with similar semantics generally receive more attention. That is, when and are similar, regardless of their relative distance , their attention is higher. On average, should be larger, at least larger than for two random tokens.
3.2 Periodicity
Because the arc of one rotation is , vector rotation in RoPE is like a clock, with each component rotating periodically. Because the rotation radius of each component increases linearly with the position index, later components have larger periods and lower frequencies in their sine functions, resulting in slower rotation speeds. The overall frequency can be mapped to both low and high frequencies.
So we have a question: as the position increases, will the rotation angle repeat? The answer is as follows.
- In any -th subspace, as long as the formula for does not contain , there will be no periodic repetition.
- If each subspace does not exhibit periodic repetition, then the whole will not repeat either.
3.3 number system
Su Shen believes that RoPE is a beta encoding, as stated in the original text below.
The Rotation Position Encoding (RoPE) of position n is essentially the beta encoding of the number n!
For a decimal number n, if you want to obtain its m-th digit (counting from right to left) in base beta, the method is…
That is, first divide by , and then find the modulus (remainder). RoPE can be rewritten as…
in, . The most important characteristic of modular arithmetic is periodicity; cosine and sinine are also periodic functions. Therefore, aside from the insignificant difference of the floor function, RoPE (or Sinusoidal positional encoding) is actually the beta encoding of the number n!
3.4 Symmetry
Referring to the properties of trigonometric function encoding, for RoPE encoding, the attentional influence of token A at position on token B at position is the same as the attentional influence of token C at position on token B. Especially when the token at position is the same as the token at position , the following expression holds:
This proves that RoPE encoding also conforms to symmetry and does not learn the difference in direction.
3.5 Frequency Domain
The magnitude of determines the monotonicity of the corresponding dimension and also gives the parameters in these dimensions different learning tendencies. corresponds to the concept of frequency in the Fourier transform.
- When the relative distance is large, the attention calculation results only maintain a consistent monotonicity when the relative distance is small, and then fall into fluctuations, which are essentially high-frequency signals.
- When the relative distance is small, the attention calculation results can still maintain a consistent monotonicity even when the relative distance is large, and the fluctuations are relatively smooth, which is essentially a low-frequency signal.
The paper SCALING LAWS OF ROPE-BASE points out that if using to represent the semantic similarity between the token at position and the token at position , then is a two-dimensional time-domain signal with two time-domain dimensions, and . Semantic similarity consists of semantic similarity components in different frequency domain dimensions. It is composed of combinations, with each dimension corresponding to a frequency band. High-frequency components correspond to local semantic influences, while low-frequency components correspond to long-term contextual semantic influences. The most basic conversion method from the frequency domain to the time domain is the inverse Fourier transform, through Combining components from different frequency bands. Since the goal is to obtain the positional information of position relative to position , the object of the transformation is . The target dimension of the transformation is the diagonal direction of the original two-dimensional time domain, that is, the direction.

The paper Round and Round We Go! What makes Rotary Positional Encodings useful? also reveals the role of different frequency components of RoPE in model learning: high frequency is used for positional attention, and low frequency is used for semantic attention.
We can calculate the wavelength corresponding to each dimension of ROPE.
where is the total number of dimensions, and is the base. The wavelength describes the number of tags required to complete one full rotation in that dimension. The wavelength is related to the frequency of RoPE embedding and may vary in different dimensions.
Given a length , some dimensions may have periods longer than . We can assume that when this happens, all positions receive a unique code, meaning their absolute positions are preserved. Conversely, dimensions with shorter periods only retain relative position information.
3.6 High frequency and low frequency
In RoPE, vector rotation works like a clock because the radius of one full rotation is . Therefore, the rotation of each component is periodic. RoPE rotates at an angle . For each two-dimensional vector (dimension pair) the rotations are performed separately, with the rotation angles taking the same values as the triangular position coding, that is, the sampling frequency multiplied by the token index . After rotating and concatenating all the segments, we obtain a feature vector containing positional information. Here adopts the original sinusoidal position encoding scheme of the Transformer. This can introduce some long-range attenuation. The rotation angle is different at each position.
In periodic functions such as , the larger the value of , the higher the frequency. In RoPE, as the dimension variable increases, decreases, thus reducing the frequency.
We can conclude that lower dimensions of positional encoding correspond to higher frequencies, and higher dimensions correspond to lower frequencies. For each group, its rotation radian increases linearly with the position index. The later the group, the slower its rotation speed, and the larger the period and lower the frequency of the sine function.
- High frequency: This is the position vector of RoPE. When is relatively small (the preceding dimension), and is large, the period is short and the frequency is high.
- Low frequency: This is the position vector of RoPE. is relatively small (in the later dimensions). When is small, the period is long and the frequency is low.
Bowen Peng, the author of NTK-RoPE and YaRN, believes that high-frequency learning captures local relative distances, while low-frequency learning captures long-range absolute distances. Both high and low frequencies are important, and their relationship is more like a hierarchy. In terms of number systems, low frequencies correspond to high-order bits. If only low-order bits are retained and high-order bits are removed, the result is equivalent to taking the modulus (remainder), which cannot accurately represent the positional information.

3.7 Long-distance attenuation
Long-range decay is based on a simple assumption: the greater the relative distance, the lower the correlation and dependence between tokens. If location encoding has long-range decay properties, tokens that are geographically close can receive more attention on average.
Performance
RoPE also exhibits a long-range decay property, specifically: for two word vectors, the closer they are, the higher their inner integral, and vice versa. That is, for the query vector at position , , and the key vector at position , , the greater the relative distance (the larger ), the smaller the value of , and the lower the inner product. As can be seen from the figure below, the inner product result tends to decrease as the relative distance increases.

As can be seen from the graph, significant fluctuations occur in the later stages of the decay curve, resulting in a U-shaped attention pattern. A comparison graph is shown below.

The paper HoPE: A Novel Positional Encoding Without Long-Term Decay for Enhanced Context Awareness and Extrapolation provides a detailed analysis of this, finding that in RoPE, the U-shaped attention pattern is caused by specific learned components, which are also key factors limiting RoPE’s expressive and extrapolation capabilities. See the figure below for details.
(a)indicates that RoPE is decomposed into components (Comps) for analysis. The upper subplot shows the contribution of each component to the overall attention logic. We highlight some components with prominent patterns (“activating” components) in red and low-frequency components in blue. The lower subplot shows the overall attention logic and the combined effect of the “activating” components.(b)The variance (VAF) of different components of RoPE during training is given.(c)It was revealed that the OOD phenomenon in the extrapolation was caused by the “activation” component. The two upper subgraphs show the attention patterns of the first layer, while the lower subgraph shows the anomalous patterns of subsequent layers.

Based on these findings, this paper proposes a novel position encoding method, High-frequency rotary Position Encoding (HoPE). HoPE removes the position-dependent components in RoPE, preserving the high-frequency signal, thus theoretically breaking the principle of long-term attenuation.
Is it possible to design a non-oscillating position code? It’s difficult. If the position code function doesn’t oscillate, it often lacks sufficient capacity to encode enough position information. In other words, in a sense, the complexity of the position code function itself is a requirement for encoding position.
Argument
We will now examine long-range attenuation.
First, let’s look at the derivation from the paper, as shown in the figure below.

Secondly, some researchers believe that the following formula represents the main functional item of RoPE. Transformer position encoding (meaning) Riverside grass lxr
The bias generally decreases monotonically with relative distance . However, the monotonically decreasing overall bias does not necessarily mean that the bias in each dimension decreases monotonically. The magnitude of determines the monotonicity of dimensions , and also gives the parameters in these dimensions different learning tendencies:
- When is small, It is relatively large, tends to 1, and maintains a consistent monotonicity only when the relative distance is small. After that, it falls into fluctuation, inducing the corresponding dimension to characterize the location information of the closer position.
- When is large, It is relatively small, tends to 0, and can maintain a consistent monotonicity even when the relative distance is large, thus inducing the corresponding dimension to characterize the location information of a more distant location.
Conversely, semantic information at different relative positions will also be reflected in different feature dimensions.
- When the relative distance is small, the biases of all dimensions are close to 1, which means that the self-attention distribution pays more attention to information from neighboring positions.
- When the relative distance is large, most dimensions have positive and negative biases that cancel each other out, with only a few dimensions having larger biases. If the semantic features of the corresponding dimensions of two tokens highly overlap, they will be partially emphasized; otherwise, the corresponding self-attention distribution approaches 0. This is a major advantage of relative bias: it does not impose an absolute penalty on semantic associations with large relative distances, but rather provides relative filtering. Although information from larger distances is suppressed through overall bias, semantics on certain feature dimensions are still allowed to converge in the self-attention calculation.
Cardinality
For , the number 10,000 determines the size of K, which we call the base. Different values of base affect the degree of attention decay over distance. Because “fade decay over distance” is key to extrapolation, the properties of base are closely related to the length extrapolation of large models. For example, length extrapolation methods such as NTK-Aware Scaled RoPE, NTK-by-parts, and Dynamic NTK essentially change the base to affect the rotation angle corresponding to each position, thereby affecting the positional encoding information of the model and ultimately achieving the purpose of length extrapolation.
Since the attention values in RoPE, besides and themselves, are only related to , below we observe the characteristics of the factor.
The problem then becomes the asymptotic estimation of the integral . The influence of different base values can be analyzed by calculating the relationship between the integral value and the location distance using the following function.
- With
base=1, the long-range attenuation characteristic is completely lost. - The smaller the base, the faster and larger the decay. Too small a base will disrupt the long-range decay property of attention; for example, when
base=10or100, the attention score no longer shows an oscillating downward trend as the relative position increases. - The larger the base, the slower and smaller the decay. This is why the base needs to be increased when training longer windows. Therefore, the mainstream practice in the industry is to increase the base as the window lengthens to adapt. Apple uses a large base in its models. The longer the input sequence, the larger the base needs to be, forcibly slowing down the decay of an insufficiently trained window, which is also a way to reduce the probability of crashing.
Smoothness
Furthermore, the embedding dimension is positively correlated with the smoothness of the decay curve; the higher the dimension, the smoother the decay curve. The fundamental premise of extrapolation is the “smoothness” of the function. Extrapolation is inferring the whole from the local, relying on the higher-order smoothness of a given function (the existence and boundedness of higher-order derivatives). However, trigonometric function encoding or RoPE does not possess this property. They are combinations of sine and cosine functions, which are high-frequency oscillating functions about the position code , rather than linear or asymptotically linear functions. Therefore, models based on them often exhibit unpredictable extrapolation behavior.
3.8 Extrapolation
Although RoPE can theoretically encode absolute positional information of arbitrary length and generate positional codes exceeding the pre-training length through rotation matrices, and RoPE also exhibits long-distance decay, it still suffers from the length extrapolation problem. For large language models based on RoPE, the model’s performance deteriorates significantly after the test length exceeds the training length, manifested as a sharp increase in language modeling perplexity.
We will write a separate article later to analyze this in detail.
0x04 Implementation
4.1 Basic Torch Knowledge
torch.outer
torch.outer(a, b) calculates the outer product of two 1D vectors a and b, generating a 2D matrix. Each element is calculated as: result[i,j] = a[i] * b[j]. That is, the element in the i-th row and j-th column of the result matrix is equal to the product of the i-th element of vector a and the j-th element of vector b.
The outer product is the matrix generated by the outer product operation of two vectors a and b: A = a ⊗ b. Here, a ⊗ b generates a matrix with the number of rows equal to the number of elements in vector a and the number of columns equal to the number of elements in vector b.
torch.matmul
When the dimension of the input tensor is greater than 2, torch.matmul performs batch matrix multiplication.
torch.polar
The torch.polar() function constructs a complex tensor, used as torch.polar(abs, angle, *, out=None) -> Tensor. Its elements are Cartesian coordinates corresponding to polar coordinates, with the absolute value abs and the angle angle. out = abs * cos(angle) + abs * sin(angle) * j.
torch.repeat_interleave
The torch.repeat_interleave() function returns a repeating tensor with the same dimensions as the input.
torch.view_as_complex
Convert a tensor to its complex form such that the last dimension of the tensor has a shape of 2.
torch.view_as_real
Transforming a complex tensor back into a real tensor can be seen as the inverse transformation of the previous operation.
4.2 Position in Transformer
Unlike the absolute position encoding of the original Transformer, RoPE is located inside the multi-head attention mechanism, directly acting on the query and key of each head to complete the transformation, and each head uses the same RoPE. This also means that RoPE must be added to each layer in the Transformer.
4.3 llama3
In LLaMA, RoPE is implemented using complex number formulas for calculation, . This method is faster, but it is less convenient to modify later.
Specifically, each vector (Key or Query) is split into element pairs based on its two dimensions. , , … Each pair is interpreted as a two-dimensional vector. Then RoPE is used in terms of angles. For each two-dimensional vector (dimension pair) the rotations are performed separately, with the rotation angles taking the same values as the triangular position coding, that is, the sampling frequency multiplied by the token index . After rotating and splicing all the segments, we obtain a feature vector containing positional information.
here . It adopts the original sinusoidal position encoding scheme of the Transformer. This can introduce some long-range attenuation. The rotation angle is different at each position.
overall
The overall code and formula are shown in the figure below.

Before implementing the RoPE algorithm, please note the following: for ease of code implementation, the rotation matrix needs to be converted to polar coordinates before rotation, and the embedding vectors (q, k) need to be converted to complex numbers. After rotation, the rotated embeddings need to be converted back to real numbers for attention calculation.
Prepare rotation matrix
The precompute_freqs_cis() function generates a rotation matrix, which pre-computes the frequencies for a given dimension. is entirely determined by the vector lengths d of Q, K, and V. The position m corresponds to our query length, which in the actual code is determined by the max_position_embeddings parameter, which can be understood as the length of the longest query supported by the model. Therefore, given max, the range of m is also determined. Combining the above information, for an LLM with a fixed longest query length m and vector dimension d, we can pre-construct its corresponding rotation transformation matrix.
The matrix of freqs = torch.outer(t, freqs) is as follows.
By combining this transformation matrix of with cos and sin respectively, we can obtain the transformation matrix of all positions and all dimensions required for our calculation.
The freqs following torch.polar are as follows.
The specific code is as follows.
def precompute_freqs_cis(dim: int, end: int, theta: float = 10000.0):
# 根据维度 d 生成旋转角度θ向量。计算词向量元素两两分组之后,每组元素对应的旋转角度 θ_i,由于是将向量两两旋转应用 RoPE,所以共有 dim/2 个 θ。θ 完全由 Q、K、V 的向量长度 dim 决定
# freqs 长度是 dim/2,一半的维度。2表示是偶数这里 θ 完全由 Q、K、V 的向量长度 d 决定,即 dim维度,取0,2,4...等维度
freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))
# 生成 token 序列索引 t = [0, 1,..., seq_len-1],即拿到所有位置对应的ID,就是论文中常说的m或者n
t = torch.arange(end, device=freqs.device, dtype=torch.float32)
# 计算m * θ。将旋转角度和 `token` 位置索引相乘,即求向量的外积,结果是一个矩阵,该矩阵包含了每个位置和每个维度对应的旋转角度,即每个元素代表位置t在第i维上的旋转角度(频率)
freqs = torch.outer(t, freqs) # freqs的形状是 [seq_len, dim // 2],具体参见上面公式。
# 将上一步的结果写成复数的形式𝑒^{𝑖𝑚𝜃},模是1,幅角是freqs。freqs_cis的大小为(seqlen, dim//2)
# 假设 freqs = [x, y],则 freqs_cis = [cos(x) + sin(x)i, cos(y) + sin(y)i]
freqs_cis = torch.polar(torch.ones_like(freqs), freqs) # complex64
return freqs_cis
The precompute_freqs_cis() function is called as follows.
class Transformer(nn.Module):
def __init__(self, params: ModelArgs):
super().__init__()
self.params = params
self.vocab_size = params.vocab_size
self.n_layers = params.n_layers
self.tok_embeddings = VocabParallelEmbedding(
params.vocab_size, params.dim, init_method=lambda x: x
)
self.layers = torch.nn.ModuleList()
for layer_id in range(params.n_layers):
self.layers.append(TransformerBlock(layer_id, params))
self.norm = RMSNorm(params.dim, eps=params.norm_eps)
self.output = ColumnParallelLinear(
params.dim, params.vocab_size, bias=False, init_method=lambda x: x
)
# 预先计算出来选择矩阵,乘以2是为了动态扩展
self.freqs_cis = precompute_freqs_cis(
params.dim // params.n_heads,
params.max_seq_len * 2,
params.rope_theta,
)
accomplish
The apply_rotary_emb() method applies cosine and sinine rotation matrices to the original query and key vectors, thus introducing positional information into the query and key during the Attention inner product.
# 为了匹配q和k,需要对角度进行扩展
# freqs_cis维度是[seq len, dim/2]
def reshape_for_broadcast(freqs_cis: torch.Tensor, x: torch.Tensor):
ndim = x.ndim
assert 0 <= 1 < ndim
# 需要确保形状和x的形状匹配,即是(x.shape[1]=seq len, x.shape[-1]=dim/2)
assert freqs_cis.shape == (x.shape[1], x.shape[-1])
# x的第二维和最后一维保留,其他维度置为1
shape = [d if i == 1 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)]
return freqs_cis.view(*shape) # [1,S,1,head_dim//2]
def apply_rotary_emb(
xq: torch.Tensor,
xk: torch.Tensor,
freqs_cis: torch.Tensor,
) -> Tuple[torch.Tensor, torch.Tensor]:
"""
作用: 将q,k向量分别与旋转向量相乘,得到旋转后的q,k向量q/k_rotated
输入:
x_q(torch.Tensor): 实际上是权重 W_q * 词嵌入向量值, 来自上一个线性层的输出, 形状为 [batch_size, seq_len, n_heads, head_dim]或者[batch_size, seq_len, dim]
x_k(torch.Tensor): 实际上是权重 W_k * 词嵌入向量值, 来自上一个线性层的输出, 形状为 [batch_size, seq_len, n_heads, head_dim]或者[batch_size, seq_len, dim]
freqs_cis (torch.Tensor): 频率复数张量, 形状为 [max_seq_len, head_dim]
输出: 施加了旋转编码后的q和k
"""
# 实数域张量转为复数域张量。将一个大小为n的向量xq_两两组合形成复数来计算,需要增加维度,把最后一维变成2,即把最后一维的两个实数作为一个复数的实部和虚部来构建一个复数。
# 计算过程q:[batch_size,atten_heads,seq_len,atten_dim]->q_complex:[b,a_h,s,a_d//2,2]->[b,a_h,s,a_d//2]->[b,a_h,s,a_d//2,2]
# [:-1]意思是从第一维到倒数第二维;*是为了展开列表;-1, 2表示把最后一维展开成两维:x/2和2,即最后一维是2;
# xq_.shape = [batch_size,atten_heads,seq_len,atten_dim//2,2],如果不考虑多头,则是[batch_size, seq_len, dim // 2, 2]
xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2)) # 复数形式张量
xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2)) # 复数形式张量
# freqs_cis 的形状必须与 xq 和 xk 相匹配,因此我们需要将 freqs_cis 的形状从 [max_seq_len, head_dim] 调整为 [1, max_seq_len, 1, head_dim]。即,旋转矩阵(freqs_cis)的维度在序列长度(seq_len,维度 1)和头部维度(head_dim,维度 3)上需要与嵌入的维度一致。
freqs_cis = reshape_for_broadcast(freqs_cis, xq_)
# 通过复数乘法实现向量旋转操作,然后将结果转回实数域。这是幅度不变,角度变换的操作,即把结果恢复成原来的样子,将第三维之后压平,也就是(atten_dim//2,2)->(atten_dim)。位置编码只和向量的序列位置还有向量本身有关,和batch以及注意力头无关,所以只用关注第二维和第四维
# xq_out.shape = [batch_size, seq_len, dim]
xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3)
xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3)
return xq_out.type_as(xq), xk_out.type_as(xk) # 又是实数了
Call
The Transformer will call the Transformer layer to perform the RoPE operation.
class Transformer(nn.Module):
@torch.inference_mode()
def forward(self, tokens: torch.Tensor, start_pos: int):
_bsz, seqlen = tokens.shape
h = self.tok_embeddings(tokens)
self.freqs_cis = self.freqs_cis.to(h.device)
freqs_cis = self.freqs_cis[start_pos : start_pos + seqlen]
mask = None
if seqlen > 1:
mask = torch.full((seqlen, seqlen), float("-inf"), device=tokens.device)
mask = torch.triu(mask, diagonal=1)
# When performing key-value caching, we compute the attention scores
# only for the new sequence. Thus, the matrix of scores is of size
# (seqlen, cache_len + seqlen), and the only masked entries are (i, j) for
# j > cache_len + i, since row i corresponds to token cache_len + i.
mask = torch.hstack(
[torch.zeros((seqlen, start_pos), device=tokens.device), mask]
).type_as(h)
for layer in self.layers:
h = layer(h, start_pos, freqs_cis, mask)
h = self.norm(h)
output = self.output(h).float()
return output
TransformerBlock will directly call the forward function of Attention.
class TransformerBlock(nn.Module):
def __init__(self, layer_id: int, args: ModelArgs):
super().__init__()
self.n_heads = args.n_heads
self.dim = args.dim
self.head_dim = args.dim // args.n_heads
self.attention = Attention(args)
self.feed_forward = FeedForward(
dim=args.dim,
hidden_dim=4 * args.dim,
multiple_of=args.multiple_of,
ffn_dim_multiplier=args.ffn_dim_multiplier,
)
self.layer_id = layer_id
self.attention_norm = RMSNorm(args.dim, eps=args.norm_eps)
self.ffn_norm = RMSNorm(args.dim, eps=args.norm_eps)
def forward(
self,
x: torch.Tensor,
start_pos: int,
freqs_cis: torch.Tensor,
mask: Optional[torch.Tensor],
):
h = x + self.attention(self.attention_norm(x), start_pos, freqs_cis, mask)
out = h + self.feed_forward(self.ffn_norm(h))
return out
Attention will perform the following operations.
def forward(
self,
x: torch.Tensor,
start_pos: int,
freqs_cis: torch.Tensor,
mask: Optional[torch.Tensor],
):
bsz, seqlen, _ = x.shape
xq, xk, xv = self.wq(x), self.wk(x), self.wv(x)
xq = xq.view(bsz, seqlen, self.n_local_heads, self.head_dim)
xk = xk.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
xv = xv.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
# attention 操作之前,应用旋转位置编码
xq, xk = apply_rotary_emb(xq, xk, freqs_cis=freqs_cis)
self.cache_k = self.cache_k.to(xq)
self.cache_v = self.cache_v.to(xq)
self.cache_k[:bsz, start_pos : start_pos + seqlen] = xk
self.cache_v[:bsz, start_pos : start_pos + seqlen] = xv
keys = self.cache_k[:bsz, : start_pos + seqlen]
values = self.cache_v[:bsz, : start_pos + seqlen]
# repeat k/v heads if n_kv_heads < n_heads
keys = repeat_kv(
keys, self.n_rep
) # (bs, cache_len + seqlen, n_local_heads, head_dim)
values = repeat_kv(
values, self.n_rep
) # (bs, cache_len + seqlen, n_local_heads, head_dim)
# Q/K/V 对应维度为 [bsz, seq_len, num_heads, head_dim],transpose 将 seq_len 和 num_heads 的维度调换了,得到的 states 维度为 [bsz, num_heads, seq_len, head_dim]。这个变换是为了将 seq_len x head_dim = 4096 x 8 挪到一起,方便后面的 ⊗ 对位相乘。
xq = xq.transpose(1, 2) # (bs, n_local_heads, seqlen, head_dim)
keys = keys.transpose(1, 2) # (bs, n_local_heads, cache_len + seqlen, head_dim)
values = values.transpose(
1, 2
) # (bs, n_local_heads, cache_len + seqlen, head_dim)
scores = torch.matmul(xq, keys.transpose(2, 3)) / math.sqrt(self.head_dim)
if mask is not None:
scores = scores + mask # (bs, n_local_heads, seqlen, cache_len + seqlen)
scores = F.softmax(scores.float(), dim=-1).type_as(xq)
output = torch.matmul(scores, values) # (bs, n_local_heads, seqlen, head_dim)
output = output.transpose(1, 2).contiguous().view(bsz, seqlen, -1)
return self.wo(output)
4.4 rotate_half
rotate_half is a frequently used method in RoPE, and we will analyze it in detail. The function of rotate_half() is to xrotate half of the hidden dimension of the input tensor, that is, to perform semantic vector complexification, which is equivalent to multiplying the vector by the imaginary number i, and rotating the vector counterclockwise by 90 degrees.
Continuing to derive the above formula, by combining cos and sin, we can find that the result after rotation is the result of adding cos to , plus the result of flipping the dimension of , inverting it by one dimension, and then multiplying by sin. This is called rotate_half in the program.
There are actually two ways to implement rotate_half. Let’s look at one of them first. Specifically, it takes the negative of the second half (the imaginary part) of the input tensor and then concatenates it with the first half (the real part) to achieve the rotation operation. The process is as follows:
- Tensor Segmentation: Assuming the input tensor
xhas the shape[batch_size, num_attention_heads, seq_len, head_size], the function first segments the tensorxinto two parts:x1andx2.x1contains the first half, andx2contains the second half. - Rotation operation: Negate
x2, then concatenatex2withx1. In this way, the latter half of the original tensor is rotated to the position of the former half, achieving the rotation effect. - Concatenation: Finally, the negative
x2andx1are concatenated on the last dimension to form the final rotation position embedding tensor.
The specific code is as follows.
# 后半部分和前半部分进行了交换,并且将后半部分的符号取反。
# 这个函数很好理解,就是将原始向量从中间劈开分为 A、B 两份,然后拼接为 [-B, A] 的状态:比如 [q0,q1,q2,q3,q4,q5,q6,q7] -> [-q4,-q5,-q6,-q7,q0,q1,q2,q3]
def rotate_half(x):
"""Rotates half the hidden dims of the input."""
# 前64个embedding位置 x=[batch_size, num_heads, seq_len, emb_size] => [batch_size, num_heads, seq_len, emb_size/2]
x1 = x[..., : x.shape[-1] // 2]
# 后64个embedding位置 x=[batch_size, num_heads, seq_len, emb_size] => [batch_size, num_heads, seq_len, emb_size/2]
x2 = x[..., x.shape[-1] // 2 :]
# 后64embedding位置取负号,和前64embedding位置拼接
return torch.cat((-x2, x1), dim=-1)
def apply_rotary_pos_emb(q, k, cos, sin, position_ids=None, unsqueeze_dim=1):
cos = cos.unsqueeze(unsqueeze_dim)
sin = sin.unsqueeze(unsqueeze_dim)
q_embed = (q * cos) + (rotate_half(q) * sin)
k_embed = (k * cos) + (rotate_half(k) * sin)
return q_embed, k_embed
Substitute rotate_half() into apply_rotary_pos_emb(), for example, with q=[x1, x2]:
q_embed = [x1, x2] * cos + [-x2, x1] * sin = [x1 * cos - x2 * sin, x2 * cos + x1 * sin]
See the diagram below for details. The negative sign here corresponds to the negative sign in the sum-of-the-angle formula. Calculate the twist angle. The process is omitted here.

However, the code above is an implementation of HuggingFace’s Transformer library, which differs slightly from the formula in the RoPE paper. Specifically, the difference lies in the arrangement of the elements. In the paper, q0 is the result of the pair of elements q0 and q1 transformed using trigonometric functions, but in the actual formula, q0 is derived from q0 and q_{d/2+1}. This pair was formed.
- HuggingFace:
- paper:
The specific approximation is as follows.

In fact, this involves two different implementations of splitting the feature dimensions.
Following the approach outlined in the RoPE paper, it follows the GPT-J style. The implementation performs a rotate_half operation on the odd and even dimensions of the feature vectors, grouping adjacent dimensions together (⊙ indicates multiplication of corresponding bits). The operation on is the same.
Because rotating odd and even dimensions requires pairwise interleaving of dimensions, which is quite complex, later researchers proposed directly halving the feature dimension. This implementation is called the GPT-NeoX style, which involves performing a rotate_half operation on the first and second halves of the feature vector. The GPT-J style and the GPT-NeoX style are equivalent and can be converted to each other: the odd-numbered dimensions in the GPT-J style correspond to the first half of the dimensions in the GPT-NeoX style, and the even-numbered dimensions in the GPT-J style correspond to the second half of the dimensions in the GPT-NeoX style. Extracting the odd-numbered dimensions from the GPT-J style and concatenating them before the even-numbered dimensions yields the result of the GPT-NeoX style.
The two implementations differ only in their corresponding R matrices; both ultimately achieve the goal of encoding relative positions from absolute positions. This has no impact on the final result. RoPE’s modification of the original vector essentially involves performing rotation matrix operations on element-wise pairs and concatenating all pairs. Whether consecutive elements are chosen as a pair or any other selection method is acceptable, as long as the embedding dimension is even and the selection strategy involves non-repeating pairs. Ultimately, the inner product result of Attention will perceive relative positional information because Attention satisfies the linear superposition property of the inner product. Which elements are paired together is irrelevant.
GPT-J sytle
Just like the original paper and blog, it uses two adjacent pairs as a group.
GPT-NeoX style
Instead of grouping adjacent elements together, it uses 0 and… As a group.
The FlashAttention source code implements RoPE for GPT-J style and GPT-NeoX style.
https://github.com/Dao-AILab/flash-attention/blob/main/flash_attn/layers/rotary.py
def rotate_half(x, interleaved=False):
if not interleaved:
x1, x2 = x.chunk(2, dim=-1)
return torch.cat((-x2, x1), dim=-1)
else:
x1, x2 = x[..., ::2], x[..., 1::2]
return rearrange(torch.stack((-x2, x1), dim=-1), '... d two -> ... (d two)', two=2)
def apply_rotary_emb_torch(x, cos, sin, interleaved=False):
"""
x: (batch_size, seqlen, nheads, headdim)
cos, sin: (seqlen, rotary_dim / 2)
"""
ro_dim = cos.shape[-1] * 2
assert ro_dim <= x.shape[-1]
cos = repeat(cos, 's d -> s 1 (2 d)')
sin = repeat(sin, 's d -> s 1 (2 d)')
return torch.cat([x[..., :ro_dim] * cos + rotate_half(x[..., :ro_dim], interleaved) * sin, x[..., ro_dim:]], dim=-1)
0xFF Reference
- Base of RoPE Bounds Context Length Xin Men etc.
- Positional Encoding in Transformers during the LLM Era (MrYXJ)
- LLM (23): The Long Text Problem in LLM (Auspicious Purple Qi from the East)
- Interpreting the Rotation Position Encoding (RoPE) implementation in LLaMA qwdjiq
- Long LLM Part 2 – Why RoPE? ( by Wang Yan)
- ROUND AND ROUND WE GO! WHAT MAKES ROTARY POSITIONAL ENCODINGS USEFUL?
- RedHerring RedHerring
- RoPE extrapolation scaling rules – attempting to extrapolate RoPE to a 1M context ( by riverside grass lxr)
- RoPE Rotation Position Encoding Depth Analysis: Theoretical Derivation, Code Implementation, and Length Extrapolation (JMXGODLZ)
- Transformer Position Encoding (Basic) by Riverside Grass lxr
- Transformer Position Encoding (Improved) by Riverside Grass lxr
- Transformer Upgrade Path: 10. RoPE is a beta encoding.
- Transformer Upgrade Path: 15. Key Normalization Aids Length Extrapolation ( Su Jianlin)
- The Transformer Upgrade Path: 16. “Reviewing” the Length Extrapolation Technique
- The Transformer Upgrade Path: 2. Rotary Position Encoding: Drawing on the Strengths of Various Approaches
- Improved Relative Position Encoding (RPE) for Transformers - Taylor Wu
- https://arxiv.org/pdf/2104.09864.pdf
- Line-by-line analysis of llama source code for bookname
- QWen Source Code Analysis 3 - Understanding the QWenAttention Model’s Calling Programmer
- The transformers library provides an implementation of llama rope.
- Chinese Language Model Research: (1) Multiplicative Positional Encoding PENG Bo
- Background knowledge of positional encoding algorithms Zhang
- Qwen2 beta/1.5 model code line by line analysis (Part 1)
- A Brief Discussion on LLM Length Extrapolation
- In-depth analysis of the principles of large-scale models — Qwen Blog
- Xianyu Intelligence: [OpenLLM 009] Position Encoding: A Comprehensive Explanation of Position Encoding and Length Extrapolation in LLM (Part 1)
- Xianyu Intelligence: [OpenLLM 010] Position Encoding: A Comprehensive Explanation of Position Encoding and Length Extrapolation in LLM (Part 2)
- Transformer position encoding that has researchers racking their brains - Scientific Spaces
- LLM: A Simple Explanation of Rotational Position Encoding (RoPE) ( Lotus Seed)
- Effective Long-Context Scaling of Foundation Models
- HoPE: A Novel Positional Encoding Without Long-Term Decay for Enhanced Context Awareness and Extrapolation