Normalization

Before each attention layer and each MLP, the model rescales the token’s vector to a standard size. LayerNorm subtracts the mean and divides by the standard deviation; RMSNorm just divides by the root mean square. Where the norm sits, before the layer or after it, decides whether a deep model trains.

Key idea
LayerNorm = (x − mean) ÷ std × γ + β; RMSNorm = x ÷ rms × γ; pre-norm keeps the residual path clean
Real world
Grading on a curve. A raw mark of 72 means little until you know the class average was 60 and the spread was 8. Converting every mark to “1.5 spreads above average” makes marks from a hard exam and an easy exam comparable.
In an LLM
GPT-2’s residual vector for “ is” has length 5 at the bottom and 430 at the top. Each layer reads it through a LayerNorm, so every layer sees numbers of the same scale, and the final norm shrinks it back to about 255 before the prediction.

Why normalise

The residual stream keeps growing: every layer adds to it. If each layer read the raw vector, the early layers would see vectors of length about 55 and the late ones vectors several times longer (in GPT-2 small, from about 55 to about 430: see the chart on the previous page), and every layer would need weights tuned to its own scale. Worse, during training the scale shifts as earlier layers change, so later layers would be chasing a moving target.

The fix is to rescale each token’s vector to a standard size before a layer reads it. The layer always sees numbers of roughly the same size, however long the stream has grown.

LayerNorm

takes one token’s vector xx with dd numbers and does three things:

  1. Subtract the mean. μ=1d∑ixi\mu = \frac{1}{d}\sum_i x_i. After this the numbers average to zero.
  2. Divide by the standard deviation. σ=1d∑i(xi−μ)2\sigma = \sqrt{\frac{1}{d}\sum_i (x_i - \mu)^2}. After this they have spread 1.
  3. Scale and shift. Multiply each number by a learned gain γi\gamma_i and add a learned bias βi\beta_i.
LayerNorm⁡(x)i=xi−μσ2+ϵ γi+βi\operatorname{LayerNorm}(x)_i = \frac{x_i - \mu}{\sqrt{\sigma^2 + \epsilon}}\,\gamma_i + \beta_i

The tiny ϵ\epsilon (usually 10−510^{-5}) stops a division by zero. The gain and bias let the model put back any scale it actually needs, per dimension. Each token is normalised on its own: no information moves between tokens.

is the cheaper version that most models now use. It skips the mean and the bias:

RMSNorm⁡(x)i=xi1d∑jxj2+ϵ γi\operatorname{RMSNorm}(x)_i = \frac{x_i}{\sqrt{\frac{1}{d}\sum_j x_j^2 + \epsilon}}\,\gamma_i

Drag the bars and watch both at work:

× γ + β
input x (drag the bars) · dashed line: mean 1.20
output after “× γ + β” · mean 0.17
output mean0.17
output std1.09
output rms1.10
Multiply each number by its learned gain γ and add its learned bias β. The model learns these to undo the normalisation where it needs to.
γ = [1.0, 0.6, 1.4, 1.0, 0.8, 1.2, 1.0, 0.5] β = [0.0, 0.3, 0.0, −0.4, 0.0, 0.2, 0.0, 0.0]
Drag the bars on the left to change the input. The right panel shows the output at the current stage. Then try the scale and shift sliders, and switch between LayerNorm and RMSNorm.

Two things to try. Move the scale slider: the input bars grow or shrink, the output does not change at all. That is the point of normalising: the size of the input no longer matters, only its shape. Then move the shift slider: LayerNorm ignores it (it subtracts the mean), RMSNorm does not (it never removes the mean). Zhang and Sennrich, 2019 showed that the re-centring step barely matters in practice, so RMSNorm gets the same quality with fewer operations. Llama, Mistral, Qwen and Gemma all use it.

example · grading on a curve

A class sits two exams. On the hard one the marks are 40, 48, 55, 61; on the easy one 70, 78, 85, 91. The raw numbers can’t be compared. Subtract each exam’s average and divide by its spread, and both become about −1.4, −0.4, +0.5, +1.3: the same students did equally well relative to their class. LayerNorm does this to the 768 numbers of a token’s vector, so every layer sees “how much above or below average is each dimension” rather than raw sizes.

