ALiBi › The Mathematical Formulation

Michael BrenndoerferUpdated May 30, 202512 min read
Language AI HandbookAll chapters
Part 14 of 67Positional Encoding
Chapter 101ALiBi › The Mathematical Formulation
Reading section 4 of 16 · The Mathematical Formulation · 12 minSection 4 of 16 · 12 min

Book contents

Section 4 of 16 · 12 min read

ALiBi › The Mathematical FormulationOne section · Sections in this chapter4 / 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 that we understand ALiBi's core insight, let's develop the complete mathematical framework. We will build from standard attention to ALiBi-augmented attention, showing exactly where and how the position bias enters the computation.

Standard attention and ALiBi attention are nearly identical. The only difference is one additional term added to the score matrix before the softmax. This surgical simplicity is part of what makes ALiBi attractive: it requires minimal changes to an existing attention implementation and adds almost no computational overhead.

Starting Point: Standard Scaled Dot-Product Attention

Recall that standard self-attention operates on three matrices derived from the input sequence. For a sequence of nn tokens, the attention mechanism computes:

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

where:

  • Q∈Rn×dkQ \in \mathbb{R}^{n \times d_k}: the query matrix containing query vectors for all nn positions
  • K∈Rn×dkK \in \mathbb{R}^{n \times d_k}: the key matrix containing key vectors for all positions
  • V∈Rn×dvV \in \mathbb{R}^{n \times d_v}: the value matrix containing value vectors for all positions
  • dkd_k: the dimension of queries and keys
  • QKT∈Rn×nQK^T \in \mathbb{R}^{n \times n}: the raw attention score matrix where entry (i,j)(i, j) is the dot product between query ii and key jj
  • dk\sqrt{d_k}: scaling factor that prevents dot products from growing too large in high dimensions, which would push the softmax into regions of very small gradients

The matrix QKTQK^T captures content-based similarity: how much each query "wants" to attend to each key based purely on their learned representations. This matrix is completely blind to position. Token 1 attending to token 2 produces the same content-based score whether they appear next to each other or 500 positions apart. This is by design for the core attention mechanism, which wants to capture global relationships. But it means we need another mechanism to introduce positional awareness. That mechanism is the ALiBi bias.

Why does ALiBi add bias at this stage rather than modifying the queries and keys? Adding to the pre-softmax scores is the most direct possible intervention. The scores are the raw votes about which tokens matter. By adjusting the scores before normalization, we influence the attention distribution in a clear and simple way. Modifying queries and keys (as RoPE does) achieves a similar effect but through a more complex indirect path involving embedding geometry.

Injecting Position: The Bias Matrix

ALiBi's modification is surgical. Rather than changing how queries, keys, or values are computed, it adds a single term to the attention scores. The complete ALiBi-augmented attention reads:

Attention(Q,K,V)=softmax(QKTdk+B)V\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}} + B\right)V

The bias matrix B∈Rn×nB \in \mathbb{R}^{n \times n} is added directly to the scaled scores before softmax. This is the only change to standard attention. The matrix BB encodes position information through a remarkably simple rule: each entry is determined entirely by the distance between the corresponding positions. Specifically,

Bij=−m⋅∣i−j∣B_{ij} = -m \cdot |i - j|

where:

  • BijB_{ij}: the bias added to the attention score between query position ii and key position jj
  • mm: the slope parameter for this attention head, controlling the strength of the distance penalty
  • ∣i−j∣|i - j|: the absolute distance between positions ii and jj in the token sequence

Let's unpack why this formula works. The absolute distance ∣i−j∣|i - j| measures how far apart two positions are in the sequence. Adjacent tokens have distance 1, tokens separated by 10 positions have distance 10. Multiplying by a positive slope mm and negating creates a penalty that grows linearly with distance. A token that is close gets a small penalty; a token that is far gets a large penalty.

