Position Encoding Comparison › Extrapolation Benchmarks

Michael BrenndoerferUpdated June 2, 202511 min read
Language AI HandbookAll chapters
Part 14 of 67Positional Encoding
Chapter 102Position Encoding Comparison › Extrapolation Benchmarks
Reading section 3 of 12 · Extrapolation Benchmarks · 11 minSection 3 of 12 · 11 min

Book contents

Section 3 of 12 · 11 min read

Position Encoding Comparison › Extrapolation BenchmarksOne section · Sections in this chapter3 / 12 ↓
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

The most visible difference between position encoding methods appears when models encounter sequences longer than their training length. This scenario is increasingly common: models trained on 2K or 4K context windows must often process documents with 8K, 16K, or even longer sequences. How gracefully does each method handle this extrapolation?

Setting Up the Comparison

We'll simulate extrapolation by creating position encodings for a sequence twice as long as the "training" length and observing how the representations behave at unseen positions.

In[3]:
Code
import numpy as np

# Configuration
train_length = 512  # Maximum position seen during training
test_length = 1024  # We'll evaluate up to this position
embed_dim = 64  # Dimension of position vectors
d_k = embed_dim  # Dimension for queries/keys

Let's implement each position encoding method and examine its behavior at extrapolated positions.

In[4]:
Code
def sinusoidal_encoding(max_len, d_model):
    """
    Generate sinusoidal position encodings.
    Follows the original Transformer paper formula.
    """
    positions = np.arange(max_len)[:, np.newaxis]  # (max_len, 1)
    dimensions = np.arange(d_model)[np.newaxis, :]  # (1, d_model)

    # Wavelengths from 2*pi to 10000*2*pi
    wavelengths = 10000 ** (2 * (dimensions // 2) / d_model)

    # Apply sin to even dimensions, cos to odd dimensions
    encodings = np.where(
        dimensions % 2 == 0,
        np.sin(positions / wavelengths),
        np.cos(positions / wavelengths),
    )
    return encodings


def learned_embedding(max_len, d_model, rng=None):
    """
    Simulate learned position embeddings.
    In practice, these would be learned during training.
    """
    if rng is None:
        rng = np.random.default_rng(42)
    # Initialize with small random values (simulating learned embeddings)
    return rng.standard_normal((max_len, d_model)) * 0.02
In[5]:
Code
def rope_encoding(positions, d_model):
    """
    Compute RoPE rotation angles for given positions.
    Returns the cos and sin components for rotation.
    """
    # Frequencies decrease exponentially with dimension pair
    freqs = 1.0 / (10000 ** (np.arange(0, d_model, 2) / d_model))

    # Outer product: position * frequency
    angles = positions[:, np.newaxis] * freqs[np.newaxis, :]  # (len, d_model/2)

    cos_vals = np.cos(angles)
    sin_vals = np.sin(angles)

    return cos_vals, sin_vals


def alibi_bias(query_len, key_len, num_heads=8):
    """
    Compute ALiBi attention bias matrix.
    Returns bias to be added to attention scores.
    """
    # Slopes: geometric sequence from 2^(-8/n) to 2^(-8)
    slopes = 2 ** (-8 * np.arange(1, num_heads + 1) / num_heads)

    # Distance matrix: query_pos - key_pos
    query_pos = np.arange(query_len)[:, np.newaxis]  # (Q, 1)
    key_pos = np.arange(key_len)[np.newaxis, :]  # (1, K)
    distances = query_pos - key_pos  # (Q, K)

    # Bias for each head: -slope * |distance|
    # Shape: (num_heads, Q, K)
    biases = -slopes[:, np.newaxis, np.newaxis] * np.abs(distances)

    return biases, slopes

Measuring Representation Quality at Extrapolated Positions

For sinusoidal encoding, extrapolation is mathematically guaranteed to work because the formula applies to any position. For learned embeddings, we have no representation at all for unseen positions. For RoPE, the rotation angles continue following the same pattern. For ALiBi, the linear bias extends naturally.

In[6]:
Code
# Generate encodings for both training and test lengths
sinusoidal_train = sinusoidal_encoding(train_length, embed_dim)
sinusoidal_test = sinusoidal_encoding(test_length, embed_dim)

learned_train = learned_embedding(train_length, embed_dim)
# Learned embeddings have NO representation for extrapolated positions
# We'd need to either: interpolate, extrapolate heuristically, or fail

# RoPE continues naturally
positions_train = np.arange(train_length)
positions_test = np.arange(test_length)
rope_cos_train, rope_sin_train = rope_encoding(positions_train, embed_dim)
rope_cos_test, rope_sin_test = rope_encoding(positions_test, embed_dim)

# ALiBi bias extends naturally
alibi_train, alibi_slopes = alibi_bias(train_length, train_length)
alibi_test, _ = alibi_bias(test_length, test_length)

Before examining extrapolation, let's visualize how each method structures position information across the embedding dimensions. These heatmaps reveal the fundamental patterns each method uses to encode position.

Out[7]:
Visualization
Heatmap showing sinusoidal position encoding patterns with wave-like structure.
Sinusoidal encoding shows its characteristic multi-frequency wave pattern across 128 positions and 64 dimensions.
Heatmap showing learned position embeddings as random noise before training.
Learned embeddings appear as random noise (unstructured initialization) before training.
Heatmap showing RoPE cosine components with frequency patterns similar to sinusoidal.
RoPE displays similar frequency patterns to sinusoidal, using cosine rotation components.
Heatmap showing ALiBi bias values with triangular linear decay pattern.
ALiBi shows uniform linear decay, operating on attention scores rather than embedding space.

The heatmaps reveal fundamental differences in how each method encodes position. Sinusoidal and RoPE show structured wave patterns with different frequencies across dimensions, enabling the model to capture both fine-grained (nearby positions) and coarse (distant positions) relationships. Learned embeddings start as random noise and must discover useful structure during training. ALiBi operates in a different space entirely, showing the triangular bias pattern that penalizes attention to distant keys.

Let's visualize how each method's representations look at both trained and extrapolated positions.

Out[8]:
Visualization
Line plot showing sinusoidal encoding values continuing smoothly beyond training boundary.
Sinusoidal encoding continues its periodic patterns seamlessly into the extrapolation region (512-1023).
Line plot showing learned embeddings stopping at training boundary with gray extrapolation region.
Learned embeddings have no representation for unseen positions, shown as the gray out-of-bounds region.
Line plot showing RoPE cosine components continuing smoothly beyond training boundary.
RoPE rotation angles continue according to the same exponentially-decaying frequency schedule.
Line plot showing ALiBi bias growing linearly beyond training boundary.
ALiBi's linear bias grows predictably with distance, making it naturally suited for extrapolation.

The extrapolation behavior differs dramatically between methods. Sinusoidal encoding continues its periodic patterns into the extrapolation region, with each frequency component oscillating according to its fixed formula. RoPE shows the same behavior: rotation angles continue according to the same exponentially-decaying frequency schedule. ALiBi's linear bias grows predictably, applying stronger penalties to more distant positions regardless of whether those distances were seen during training.

Learned embeddings, however, have a fundamental problem: they simply don't exist for unseen positions. The gray region in the plot represents a complete absence of positional information. Various workarounds exist (position interpolation, extrapolation via linear projection), but none match the clean mathematical extension of formula-based methods.

Quantifying Extrapolation Quality

Beyond visual inspection, we can measure extrapolation quality by examining whether the relative position relationships remain consistent. Good extrapolation should preserve the property that nearby positions have similar representations and that relative distances remain meaningful.

In[9]:
Code
def compute_relative_similarity(encodings, query_pos, max_distance=100):
    """
    Compute cosine similarity between a query position and nearby positions.
    Returns similarities at each relative distance.
    """
    query_vec = encodings[query_pos]
    similarities = []

    for dist in range(max_distance):
        key_pos = query_pos + dist
        if key_pos < len(encodings):
            key_vec = encodings[key_pos]
            # Cosine similarity
            sim = np.dot(query_vec, key_vec) / (
                np.linalg.norm(query_vec) * np.linalg.norm(key_vec) + 1e-8
            )
            similarities.append(sim)
        else:
            similarities.append(np.nan)

    return np.array(similarities)


# Compare relative similarity patterns at trained vs extrapolated positions
trained_query = 256  # Well within training range
extrap_query = 768  # In extrapolation region

sinusoidal_sim_trained = compute_relative_similarity(
    sinusoidal_test, trained_query
)
sinusoidal_sim_extrap = compute_relative_similarity(
    sinusoidal_test, extrap_query
)
Out[10]:
Visualization
Line plot comparing cosine similarity decay from query positions 256 and 768, showing nearly identical patterns for sinusoidal encoding.
Relative similarity patterns at trained (position 256) vs. extrapolated (position 768) query positions. For sinusoidal encoding, the similarity decay pattern is nearly identical at both positions. This shows that relative position relationships are preserved during extrapolation.

The nearly identical curves show that sinusoidal encoding preserves relative position relationships during extrapolation. Position 768 "looks at" its neighbors in the same way that position 256 does. This consistency is what allows models with sinusoidal or RoPE encoding to generalize, with appropriate scaling adjustments, to longer sequences.

Position Similarity Matrices

Another way to understand position encoding quality is through pairwise similarity matrices. These show how similar any two positions are in the encoding space, revealing whether relative relationships are preserved.

Out[11]:
Visualization
Heatmap showing cosine similarity matrix for sinusoidal position encodings with banded diagonal pattern.
Sinusoidal encoding shows the distinctive Toeplitz-like structure where similarity depends primarily on relative distance.
Heatmap showing cosine similarity matrix for learned position encodings with random structure.
Learned embeddings (random init) show no structure, with near-zero similarity everywhere except the diagonal.

The sinusoidal similarity matrix displays the characteristic banded structure where similarity depends on the relative distance between positions, not their absolute values. This Toeplitz-like property (constant values along diagonals) is what enables position-invariant pattern learning. The learned embeddings, in contrast, show near-zero similarity everywhere except the diagonal. This reflects their random initialization. During training, learned embeddings would develop task-specific similarity structure.