Unit 2.6 · about 6 h
302 / 324The modern decoder block: residuals, RMSNorm and SwiGLU
Attention mixes positions; the feed-forward network transforms each position, and residual additions preserve the model width. Normalization placement and initialization change how a deep stack carries signals and gradients.
- explain
- implement
You can now
- Explain the pre-norm residual stream and contrast its gradient path with post-norm.
- Implement per-token RMSNorm, a bias-free SwiGLU feed-forward network and both residual sublayers.
- Contrast LayerNorm with RMSNorm and a two-matrix GELU FFN with three-matrix SwiGLU.
- Distinguish component initialization from depth-dependent residual-projection scaling and state the chosen recipe.
Covers
- Residual stream and pre-norm decoder blocks
- LayerNorm versus RMSNorm
- GELU, gated feed-forward blocks and SwiGLU
- Initialization and residual-scale vocabulary
Study, in this order
4 steps
- Normalization, gating and norm placementModern LLM Notebook - decoder construction path
Component Upgrades: LayerNorm and RMSNorm hand calculations, RMSNorm full implementation, The SwiGLU gating mechanism, Full SwiGLU FFN implementation, and Post-Norm versus Pre-Norm comparison
Depth · Read the formulas and code. Skip the eight-layer gradient demonstration; a single random example is not a general stability proof.
- GELU FFN baselineLLMs from Scratch companion - attention and GPT construction
Section 4.3, Implementing a feed forward network with GELU activations
- Initialization and modern block specificationsStanford CS336 Assignment 1 - model contract
Section 3.3.1, Parameter Initialization, printed p. 17; section 3.4 through 3.4.2, printed pp. 19 to 22; section 3.5 through problem (
transformer_block), printed p. 26 - Depth-scaled residual initializationnanoGPT - residual projection initialization
MLPandBlockclasses;GPT.__init__fromself.apply(self._init_weights)through thec_proj.weightinitialization loop;GPT._init_weightsDepth · Use this as a contrasting GPT-2 recipe, not a replacement for the CS336 test architecture. Skip pretrained loading, optimizer setup and generation.
Focus on
- Write \(y=x+\operatorname{Attn}(\operatorname{RMSNorm}(x))\), then \(z=y+\operatorname{FFN}(\operatorname{RMSNorm}(y))\). Normalize the branch input, not the residual sum; final stack normalization comes later.
- LayerNorm subtracts the feature mean and divides by feature standard deviation. RMSNorm divides by \(\sqrt{\operatorname{mean}(x^2)+\mathrm{eps}}\), without centering, and uses one learned gain per feature.
- SwiGLU is \(W_{\mathrm{down}}(\operatorname{SiLU}(W_{\mathrm{gate}} x) \odot (W_{\mathrm{up}} x))\). Its gate is not bounded to \([0, 1]\). Three bias-free matrices cost \(3DF\) parameters; a two-matrix GELU FFN costs \(2DF\) at the same hidden width.
- CS336 specifies truncated-normal component weights and unit RMSNorm gains. nanoGPT instead uses base \(\mathrm{std}=0.02\) and residual-projection \(\mathrm{std}=0.02/\sqrt{2L}\); that scales initial branch weights, not the residual identity path.
Reproduce closed-book
Traps
- Normalizing across tokens instead of the feature axis. That couples positions and can leak future information even when attention is causal.
- Squaring low-precision activations before upcasting. Overflow has already happened; accumulate RMS statistics in
float32first. - Copying the notebook's explanation that a SwiGLU gate is a probability. SiLU can be negative or exceed one; the sigmoid factor alone is bounded.
Practice
CS336 Assignment 1: `rmsnorm` and `positionwise_feedforward`
Problems (rmsnorm) and (positionwise_feedforward), sections 3.4.1 and 3.4.2; implement run_rmsnorm, run_silu and run_swiglu and pass test_rmsnorm, test_silu_matches_pytorch and test_swiglu
CS336 Assignment 1: `transformer_block`
Problem (transformer_block), section 3.5; implement run_transformer_block and pass test_transformer_block
Add your own zero-branch identity and gradient test, zero-input RMSNorm test and a test showing that changing another token cannot change this token's norm or FFN output.
Self-test
-
For \(x=[1, 3, 5, 7]\), unit gains and negligible \(\epsilon\), how do LayerNorm and RMSNorm differ?
LayerNorm gives \([-3, -1, 1, 3]/\sqrt{5}\), before any affine shift. RMSNorm gives \([1, 3, 5, 7]/\sqrt{21}\), whose mean is not zero. -
Why does SwiGLU often use \(F\) near \(8D/3\) instead of \(4D\)?
Three matrices give \(3DF\) weights. Setting \(F=8D/3\) matches the \(8D^2\) weights of a two-matrix FFN with hidden width \(4D\), before rounding or biases. -
What is the clean gradient path supplied by \(x+f(\operatorname{norm}(x))\)?
Its Jacobian includes an identity term plus the branch Jacobian. Unlike post-norm, the residual identity contribution does not pass through a normalization Jacobian; this is not a guarantee against every training instability. -
In nanoGPT, why are both attention and
MLPc_projweights scaled with layer count?Both project branch outputs back into the residual stream. With two residual branches per layer, the recipe reduces their initial standard deviation by \(\sqrt{2L}\) to limit accumulation across depth.
Completion criterion
Stop when
All four named public tests pass, the zero-branch block passes output and input-gradient identity checks, and you explain norm placement, gating and your initialization recipe without notes.
Mark passed, then open 2.7 Only mark this when you can do it without notes.Leads to
- 2.7 Assembling and verifying a decoder Stack these blocks and add the final norm and vocabulary head.
- 3.4 Keeping training numerically healthy Track activation and gradient behavior during training.
Comes after
- 2.5 RoPE: positions as rotationsInsert rotary attention into the pre-norm residual block.
Resources for this unit
- Modern LLM Notebook - decoder construction path Work through English notebooks 03-embedding, 04-position-encoding, 05-transformer-block, 06-mini-gpt and the selected normalization, RoPE, GQA and SwiGLU comparisons in 08-gpt2-to-modern-models. Re-derive shapes and rerun with changed dimensions.
- LLMs from Scratch companion - attention and GPT construction Use the ch03 attention notebooks and ch04 model code. Rebuild the model without a high-level Transformer module and compare one forward and backward path with an independent small reference.
- Stanford CS336 Assignment 1 - model contract Use the named linear, embedding, rmsnorm, positionwise_feedforward, rope, softmax, scaled_dot_product_attention, multihead_self_attention, transformer_block, transformer_lm and transformer_accounting specifications and public tests. Keep implementation independent and respect the course AI and honor-code boundary.
- nanoGPT - residual projection initialization Read
model.py:MLP,Block,GPT.__init__'s special scaled initialization ofc_proj.weight, andGPT._init_weights. Contrast the depth-dependent residual initialization with CS336's component initialization; do not adopt the training or generation code.
Also in this section
- PyTorch scaled dot product attention reference Use the functional contract only after the explicit attention oracle passes. Transfer identical weights and masks, compare outputs and gradients, and explain dtype, causal and dropout behavior from the documented semantics.
- Deep-ML candidate - three transformer closing drills After the platform quality sample passes, attempt at most problems 490, 53 and 904 as changed-prompt drills for attention shapes and multi-head composition. Preserve independent tests; a judge result does not replace the section checkpoint.