Consider what happens for a query at position 5 attending to various keys:

  • Attending to position 5 (itself): B55=−m⋅0=0B_{55} = -m \cdot 0 = 0 (no penalty, full score preserved)
  • Attending to position 4 (adjacent): B54=−m⋅1=−mB_{54} = -m \cdot 1 = -m (small penalty)
  • Attending to position 3 (two steps away): B53=−m⋅2=−2mB_{53} = -m \cdot 2 = -2m (moderate penalty)
  • Attending to position 0 (distant): B50=−m⋅5=−5mB_{50} = -m \cdot 5 = -5m (large penalty)

The negative bias reduces the attention score, and larger distances produce more negative biases. After softmax normalization, this translates to lower attention weights for distant tokens. The content-based similarity in QKTQK^T still matters completely: a very semantically relevant distant token can overcome its distance penalty if its dot product score is large enough. But now content has to compete against a structural penalty that favors proximity.

Why does this formula make sense? Notice that the formula simply implements a universal assumption that language models hold implicitly: nearby context tends to be more relevant than distant context. Rather than forcing the model to learn this bias from data (which is expensive and may lead to overfitting on long-range spurious correlations), ALiBi builds it in as an inductive bias. The model is free to override it with strong content signals, but the default behavior is local attention. This is similar to how convolutional neural networks build in a translation-invariance inductive bias, rather than forcing the network to learn that from scratch.

The Causal Case: Masking the Future

For decoder-style models that generate text left-to-right, we need causal masking: position ii can only attend to positions j≤ij \le i. The combined bias matrix integrates both the ALiBi distance penalties and the causal mask:

B=[0−∞−∞−∞⋯−m0−∞−∞⋯−2m−m0−∞⋯−3m−2m−m0⋯⋮⋮⋮⋮⋱]B = \begin{bmatrix} 0 & -\infty & -\infty & -\infty & \cdots \\ -m & 0 & -\infty & -\infty & \cdots \\ -2m & -m & 0 & -\infty & \cdots \\ -3m & -2m & -m & 0 & \cdots \\ \vdots & \vdots & \vdots & \vdots & \ddots \end{bmatrix}

The structure reveals two distinct components working together. The lower triangle, including the diagonal, contains the ALiBi distance penalties. Entry (i,j)(i, j) with j≤ij \le i holds the value −m⋅(i−j)-m \cdot (i - j), which is zero on the diagonal and grows more negative as you move left along any row. The upper triangle holds −∞-\infty values from the causal mask.

The −∞-\infty entries ensure that after applying exp⁡(−∞)=0\exp(-\infty) = 0 inside the softmax, future positions contribute nothing to the weighted sum. The linear penalties in the lower triangle then shape how attention flows among the allowed past positions. These two components operate in entirely different regimes: the causal mask is a hard prohibition (zero weight, always), while the ALiBi penalty is a soft preference (lower weight, but nonzero).

Notice that the causal mask interacts naturally with ALiBi. For a model processing position ii, the only tokens it can attend to are positions 0 through ii. These are exactly the tokens for which j≤ij \le i, so the distance is always i−ji - j, always positive, and always measured in the backward direction. The ALiBi penalty is therefore always a backward-looking decay, consistently favoring the most recent tokens in the context.

Building the Bias Matrix: Step-by-Step Implementation

Let's translate this mathematics into code, building up the bias matrix piece by piece. The core insight behind the implementation is that we can compute all pairwise distances simultaneously using broadcasting, rather than iterating over all pairs with nested loops.

In[3]:
Code
import numpy as np


def create_alibi_bias(seq_len, slope):
    """
    Create the ALiBi bias matrix for a single attention head.

    Args:
        seq_len: Length of the sequence
        slope: The slope parameter m for this head

    Returns:
        Bias matrix of shape (seq_len, seq_len)
    """
    # Create position indices
    positions = np.arange(seq_len)

    # Compute pairwise distances: |i - j|
    # positions[:, None] is (seq_len, 1), positions[None, :] is (1, seq_len)
    # Broadcasting gives (seq_len, seq_len)
    distances = np.abs(positions[:, None] - positions[None, :])

    # Apply linear penalty
    bias = -slope * distances

    return bias

The key implementation insight is using NumPy broadcasting to compute all pairwise distances at once. By reshaping the position array into a column vector positions[:, None] and a row vector positions[None, :], subtraction produces an n×nn \times n matrix where entry (i,j)(i, j) is i−ji - j. Taking the absolute value gives us the distance matrix. Multiplying by the slope and negating gives the penalty matrix. This vectorized approach is both faster and more readable than explicit loops.

