VQ-VAE
VQ-VAE compresses an image into a grid of discrete codebook tokens instead of smooth numbers, giving generators a finite vocabulary of visual words.
Why Does This Exist?
Continuous latents are awkward for the strongest generators. Transformers predict discrete tokens, words, IDs, and a smooth Gaussian vector gives them nothing to classify. Researchers wanted the scaling power of next-token prediction applied to images, but images have no vocabulary.
Vector quantisation builds one. By forcing every encoder output through a finite codebook of learned visual words, VQ-VAE turns a photo into a sentence of token IDs. That discrete grid is exactly what powers autoregressive image models, as the owner page autoregressive image generation shows from the generator side. The continuous alternative it departs from is the variational autoencoder.
Think of It Like This
A paint-by-numbers kit with 512 mixed colours
A paint shop holds millions of blendable shades. A paint-by-numbers kit offers 512 premixed pots and a rule: every region of your painting must use the nearest premixed colour. The finished picture is coarser than a freehand blend, but anyone can reproduce it exactly by reading out pot numbers, and a machine can learn to predict those numbers one region at a time.
The codebook is the kit. Quantisation error is the visible gap between the shade you wanted and the nearest pot. It fails when the kit misses a colour family entirely, whole skies collapse into one pot, which is the codebook collapse pitfall below.
How It Actually Works
The encoder outputs a continuous vector per spatial location. A codebook holds learned vectors , usually . Quantisation snaps each output to its nearest entry:
The decoder only ever sees . Gradients cannot flow through the , so training copies decoder gradients straight through to the encoder, the straight-through estimator, and moves codebook vectors toward the encoder outputs assigned to them with a separate dictionary loss. A third term, the commitment loss with , keeps the encoder loyal to its chosen entry instead of drifting between codes. The symbol means stop-gradient: that term trains the encoder only.
Worked example
Encoder output . Codebook has and . Distances squared: to , ; to , . Nearest is , so the region becomes token and the decoder receives exactly . Commitment loss is , a gentle tug keeping the encoder near its pick.
Code
Nearest-code lookup plus the commitment term, the heart of the forward pass.
def quantize(z_e: list[float], codebook: list[list[float]], beta: float = 0.25) -> tuple: """Snap encoder output to nearest code; return token, vector, commitment loss.""" dists = [sum((a - b) ** 2 for a, b in zip(z_e, e)) for e in codebook] k = min(range(len(dists)), key=dists.__getitem__) return k, codebook[k], beta * dists[k]
z_e = [0.6, -0.4]book = [[0.5, -0.5], [-0.3, 0.8]]print(quantize(z_e, book)) # -> (1, [0.5, -0.5], 0.005)Watch Out For
Codebook collapse leaves most entries unused
Early in training a few entries win every lookup, get all the gradient, and win more, while hundreds of codes sit frozen. Reconstructions then reuse a tiny visual vocabulary and look posterised.
Track the fraction of codes used per batch. If it drops under half, restart dead entries near active encoder outputs or use exponential moving-average codebook updates, which spread assignments far more evenly than plain gradient steps.
Expecting smooth interpolation between tokens
In a continuous latent space, averaging two codes gives a sensible in-between image. Token IDs have no arithmetic: the average of token and token is not token in any meaningful sense.
Interpolate in encoder space before quantisation, or decode both endpoints and blend pixels. Never blend IDs.
The Quick Version
- VQ-VAE replaces each continuous encoder output with its nearest learned codebook vector.
- The image becomes a grid of discrete token IDs, a vocabulary transformers can predict.
- Gradients bypass the lookup via straight-through estimation while a dictionary loss moves the codes.
- Our example snaps to token at distance with commitment cost .
- Watch for dead codebook entries and never interpolate raw token IDs.