Part 3 of 82 min read

Layer Normalization

A technique that stabilizes training by making the next layer's input scale independent of how large the values from earlier layers grew. It runs identically in training and at inference.

LLMGPTlayer normalizationfundamentalsplayground
r50k_baseprivate

Layer normalization rewrites one token's vector using nothing but that vector: subtract the vector's own mean, divide by its own standard deviation, then multiply by a learned gain and add a learned bias, one of each per dimension.

What it computes

LayerNorm(x)=γxμσ2+ϵ+β\text{LayerNorm}(x) = \gamma \odot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta

xx is one token's row, d components wide. μ\mu and σ2\sigma^2 are that row's own mean and variance — the variance divided by d rather than by d − 1, which is unbiased=False in PyTorch and what GPT-2 was trained with. The fraction is the row standardized: mean 0 and variance 1, whatever arrived. γ\gamma and β\beta are the learned gain and bias, applied componentwise.

Three details in the arithmetic are worth naming:

  • The statistics are the token's own, so a token's output never depends on what else is in the batch or the sequence, and training and inference compute the same thing. This is the contrast with batch normalization, which normalizes across the batch and is not used in transformers.

  • eps guards the division. A token vector whose components are all equal has variance 0, and without eps the division would be by zero. GPT-2 uses ϵ=105\epsilon = 10^{-5}, PyTorch's default.

  • gain and bias are the only trainable parameters, d of each: one pair per dimension, shared by every token in the sequence and every sequence in the batch. They start at 1 and 0, where the layer is standardization and nothing more. Training moves them, so the output rows stop having mean 0 and variance 1. That is intended: standardizing fixes the scale and the offset of what leaves, and the pair then lets training pick a scale and an offset per dimension rather than inheriting whatever the input carried.

Why it matters

Switching between X_small and X_big changes the layer's input magnitude and offset; the gain and bias from the section above stay at 1 and 0 here.

The two branches are the same rows forty times apart in magnitude, each with its own offset, and layer normalization gives the same output for both — up to the eps under the square root, which does not scale with the rows and whose effect the readout prints. However large or small the values arriving have become, the next layer sees rows at the same scale, so its gradients neither explode nor vanish with them.

References

Sebastian Raschka, Build a Large Language Model (From Scratch) (Manning, 2024). Section 4.2 implements the layer in PyTorch, which the code exported above follows. It names the two parameters scale and shift; this chapter uses Ba et al.'s gain and bias instead.

Jimmy Lei Ba, Jamie Ryan Kiros and Geoffrey E. Hinton, Layer Normalization (2016). The paper the method comes from.

Search

Search pages, articles, and resources