Paper Breakdowns  /  VQ-VAE
Paper 93~11 min read2017worked math + runnable code
Paper Breakdown

Discrete
latents.

A normal autoencoder squeezes an image into a cloud of real numbers — infinitely fine, hard to model. VQ-VAE asks a stranger question: what if the latent had a vocabulary? Instead of a continuous vector, every patch of the image is forced to pick the closest word from a small learned dictionary — a codebook. The picture becomes a little grid of discrete symbols, like text. That one change — quantize the latent — is what lets a Transformer or a diffusion model treat images the way it treats language, and it's the quiet foundation under DALL·E's image tokens and a decade of generative modeling. Here's the nearest-neighbor snap, the gradient trick that makes it trainable, and the commitment loss.

Video breakdown
The animated walkthrough is in production.
Read the full breakdown below in the meantime ↓
01

A latent with a vocabulary

A standard variational autoencoder maps each input to a continuous latent vector — a point in a smooth, real-valued space. That's flexible, but it's awkward to model: the strongest generative machinery we have — autoregressive Transformers — works over discrete tokens, a finite vocabulary, not a cloud of floats. VQ-VAE (van den Oord, Vinyals & Kavukcuoglu, 2017) closes that gap by making the latent itself discrete.

The move is simple to state: the encoder still outputs a continuous vector, but before it reaches the decoder it's quantized — replaced by the nearest entry in a small learned dictionary of vectors called the codebook. Each latent position becomes one of K possible symbols, an integer index. An image is no longer a fog of real numbers; it's a compact grid of discrete tokens, exactly the kind of thing a language model knows how to devour. The whole paper is about making that snap-to-nearest operation actually learnable.

The one-sentence version

Quantize the encoder's continuous output to the nearest vector in a learned codebook so the latent is a grid of discrete tokens; train it by copying the decoder's gradient straight through the non-differentiable snap, plus a commitment loss that keeps the encoder faithful to its chosen code.

02

The codebook

The codebook is a learned set of K embedding vectors — the discrete vocabulary of the latent space. Think of it as a palette: a fixed number of prototype vectors that the model gets to place wherever they're most useful. When the encoder emits a continuous vector z_e(x), quantization measures its distance to every codebook entry and replaces it with the closest one, z_q. The index of that entry is the discrete token you store.

Both sides learn together. The encoder learns to produce vectors that land near useful codes; the codebook entries drift toward wherever the encoder's outputs actually cluster (in the original paper, the codebook is updated to track the mean of the encoder vectors assigned to it). Over training, the K codes spread out to tile the space of representations the data needs — a self-organizing dictionary. Choose K and the grid size and you've fixed exactly how many bits the latent can hold: a hard, interpretable information bottleneck.

03

Snap to the nearest code

Quantization is a nearest-neighbor lookup: pick the codebook entry with the smallest squared distance to the encoder's vector.

The forward and backward passes
encodeEncoder outputs a continuous vector z_e(x).
quantizek = argminj ‖z_e − ej‖² — snap to the nearest code z_q = ek.
decodeDecoder reconstructs the input from the discrete code z_q.
backwardargmin has no gradient — copy the decoder's gradient straight back to the encoder (straight-through).

The catch is the backward pass. The argmin — "which code was closest?" — is a hard, non-differentiable choice; there's no gradient telling the encoder how to nudge its output to change the winner smoothly. VQ-VAE sidesteps this with the straight-through estimator: on the way forward it uses the quantized code, but on the way back it pretends the quantization was the identity and copies the decoder's gradient directly onto the encoder's continuous output. The encoder gets trained as if the snap never happened. It's an approximation — but a remarkably effective one, and it's the trick that makes discrete latents learnable end-to-end.

04

The three-part loss

Because the straight-through trick skips the quantizer on the backward pass, the encoder gets a reconstruction gradient but the codebook gets none — so VQ-VAE adds explicit terms to train the codes and to keep the encoder honest. The loss has three parts:

L  =  ‖x − decode(z_q)‖²  +  ‖sg[z_e] − e‖²  +  β·‖z_e − sg[e]‖²

Left: reconstruction. Middle: the codebook loss moves the chosen code e toward the encoder output (sg = stop-gradient, so only e updates). Right: the commitment loss, weighted by β, pulls the encoder's output toward its code so the encoder "commits" and doesn't hop between codes — only z_e updates. The runnable version below computes the quantization and these losses.