example · GPT-2’s growing stream

At the last token of “The capital of France is”, GPT-2 small’s residual vector has length 55 after the first layer and 430 before the output. The LayerNorm in front of each layer turns both into vectors of the same length (the square root of 768, about 28, before the gain is applied). Without it, a layer reading the 430-long vector instead of the 55-long one would see numbers about 8 times bigger, so its attention scores (dot products of two such vectors) would come out roughly 60 times bigger, which would push its softmax into saturation.

Pre-norm or post-norm

There are two places to put the norm. The original Transformer (Vaswani et al., 2017) normalised after adding each sub-layer’s output: post-norm, x←LN⁡(x+f(x))x \leftarrow \operatorname{LN}(x + f(x)). GPT-2 moved it to the start of each branch: , x←x+f(LN⁡(x))x \leftarrow x + f(\operatorname{LN}(x)).

main residual pathLayerNormattentionMLP
LayerNorms on the main path0 (+1 at the end)
additions on the main path48
In pre-norm each sub-layer normalises its own copy of the input, and the main path only ever has things added to it. A signal (or a gradient on the way back) can travel through all 24 layers untouched. That is why deep pre-norm models train stably, often without a careful warm-up.
One transformer block drawn both ways. Purple is the main residual path from the block’s input to its output. In pre-norm it is a clean line with only additions on it; in post-norm every sub-layer’s LayerNorm sits on it.

The difference looks small but matters a lot for deep models. In pre-norm the main path from the input to the output has nothing on it but additions, so the gradient flows straight down it (the identity path from the residual stream). In post-norm the gradient must pass through a LayerNorm at every sub-layer, and each one rescales it. Xiong et al., 2020 showed that post-norm gradients near the output are large at the start of training, which is why post-norm models need a slow learning-rate warm-up and still often diverge when they are deep.

Pre-norm has one side effect: since nothing on the main path normalises it, the stream grows with depth (you saw this in GPT-2). So pre-norm models add one final norm after the last block, before the output layer.

QK-norm

Some recent models (Gemma 3, OLMo 2, Qwen 3) add one more norm inside attention: they apply RMSNorm to every query and key vector before the dot product. This caps how large the attention scores can get, which stops a failure in large-scale training where a few scores grow without limit, softmax becomes one-hot, and the loss spikes. It is a small, cheap change: two extra norms per layer.

going deeper

In code

def layer_norm(x, gamma, beta, eps=1e-5):          # x: (..., d)
    mu = x.mean(-1, keepdim=True)
    var = ((x - mu) ** 2).mean(-1, keepdim=True)    # biased variance
    return (x - mu) / torch.sqrt(var + eps) * gamma + beta
 
def rms_norm(x, gamma, eps=1e-5):
    return x / torch.sqrt((x ** 2).mean(-1, keepdim=True) + eps) * gamma

After normalising (before γ\gamma), a dd-dimensional vector has RMS 1, so its length is d\sqrt{d}: about 27.7 for d=768d = 768.

Parameters

Each norm has dd gains (and dd biases for LayerNorm). GPT-2 small has 25 LayerNorms × 2 × 768 = 38,400 parameters in norms, 0.03% of the model.

In papers

Related

  • residual-stream - Every token carries one vector up through the model. Each attention layer and each MLP reads that vector, computes something, and adds the result back. Nothing is overwritten. This running sum is the residual stream, and it is why deep transformers can be trained at all.
  • the-block - Put the pieces together: LayerNorm, attention, add; LayerNorm, MLP, add. That is one transformer block, and a model is a stack of identical blocks between an embedding table and an output layer. Here is one block computed number by number, and an exact parameter count for real models.
  • mlp - After attention has moved information between tokens, the MLP processes each token on its own: widen the vector four times, bend it with an activation function, narrow it back. Its neurons act like key–value memories, and it holds most of the model’s parameters.