Autoregressive models: the chain rule, MADE, PixelCNN and transformer language models
Before this lesson: lesson 01 (maximum likelihood is a forward KL; a VAE gives only a bound on , here it is exact); cross-entropy from the information-theory track; convolutional networks and attention with masks from the deep-learning track. Time: about 70 minutes, plus the notebook.
Why this matters #
A VAE (lesson 02) gives only a lower bound on . An autoregressive (AR) model gives the exact value, and it trains with nothing more than cross-entropy. This one idea powers GPT-style language models (next-token prediction), WaveNet for raw audio, PixelCNN for images, and the token models that generate the codes of a VQ-VAE. In science, most learned weather emulators are autoregressive in time: GenCast samples the next state of the atmosphere given the previous two and feeds the result back in. The cost structure of this lesson (cheap training, sequential sampling) and its failure mode (errors that build up over a long rollout) apply to all of them.
1. Predict first #
2. The picture #
The chain rule with two bits #
Take two binary variables . Every joint distribution of them can be written as
So three numbers describe it completely: , and . This is the chain rule of probability. There is no assumption yet: it holds for every distribution. For variables it reads
where is the prefix of .
A tree is the picture. Draw one level per variable. Each edge carries a conditional probability. The probability of a full outcome is the product of the edges on its path from the root to its leaf.
Move the sliders to change the seven conditional probabilities of three binary variables. The bars are the eight joint probabilities (one per leaf); their sum stays exactly 1. In evaluate mode, pick an : its three factors light up together in yellow, because all of them can be read from the data at once. Switch to sample and press Next step: now each factor needs the result of the step before. Last, switch on the leak and watch the sum become 2.
Two directions of use.
- Evaluate for an observed . Every conditional is known, because its inputs are part of the data. All factors can be computed in parallel.
- Sample a new . Draw , then given that , and so on. Step needs the result of step , so this is sequential. It is called ancestral sampling.
Where the modeling happens. With binary variables, a full table of the joint needs numbers: about for a tiny binary image. An AR model replaces each conditional table by a neural network, for example with the sigmoid. Three choices matter: the order of the variables, the family of each conditional (Bernoulli, a 256-way softmax over pixel values, a mixture of logistics, a Gaussian), and the network.
One network for all conditionals. To get all conditionals in one pass, a single network produces outputs, and output must never see . Masks do this. MADE masks the weights of an MLP, PixelCNN masks the convolution kernels, and a transformer masks the attention matrix. Section 3 builds each one.
Two bits with , and . What is ?
Follow the path in the tree: . The value is the probability of ; uses the conditional of the wrong branch.
A 2D example: two moons by counting #
Discretize the plane into a grid. Let be the column of a point and its row. The chain rule gives , and for discrete variables the maximum-likelihood estimate of each factor is a table of relative frequencies: count the points in each column, and in each cell of the column.
Click a column of the two-moons picture. The top chart is , one bar per column; the bottom chart is the conditional of the selected column. Press Sample: each orange point takes two sequential steps, a column from , then a row from . With smoothing the model gives probability 0 to every empty cell; a larger spreads some mass there.
This model has free numbers: exactly as many as a full table of the 1024 cells, because with full tables the chain rule is not an approximation. That is fine for a small grid but impossible for an image. A neural AR model shares parameters across the conditionals; the counting model is the same idea without sharing.
3. Definitions and main results #
The autoregressive property #
Fix an order . An autoregressive model is a set of conditionals , , such that:
- for every value of , is a normalized distribution over ;
- (autoregressive property) the parameters of factor are a function of only.
The model is .
Theorem (an autoregressive model is normalized). For discrete , . (For continuous , replace the sums by integrals.)
Why this is true. Sum out the last variable first. Only the last factor contains it, and that factor sums to 1. What is left is the same model with one variable less.
Proof. Induction on . For , by condition 1.
- In , factor depends only on (condition 2). So only the last factor contains .
- Move next to the last factor: by condition 1.
- What remains is the same sum for variables, which is 1 by induction.
Why condition 2 matters. Take and let the "conditional" see itself: . Then and . The training log-likelihood is perfect (0 nats), but : this is not a distribution. In the proof, step 2 fails: the last factor now depends on also through its parameters, so its sum over is no longer 1. A leak of into factor shows up as a training loss that is too good to be true.
You train a MADE on binary images. After a few hundred steps the training loss is nats per pixel, and samples look like noise. What is the most likely cause?
A loss of exactly 0 means the model predicts every pixel with certainty. Real images are not that predictable from the earlier pixels, but they are from the pixel itself. A leak makes "copy the input" possible, and the leaky model is not normalized, so its samples are meaningless. Overfitting lowers the loss slowly and keeps the model normalized.
Training: maximum likelihood with teacher forcing #
The negative log-likelihood of one data point is a sum of terms:
Each term is an ordinary cross-entropy loss: "predict from the true prefix ". Feeding the true prefix from the data, not the model's own samples, is called teacher forcing. With masks, one forward pass gives all terms. Averaged over the data, the loss is the cross-entropy , so training minimizes the forward KL, as in lesson 01. For language models, the mean loss per token in nats gives the perplexity .
Cost. Evaluating takes one parallel pass. Sampling takes sequential passes, because needs first.
Exposure bias #
At training time, the prefix is always real data. At sampling time, it is the model's own output. A small error at step can move the prefix to a region the model never saw in training, where the later conditionals are worse. So errors can build up over a long sequence. This mismatch is called exposure bias.
Two precise remarks. First, exposure bias does not bias the likelihood: is still exact. Second, a perfect model () has no mismatch, because its own prefixes follow the data distribution. It is a problem of imperfect models at generation time. Fixes: scheduled sampling (sometimes feed the model's own predictions during training), sequence-level training (for example RL fine-tuning), and, for time-stepping emulators, training on multi-step rollouts. For large language models, how much it matters in practice is debated.
MADE: masks from degrees #
MADE (masked autoencoder for distribution estimation; Germain et al. 2015) takes an MLP with inputs and outputs ( outputs for parameters per variable) and multiplies each weight matrix elementwise by a fixed binary mask. Every unit gets a degree:
- input has degree ;
- hidden unit of layer gets a degree . It means "this unit may depend on ". A simple choice is for ; the paper samples the degrees at random;
- output (the parameters of factor ) has degree .
The masks have the shape of the weight matrix (rows = units of this layer, columns = units of the layer below). With :
In words: a hidden unit may read units of the same or lower degree; an output may read only units of strictly lower degree.
Theorem (MADE has the autoregressive property). Output depends only on inputs .
Proof.
- Entry of counts the paths from input to output through allowed connections. If it is 0, output cannot depend on , whatever the weights are.
- Along any path , the hidden rule gives , and the output rule gives .
- So every path has . For there is no path: the matrix of path counts is strictly lower triangular.
Why the degrees are . A unit of degree could only feed outputs with , which do not exist, so it is wasted. A unit of degree 0 has no inputs (it is a constant). Output 1 gets no connections at all: its parameters are just the biases, which is right for the unconditional factor .
Click a hidden unit to change its degree, and choose an output to see all paths into it. The table of path counts (the product of the masks) must be zero on and above the diagonal; the shaded cells are the forbidden ones. Change the order: the same rule works for any order, with "degree" meaning "position in the order". Switch on the leak (output rule ): the diagonal fills, and each output sees its own input.
Order-agnostic training (short). The MADE paper also trains one network for many orders at once: it samples a new order and new degrees for each minibatch. At test time, an ensemble over several orders gives a better likelihood. A model trained for one order works only for that order.
MADE with inputs and one hidden layer with degrees . Is the weight from the hidden unit of degree 3 to output 3 kept by the mask?
Output may read hidden unit only if . Here is false, so the weight is masked. If it were kept, output 3 could see through this unit (the unit itself may read ). The unit of degree 3 feeds only output 4.
PixelCNN: masked convolutions #
For images, PixelCNN (van den Oord et al. 2016) uses the raster order: row by row, left to right. Pixel may depend on all rows above and on the pixels to its left in row . A convolution is made causal by setting some kernel weights to zero. For kernels (1 = weight kept; the center is the middle entry):
- Layer 1 uses mask A (center excluded). The feature at will predict input pixel , so it must not see it.
- Later layers use mask B (center included). The layer- feature at already depends only on pixels before , so reading it again is safe. Mask B in layer 1 would leak .
For RGB images the papers also order the channels R, G, B inside a pixel, and masks A and B also say whether a channel may see itself. Here we use one channel.
The blind spot. In a masked layer, the feature at reads positions with either and (the row above), or and (same row, not to the right). After layers, input reaches output only as a sum of such offsets. Exactly of them go up, and only those can move right, by at most 1 each. So
Pixel is never seen, although it comes before in raster order. The unseen region is a wedge to the upper right, and more layers do not remove it.
Increase the number of layers . The blue region is everything the target pixel can see. The orange pixels come before the target in raster order and lie within steps, but no path reaches them: the blind spot. It grows with . Then switch on the two stacks: the blind spot disappears.
The gated PixelCNN: two stacks and gated units
The gated PixelCNN (van den Oord et al. 2016, "Conditional Image Generation with PixelCNN Decoders") removes the blind spot with two stacks of layers. A vertical stack sees all rows above the current pixel, with no masking inside those rows, so there is no wedge. A horizontal stack sees the current row to the left, and at each layer it also receives the features of the vertical stack (shifted so that they cover only rows above). The output combines both, so every earlier pixel within the reach of the layers is seen. The figure shows a simplified geometry of this design.
The same paper replaces ReLU by a gated unit , where is a masked convolution and the sigmoid. A class label or another condition can be added inside both terms: . This is the conditional PixelCNN.
A WaveNet generates raw audio at 16,000 samples per second. One forward pass takes 2 ms on your GPU, and one pass covers a whole second of audio. How long does it take to evaluate of one second of real audio, and to generate one second of new audio (no caching tricks)?
Evaluation uses the real audio as the prefix of every sample, so one pass gives all 16,000 conditionals. Generation needs sample before it can compute the conditional of sample : ms s. This gap is why Parallel WaveNet distills WaveNet into a flow that samples in one pass (lesson 04).
Transformer language models: causal masks and the KV cache #
A decoder-only transformer models tokens with the same chain rule. The input at positions is the sequence shifted right by one, , where BOS is a start token, and position outputs the distribution of . The causal mask sets the attention weight from position to every later position to zero (the score is set to before the softmax). So position sees : exactly the prefix of . The three architectures put the strict inequality in different places:
| Model | Non-strict part ("may see itself") | Strict part |
|---|---|---|
| MADE | hidden masks | output mask |
| PixelCNN | mask B in layers | mask A in layer 1 |
| Transformer LM | causal attention in every layer | input shifted right by one token |
The KV cache. Under a causal mask, the hidden state at position , in every layer, depends only on the inputs up to position . So when a new token is appended, the keys and values of all earlier positions do not change. Decoding step computes the query, key and value of the new position only, appends the key and value to a cache, and attends over the cache. This is exact, not an approximation. Queries are not cached, because each query is used only once, at its own step.
Without a cache, generating tokens processes positions through the projections and MLPs, instead of 1024, and the attention work grows like instead of . The price is memory: numbers per sequence for standard multi-head attention ( layers, model width , one key and one value vector per layer and position); grouped-query attention stores fewer. A plain MADE has no such saving: it recomputes the full pass at each of its sampling steps.
During decoding with a KV cache, what is stored for each earlier position?
A new query must be compared with the keys of all earlier positions and must mix their values, so keys and values are reused at every later step. A query is used only once, at its own step. The attention weights change at every step (each new query gives new weights), so storing them does not help.
Answers to section 1. (1) The network can copy into its prediction, so the training loss goes to 0 nats. But the result is not a distribution: in the example above, the "probabilities" sum to 2. (2) takes one pass, 1 ms. Sampling takes sequential passes, about 1 s.
4. Worked example #
(a) Two bits. , , .
| (0, 0) | (0, 1) | (1, 0) | (1, 1) | |
|---|---|---|---|---|
The sum is , as the theorem says. The log-likelihood of is nats.
The reverse order describes the same joint with three other numbers: , and . With full tables the order does not matter. With a restricted network for each conditional, it does.
(b) MADE masks, , one hidden layer of 5 units. Degrees for , so . Row of has ones in the columns . Row of has ones where :
Row of counts the paths from each input to output . Check one entry: output 3 reads the hidden units with degree below 3, which are units 0, 1, 3, 4 (degrees 1, 2, 1, 2). All four read , so there are 4 paths from ; units 1 and 4 also read , so there are 2 paths from . Output 1 sees nothing (only its bias), output 2 sees , output 3 sees , and output 4 sees . The hidden unit of degree 3 feeds only output 4.
(c) The blind spot, by counting offsets. Stack masks A, B, B () and look at output pixel , with rows and columns numbered from 0.
- Row 3 (one step up): , so columns up to 5.
- Row 2 (two steps up): columns up to 6. Row 1 (three steps up): columns up to 7.
- Row 4 itself: layer 1 (mask A) must move left, so only columns 1 to 3.
Pixels such as , and come before in raster order, but no path reaches from them. (Column 0 and row 0 are unseen for a different reason: three layers reach at most three steps away.)
5. In code #
NumPy checks the claims of sections 3 and 4: the joint table of the two bits, the MADE mask product, the normalization theorem on a tiny causal transformer (summed over all sequences), the causality that makes a KV cache exact, and the blind spot.
import numpy as np
from scipy.signal import convolve2d
# (a) Two bits: the chain rule gives the joint table
p1, p2 = 0.3, {0: 0.8, 1: 0.4} # p(x1=1) and p(x2=1 | x1)
joint = np.array([[(1 - p1) * (1 - p2[0]), (1 - p1) * p2[0]],
[p1 * (1 - p2[1]), p1 * p2[1]]])
print(joint.round(2).tolist(), joint.sum().round(12), np.log(joint[0, 1]).round(4))
# [[0.14, 0.56], [0.18, 0.12]] 1.0 -0.5798
# (b) MADE masks from degrees (D = 4, one hidden layer of 5 units)
D, H = 4, 5
m_in = np.arange(1, D + 1) # input j has degree j
m_h = 1 + np.arange(H) % (D - 1) # hidden degrees [1 2 3 1 2]
M1 = (m_h[:, None] >= m_in[None, :]).astype(int) # hidden rule: >=
M2 = (m_in[:, None] > m_h[None, :]).astype(int) # output rule: strict >
print(M2 @ M1) # path counts: strictly lower triangular
# [[0 0 0 0]
# [2 0 0 0]
# [4 2 0 0]
# [5 3 1 0]]
# (c) A tiny causal self-attention language model sums to 1 over all V^T sequences
rng = np.random.default_rng(0)
V, T, BOS, d = 3, 3, 3, 8 # vocabulary {0,1,2}, length 3, BOS id 3
E, P = rng.normal(size=(V + 1, d)), rng.normal(size=(T, d))
Wq, Wk, Wv, Wo = (rng.normal(size=(d, d)) for _ in range(4))
Wout = rng.normal(size=(d, V))
def log_prob(seq, causal=True):
inp = [BOS] + list(seq[:-1]) # shift right: position i predicts token i
h = E[inp] + P
S = (h @ Wq) @ (h @ Wk).T / np.sqrt(d)
if causal:
S = np.where(np.tril(np.ones((T, T))) == 1, S, -np.inf) # no attention to j > i
A = np.exp(S - S.max(1, keepdims=True)); A /= A.sum(1, keepdims=True)
out = h + (A @ (h @ Wv)) @ Wo
logits = out @ Wout
logp = logits - np.log(np.exp(logits).sum(1, keepdims=True))
return logp[np.arange(T), seq].sum(), out
seqs = [np.array(s) for s in np.ndindex(V, V, V)] # all 27 sequences
print(round(sum(np.exp(log_prob(s)[0]) for s in seqs), 12)) # 1.0
print(round(sum(np.exp(log_prob(s, causal=False)[0]) for s in seqs), 4)) # 0.9954: not 1
# change the second token: only the last position, which reads it, changes
_, a = log_prob(np.array([0, 1, 2]))
_, b = log_prob(np.array([0, 2, 2]))
print(np.abs(a - b).max(1).round(4)) # [0. 0. 4.3719]
# (d) PixelCNN receptive field: masks A, B, B on a 9 x 9 image, output pixel (4, 4)
A_ = np.array([[1, 1, 1], [1, 0, 0], [0, 0, 0]])
B_ = np.array([[1, 1, 1], [1, 1, 0], [0, 0, 0]])
g = np.zeros((9, 9)); g[4, 4] = 1 # backward pass from the output pixel
for K in (B_, B_, A_): # the last layer first
g = convolve2d(g, K, mode="same") # adjoint of a cross-correlation
for r in range(5):
print("".join("o" if (r, c) == (4, 4) else "#" if g[r, c] > 0 else "." for c in range(9)))
# .........
# .#######.
# .######..
# .#####...
# .###o....
o is the output pixel and # marks the pixels it depends on. The empty wedge to the upper right of
o is the blind spot. The leaky model in (c) sums to 0.9954 with this seed: a random leaky model can
land on either side of 1, and a trained one goes far above it, because training rewards copying.
6. Where it shows up #
- Language models. GPT-style models are causal transformers trained with next-token cross-entropy, which is exactly the AR maximum-likelihood loss. Perplexity is of the mean negative log-likelihood per token. A later track on large language models will cover pretraining and inference.
- Audio and images. WaveNet uses dilated causal 1D convolutions over raw audio samples. PixelCNN++ (a mixture of logistics per pixel) reaches 2.92 bits per dimension on CIFAR-10.
- Two-stage generators. A VQ-VAE (lesson 02) turns an image into a grid of discrete codes. An AR prior over the codes (a PixelCNN in VQ-VAE, a transformer in VQGAN; DALL-E uses a transformer over the codes of a discrete VAE) generates new grids, and the decoder turns them into images.
- Normalizing flows. An AR model with Gaussian conditionals, with , is a one-layer affine autoregressive flow. MAF stacks such layers with MADE inside (lesson 04).
- ML for science. Weather emulators step forward in time. GenCast samples each 12-hour step from with a diffusion model and is trained on single steps. GraphCast (deterministic) is fine-tuned on rollouts of 2 to 12 steps of 6 hours to limit error growth: the time-series form of exposure bias. For a long signal, such as a seismogram with samples, the sequential passes are the main reason to prefer flows or diffusion models, which update all samples in each network pass.
7. Common mistakes #
- Leaky masks. A non-strict MADE output mask, mask B in the first PixelCNN layer, or a transformer without the one-token shift. The training loss looks excellent, samples are garbage, and the probabilities over all states do not sum to 1. Check the mask product, or sum the model over all states of a tiny example.
- Thinking sampling is parallel because training is. Teacher forcing parallelizes only evaluation. Sampling stays sequential; the KV cache makes each step cheaper, not the number of steps smaller.
- Confusing exposure bias with a biased likelihood. The likelihood is exact. Exposure bias is about the distribution of the prefix at sampling time.
- Caching queries, or caching in a bidirectional model. Only past keys and values are reused. Without a causal mask, past states change when a token is added, so a cache would be wrong.
- Thinking more PixelCNN layers remove the blind spot. Every layer moves at most one column to the right per row up, so the wedge stays. The fix is a different architecture (two stacks).
8. Check yourself #
- How many free parameters does a full probability table for binary variables have? How
many does a logistic AR model, , have?
Answer
. Factor has weights and one bias, so the AR model has . For (MNIST): against . - In MADE with , which hidden degrees are allowed? Why are 0 and 5 excluded?
Answer
. A degree-5 unit could only feed outputs with , which do not exist. A degree-0 unit sees no input, so it is a constant. - In worked example (b), which inputs does output 3 depend on, and through how many paths?
Answer
through 4 paths and through 2 paths: row 3 of is . - A stack of masked layers (A, then B, B, ...) of any depth. Can output see
pixel ? Pixel ?
Answer
: never, because (blind spot). : yes, with at least 3 layers (three up-right offsets; the row above is allowed in both masks). - A transformer LM generates tokens. How many sequential steps does it need with and without
a KV cache, and what changes?
Answer
steps either way, because sampling is sequential. Without a cache, each step reprocesses the whole prefix (about positions in total). With a cache, each step processes one new position and attends over the cached keys and values. - Why does a model trained with teacher forcing behave differently at sampling time? Why does a
perfect model not have this problem?
Answer
Training conditions on true prefixes, sampling on generated ones (exposure bias). If , generated prefixes follow the data distribution, so there is no mismatch. The problem comes from errors of imperfect models that compound along the sequence.
Write the chain-rule factorization of .
, with . It holds for every distribution and every order.
What is the autoregressive property?
The parameters of factor depend only on , never on .
Why does an autoregressive model sum to 1?
Sum out the last variable first: only the last factor contains it, and that factor sums to 1. Repeat for .
What is teacher forcing?
Training each conditional on the true prefix from the data, not on the model's own samples. With masks, all terms come from one pass.
What is exposure bias?
The mismatch between true prefixes at training time and generated prefixes at sampling time; errors of an imperfect model can compound along the sequence.
Cost of an autoregressive model with variables: evaluate vs sample?
Evaluate: one parallel pass. Sample: sequential passes, since needs .
State the MADE mask rules with degrees .
Hidden: keep if . Output: keep if (strict).
PixelCNN: which mask does layer 1 use, and why?
Mask A (center weight 0), because the feature at predicts pixel and must not see it. Later layers use mask B (center 1).
What is the PixelCNN blind spot?
Pixels before in raster order with : a wedge to the upper right that stacked masked layers never see.
Why is the KV cache exact, and what does it store?
Under a causal mask, the keys and values of earlier positions never change when a token is added. It stores keys and values of every layer, not queries.
9. Interview angle #
- "Why can a GPT train on all positions in parallel but must generate one token at a time?" — The causal mask gives every conditional from the true prefix in one pass (teacher forcing). Generation needs before .
- "How does MADE enforce the autoregressive property?" — Degrees, in the hidden masks, a strict output mask; the mask product is strictly lower triangular.
- "What is the PixelCNN blind spot, and how is it fixed?" — Each row up allows at most one column to the right, so a wedge to the upper right is never seen. The gated PixelCNN uses vertical and horizontal stacks.
- "Why is the KV cache exact? Why are queries not cached?" — Causality: past keys and values never change. Each query is used once.
- "What is exposure bias? Does it matter for LLMs?" — The train/sample prefix mismatch. Fixes: scheduled sampling, sequence-level training, multi-step rollout training. Its size for large LMs is debated.
10. Practice #
The notebook for this lesson has five exercises, each with a check cell and a folded solution:
- Fit a grid AR model of two moons by counting; check that the probabilities sum to 1; sample from it.
- Build MADE masks from degrees; check the dependency pattern of a random masked MLP with finite differences.
- Exposure bias on a Markov chain: compare the error of an imperfect model under true prefixes and under its own prefixes.
- Compute the receptive field of stacked PixelCNN masks and find the blind-spot pixels.
- Write causal self-attention in NumPy and check that output does not change when later inputs change.
11. Watch and read #
- Murphy, Probabilistic Machine Learning: Advanced Topics, free PDF: chapter 22 (§22.1 the chain rule, §22.2 NADE and MADE, §22.3 PixelCNN, §22.4 transformers).
- Germain, Gregor, Murray and Larochelle, MADE: Masked Autoencoder for Distribution Estimation (2015): §4 (masks and the proof), §4.2 (order-agnostic training).
- van den Oord et al., Conditional Image Generation with PixelCNN Decoders (2016): §2.1 (gated units), §2.2 (the blind spot, vertical and horizontal stacks). Masks A and B with color channels are defined in the earlier Pixel Recurrent Neural Networks paper, §3.4.
- Stanford CS236, Deep Generative Models: course notes on autoregressive models.
- Karpathy, pytorch-made: a MADE in about 150 lines of PyTorch.
Runs in your browser with nothing to install. The notebook repeats the key demos and has exercises with checks; solutions are inside, folded.
No Google account needed: Python runs inside your browser. The first start downloads about 40 MB; your changes are saved in this browser only.