The stop-gradient operator sg[·] is what lets one squared-distance be reused for two jobs: freeze the encoder side and the term trains the codebook; freeze the codebook side and (scaled by β) it trains the encoder to commit. The commitment weight β is the one real knob — too small and the encoder's outputs wander freely, growing faster than the codes can chase; the paper found results were robust across a broad range and used β = 0.25.

RUN IT YOURSELF

Quantization, from scratch

VQ-VAE's core operation is nearest-neighbor quantization: measure the squared distance from the encoder's vector to every codebook entry and snap to the closest one. Here it is with no autograd, no tensors — the argmin lookup, the squared L2 distance, the commitment loss (β times the distance to the chosen code), and the three-part total. Change the codebook or the encoder vector and watch which code wins.

CPython · WebAssembly
05

What it showed

VQ-VAE demonstrated that a discrete latent can match continuous ones on reconstruction while being far more useful downstream:

ContributionSignificance
Discrete latents that workQuantized codes reconstructed images, audio, and video as well as continuous VAEs — without "posterior collapse".
Straight-through trainingCopying the gradient past the non-differentiable snap made end-to-end learning of discrete codes practical.
A learned discrete codeThe codebook self-organized into meaningful, reusable prototypes — a compact vocabulary for the data.
Powerful priors over codesTraining an autoregressive prior (PixelCNN / WaveNet) over the codes produced strong, coherent samples.

It isn't free: the straight-through estimator is a biased gradient approximation, codebook usage can collapse to a few entries if unbalanced, and the reconstruction ceiling is set by K and the grid — a hard bottleneck. But the central result was decisive: you can compress continuous data into discrete tokens and lose little, which opens the door to modeling those tokens with the full power of sequence models.

06

A tokenizer for images

VQ-VAE's real legacy is as a tokenizer for continuous data. Once an image is a small grid of discrete codes, you can hand those codes to a powerful separate model — an autoregressive Transformer or a diffusion prior — and generate in that compact token space instead of over millions of raw pixels. This "compress to tokens, then model the tokens" recipe is dramatically cheaper and produces sharper results, and it became the dominant pattern in generative vision.

The line of descent is direct: VQ-VAE-2 stacked hierarchical codes for high-resolution images; DALL·E tokenized images into a discrete grid and modeled them with a Transformer alongside text; VQGAN added a perceptual/adversarial loss for crisper codes; and the same idea powers discrete audio tokenizers behind modern speech and music models. Even latent diffusion — which uses a continuous latent — inherits the core insight that you should generate in a learned, compressed representation rather than pixel space. The specific trick of a nearest-neighbor codebook with a commitment loss turned out to be one of the most reused building blocks in generative AI.

Worth knowing

A recurring failure mode is "codebook collapse": the model learns to use only a handful of the K codes and ignores the rest, wasting capacity. Practical fixes include EMA codebook updates, periodically re-initializing dead codes to active encoder outputs, and normalizing or lowering the code dimension — engineering that later work (VQGAN, improved VQ-VAEs) leaned on heavily to keep the whole vocabulary alive.

Frequently asked

Quick answers

What is a VQ-VAE?

An autoencoder with a discrete latent: the encoder's continuous output is snapped to the nearest vector in a learned codebook, so each latent position is a discrete token.

What is the codebook?

A learned set of K embedding vectors — the vocabulary of the latent space. Quantization replaces the encoder's vector with the nearest codebook entry; its index is the token.

What is the commitment loss?

A term (weighted by β) that pulls the encoder's output toward its chosen code, so the encoder commits and doesn't oscillate between codes. Part of the three-part VQ-VAE loss.

Why does it matter?

Discrete codes let Transformers and diffusion priors model images/audio as tokens. It's the tokenizer behind VQ-VAE-2, DALL·E's image tokens, and VQGAN.

Neural Discrete Representation Learning · Aaron van den Oord, Oriol Vinyals, Koray Kavukcuoglu · DeepMind · 2017 · read the original paper on arXiv → · Vibe Engines · 2026
Finished this one? 0 / 101 Paper Breakdowns done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.

More Paper Breakdowns