Transformers and language models
The transformer block
A modern decoder block is pre-norm, attention, residual, pre-norm, MLP, residual. The residual stream is the highway. Sublayers read it and write an additive update.
Self-attention is one sublayer. A transformer block wraps it with a norm, a residual add, an MLP and another residual add. Stack L of those blocks and you have the body of a decoder-only LLM.
Concept
The residual stream is a running d-dimensional highway. Each attention and MLP reads a normed view of the stream and writes an additive update. Information that should persist can ride the residual.
The big idea
A modern Llama-style block (one layer) looks like:
h = h + Attention(RMSNorm(h))
h = h + MLP(RMSNorm(h)) # MLP often SwiGLUThat is pre-norm: normalize, then sublayer, then residual add. Post-norm (norm after the add) was the 2017 default. Pre-norm trains more stably at depth.
RMSNorm scales by the root-mean-square of the vector (no mean centering, unlike LayerNorm):
RMSNorm(x) = x / RMS(x) * γ
RMS(x) = sqrt(mean(x²) + ε)γ is a learned per-channel scale (d parameters per norm). See normalization layers.
Without residuals, stacking 32 nonlinear layers tends to destroy gradient signal. Residuals make each layer learn a refinement F(h) added to h, so the identity path carries gradients. See residual connections.
Walking through SwiGLU
Classic transformer FFN: σ(x W₁) W₂ with d_ff ≈ 4 d. Llama-style SwiGLU uses a gated linear unit:
SwiGLU(x) = (Swish(x W_gate) ⊙ (x W_up)) W_downThree matrices instead of two. To keep parameter count similar to a 4d FFN, width is often set near d_ff ≈ (8/3) d (rounded to a multiple of 256). Most parameters in a dense transformer live in these MLPs. They are a natural place for mixture of experts to sparsify.
Modern stacks often drop attention biases and sometimes MLP biases entirely. SwiGLU gates are not optional decorations. They are first-class parameters in the W_gate matrix. Norm γ vectors are tiny in count but critical for scale.
Karpathy's nanoGPT is small enough to hold in your head:
wte/wpe— token and (absolute) position embeddings. GPT-2 style, not RoPE.h— a list of blocks. Each block is LayerNorm → causal attention → residual → LayerNorm → MLP → residual (pre-norm).- MLP — expand 4× with GELU, project back (not SwiGLU).
- Final LayerNorm plus linear LM head. Optional weight tying with
wte.
Then compare to a Llama implementation: swap in RMSNorm, RoPE, SwiGLU, and maybe grouped-query attention.
Width (d) buys richer residual streams and bigger MLPs. Depth buys more serial computation inside one forward pass. Frontier recipes grow both roughly together.
Common mistakes
- Removing residuals and expecting depth to train. It usually will not.
- Copying GPT-2 GELU MLP math onto a Llama config. SwiGLU has three matrices and a different width.
- Forgetting norm
γat export. Generation breaks in ways that look like sampler bugs.
Check yourself
- Write the two residual updates in a Llama-style block. Answer:
h = h + Attention(RMSNorm(h))thenh = h + MLP(RMSNorm(h)). - Why is SwiGLU width often near
(8/3) drather than4d? Answer: Three matrices instead of two.(8/3) dkeeps parameter count close to a classic 4d FFN.
Key takeaways
- Pre-norm plus residual is why deep stacks train.
- The residual stream is the highway. Sublayers read and write additives.
- RMSNorm is LayerNorm without mean centering.
- SwiGLU is a gated MLP with three matrices. Most dense parameters live there.
Further learning
Next: parameter and FLOP counts.
Related
The transformer architecture
Every component of a modern decoder-only LLM, from embeddings to the LM head, with parameter and FLOP counts.
Embeddings and rotary positions
A token id becomes a vector from a table. Attention has no sense of order unless you inject position, and RoPE does that by rotating queries and keys.
Self-attention
The operation at the core of every modern language model. Each position builds a weighted average of the others, with weights set by query-key matches.