Let's see what this produces for a small sequence:

Out[4]:
Console
ALiBi bias matrix for sequence length 6, slope 0.5:
[[-0.  -0.5 -1.  -1.5 -2.  -2.5]
 [-0.5 -0.  -0.5 -1.  -1.5 -2. ]
 [-1.  -0.5 -0.  -0.5 -1.  -1.5]
 [-1.5 -1.  -0.5 -0.  -0.5 -1. ]
 [-2.  -1.5 -1.  -0.5 -0.  -0.5]
 [-2.5 -2.  -1.5 -1.  -0.5 -0. ]]

Reading this matrix: the diagonal is zero because a token attending to itself has distance zero and receives no penalty. Moving away from the diagonal in either direction, penalties grow linearly. Position 5 (row 5) attending to position 0 (column 0) shows −2.5-2.5, which is exactly −0.5×5-0.5 \times 5 as expected. The matrix is symmetric because distance is symmetric: ∣i−j∣=∣j−i∣|i - j| = |j - i|. In a causal model we will only use the lower triangle, but the full symmetric matrix is the natural output of the distance computation.

For decoder models, we overlay the causal mask on top of the distance penalties:

In[5]:
Code
def create_causal_alibi_bias(seq_len, slope):
    """
    Create ALiBi bias with causal masking.

    Args:
        seq_len: Length of the sequence
        slope: The slope parameter m

    Returns:
        Bias matrix with -inf for future positions
    """
    # Start with the distance-based bias
    bias = create_alibi_bias(seq_len, slope)

    # Create causal mask (upper triangle should be -inf)
    causal_mask = np.triu(np.ones((seq_len, seq_len)), k=1)

    # Apply causal mask: future positions get -inf
    bias = np.where(causal_mask == 1, -np.inf, bias)

    return bias

The np.triu function creates an upper triangular matrix of ones, which we use to identify positions that should be masked. The k=1 argument excludes the diagonal, since a token should be able to attend to itself. The np.where call then replaces those positions with negative infinity, which becomes effectively zero after the exponential in softmax.

Out[6]:
Console
Causal ALiBi bias matrix:
[[-0.  -inf -inf -inf -inf -inf]
 [-0.5 -0.  -inf -inf -inf -inf]
 [-1.  -0.5 -0.  -inf -inf -inf]
 [-1.5 -1.  -0.5 -0.  -inf -inf]
 [-2.  -1.5 -1.  -0.5 -0.  -inf]
 [-2.5 -2.  -1.5 -1.  -0.5 -0. ]]

Now the upper triangle shows inf (NumPy's display for −∞-\infty), while the lower triangle retains the distance penalties. Row 5 can attend to all previous positions with penalties −2.5,−2.0,−1.5,−1.0,−0.5,0.0-2.5, -2.0, -1.5, -1.0, -0.5, 0.0 for positions 0 through 5 respectively. Row 0 can only attend to itself with penalty 0, since there are no previous positions available.

Let's visualize both the distance matrix and the resulting causal ALiBi bias matrix side by side to make the structure visually clear:

Out[7]:
Visualization
Heatmap of distance matrix with values increasing symmetrically away from the diagonal.
Distance matrix showing absolute distances between all position pairs. Entry (i, j) contains |i - j|. The matrix is symmetric with zeros on the diagonal and values increasing as positions diverge.
Heatmap of causal ALiBi bias matrix showing negative values in the lower triangle and masked upper triangle.
Causal ALiBi bias matrix with slope 0.5. The distance matrix is negated and scaled to produce penalties, then the upper triangle is masked with negative infinity to prevent attending to future positions.

The left matrix shows raw distances: the diagonal is 0 (same position), adjacent cells are 1, and values grow as positions diverge. The right matrix shows what happens after applying ALiBi: distances become negative penalties (scaled by the slope), and the upper triangle is masked to enforce causality. This visual makes clear that the bias matrix is nothing more than a scaled, negated distance matrix with causal masking applied on top.