YaRN › The Complete YaRN Formula
Language AI HandbookAll chapters YaRN › The Complete YaRN FormulaOne section · Sections in this chapter8 / 16 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
Now we can put together the complete YaRN transformation. Given a model trained on context length that we want to extend by factor , the process involves three coordinated steps. Each step builds on the previous one, and together they constitute the full YaRN algorithm.
Step 1: Compute adjusted frequencies
For each dimension pair with base frequency and wavelength , compute the wavelength ratio and the adjusted frequency:
where:
- : the adjusted frequency for dimension pair
- : the original RoPE frequency
- : the ramp function defined in the previous section
- : the wavelength ratio that determines the amount of interpolation for this dimension
This step is performed once at initialization and the adjusted frequencies are stored. During inference, every query and key vector is rotated using rather than . The computational cost is identical to standard RoPE; only the frequency values change.
Step 2: Apply RoPE with adjusted frequencies
For query or key vector at position , apply the block-diagonal rotation matrix using the adjusted frequencies. Each pair of dimensions is rotated by angle :
where:
- : the rotated vector, incorporating YaRN's frequency adjustments
- : a rotation matrix for angle , applied to dimension pair
- : the rotation angle at position , increasing linearly with position at the adjusted rate
- The block-diagonal structure means each dimension pair is rotated independently of all others
The rotation matrix for angle is:
This is the standard 2D rotation matrix. Applying it to a pair gives:
Because rotation is an isometry (it preserves vector lengths), YaRN-RoPE does not change the magnitude of query or key vectors. It only changes their direction, which is all that matters for computing dot products.
Step 3: Apply temperature scaling to attention scores
After computing the raw attention scores from the rotated query and key vectors, apply the temperature correction before softmax:
where:
- : the temperature-scaled attention score between positions and
- : the YaRN-rotated query vector at position
- : the YaRN-rotated key vector at position
- : the dimension of key vectors (the standard prevents dot products from growing too large)
- : the temperature factor, computed once from the extension scale
- : the multiplier applied to raw scores, increasing the spread of scores to counteract entropy inflation
- This scaling occurs before the softmax normalization, not after
class YaRNRoPE:
"""YaRN-adjusted Rotary Position Embedding."""
def __init__(
self,
d_model,
original_context=2048,
scale=4.0,
base=10000,
alpha=1.0,
beta=32.0,
):
"""Initialize YaRN RoPE.
Args:
d_model: Embedding dimension (must be even)
original_context: Original training context length
scale: Context extension factor
base: RoPE frequency base
alpha: Lower wavelength threshold
beta: Upper wavelength threshold
"""
self.d_model = d_model
self.original_context = original_context
self.scale = scale
self.alpha = alpha
self.beta = beta
# Compute adjusted frequencies
self.original_freqs = compute_rope_frequencies(d_model, base)
self.wavelengths = compute_wavelengths(d_model, base)
self.gamma_values = np.array(
[
yarn_gamma(w, original_context, scale, alpha, beta)
for w in self.wavelengths
]
)
self.adjusted_freqs = self.original_freqs * self.gamma_values
# Compute temperature factor
self.temperature = compute_yarn_temperature(scale)
def apply(self, x, position):
"""Apply YaRN-adjusted RoPE to a vector.
Args:
x: Input vector of shape (d_model,)
position: Position index
Returns:
Rotated vector of shape (d_model,)
"""
return apply_rope(x, position, self.adjusted_freqs)
def apply_batch(self, x):
"""Apply YaRN-adjusted RoPE to a batch of vectors.
Args:
x: Input tensor of shape (seq_len, d_model)
Returns:
Rotated tensor of shape (seq_len, d_model)
"""
seq_len, d = x.shape
positions = np.arange(seq_len)
# Compute all rotation angles
angles = np.outer(positions, self.adjusted_freqs)
cos_angles = np.cos(angles)
sin_angles = np.sin(angles)
x_pairs = x.reshape(seq_len, -1, 2)
x_rotated = np.stack(
[
x_pairs[:, :, 0] * cos_angles - x_pairs[:, :, 1] * sin_angles,
x_pairs[:, :, 0] * sin_angles + x_pairs[:, :, 1] * cos_angles,
],
axis=-1,
)
return x_rotated.reshape(seq_len, d)
def scale_attention(self, scores):
"""Apply temperature scaling to attention scores.
Args:
scores: Attention scores of shape (seq_len, seq_len)
Returns:
Scaled scores
"""
return scores * np.sqrt(self.temperature)Let's test the complete YaRN implementation:
# Create YaRN module
yarn = YaRNRoPE(d_model=64, original_context=2048, scale=4.0)
# Test with random input
seq_len = 32
test_input = np.random.randn(seq_len, 64)
# Apply YaRN RoPE
rotated = yarn.apply_batch(test_input)YaRN Configuration: Original context: 2048 Extension scale: 4.0x Extended context: 8192 Temperature: 1.1386 Attention scale: sqrt(t) = 1.0671 Input shape: (32, 64) Output shape: (32, 64) Magnitude preserved: True
The implementation confirms that YaRN preserves vector magnitudes (rotation is an isometry) while applying the adjusted frequencies. The extended context (8,192 positions) is 4x larger than the training context (2,048 positions), and the temperature correction of approximately 1.067 will be applied to attention scores before softmax.