AI Grimoire
Sheet
statusstale
difficultyintroductory
timeO(n·d)
memoryO(L·d) parameters
described2018
revisedtoday

Learned Absolute Position Embeddings

Stop deriving the encoding and simply learn it: one trainable vector per position, added to the token embedding. Trivial to implement, and it stops dead at the end of the table.

Standing

StaleLoad-bearing for understanding how the field arrived here, and replaced in practice by something on this list. Worth reading, not worth reaching for.

Gone from language models, where the hard context ceiling is disqualifying. Still routine in vision transformers, which know their input size in advance.

judged as of 2026-09 · what the labels mean

Theory

If the sinusoidal table is a guess at what position should look like, the learned table is a refusal to guess. Allocate L×dL \times d parameters, index by position, add to the token embedding, and let gradient descent decide.

hp(0)=Emb(xp)+Pp,PRL×dh^{(0)}_p = \mathrm{Emb}(x_p) + P_p, \qquad P \in \mathbb{R}^{L \times d}
eq. 1 — the whole method

BERT did this, GPT-2 did this, and ViT still does. It performs no worse than sinusoids on any benchmark where both were tried — Vaswani et al. reported the same, and chose sinusoids anyway on the untested hope that they would extrapolate.

The ceiling is structural

PP has LL rows. Position LL has no row. There is no natural value to fall back on, no continuation of a formula, no reasonable default — the model simply cannot be evaluated there. This is why GPT-2 is a 1024-token model in a way that is not a matter of degree: the failure at 1025 is a missing parameter, not a degraded one.

What the table learns

Probing trained tables finds less structure than the parameter count suggests. The dominant component is smooth and low-frequency — neighbouring positions get neighbouring vectors — with the first few positions sitting well apart from everything else, which is the same sink phenomenon seen from the embedding side. Beyond that the table is largely a monotone curve through a handful of dimensions, which is a costly way to encode a scalar.

That observation is the case for the relative schemes. If what the model needs is mostly offset, and the absolute index is a means to it, then encoding the offset directly is both cheaper and unbounded.

Implementation

python · torch
import torch
from torch import Tensor, nn


class LearnedPositions(nn.Module):
    def __init__(self, max_len: int, dim: int):
        super().__init__()
        self.table = nn.Embedding(max_len, dim)
        # Small init: position must not dominate content at step zero.
        nn.init.normal_(self.table.weight, std=0.02)

    def forward(self, x: Tensor) -> Tensor:                   # [B, T, D]
        t = x.size(1)
        if t > self.table.num_embeddings:
            raise ValueError(f"{t} tokens exceeds the {self.table.num_embeddings}-row table")
        pos = torch.arange(t, device=x.device)
        return x + self.table(pos)

The explicit raise matters more than it looks. Indexing past the table in PyTorch is a device-side assert that surfaces as an opaque CUDA error several operations later, usually attributed to whatever kernel happened to run next.

Where it survives

Vision keeps it because the objection does not apply: a ViT knows its patch grid at configuration time, and changing resolution is a deliberate act during which the table can be interpolated on the grid. Text has no such structure — token 900 is not spatially between token 899 and 901 in any sense that survives interpolation — so language models moved to rotary embeddings and never came back.

BERT-base, 512×768
0.39 M
GPT-2, 1024×1600
1.6 M
Beyond L
undefined
Parameter cost of the table alone

Related

References

[1]Devlin et al. — BERT: Pre-training of Deep Bidirectional Transformers (2018)arXiv:1810.04805
[2]Radford et al. — Language Models are Unsupervised Multitask Learners (2019)GPT-2
[3]Dosovitskiy et al. — An Image is Worth 16x16 Words (2020)arXiv:2010.11929