Vibe Engines is free, interactive AI engineering & system design — runs in your browser. Pick a learning path →
DDPM,
explained.
Diffusion was a decade-old idea that never quite worked — beautiful in theory, mediocre in practice. Then this paper made one deceptively humble change: instead of predicting complicated distributions, just train a network to guess the noise. That single simplification turned diffusion from a curiosity into the method behind DALL·E, Midjourney, and Stable Diffusion. Here's the original math, made intuitive.
Contents 18 sections
The delta The core intuition The forward process: adding noise on a schedule The trick that makes training cheap The reverse process: the learned part The masterstroke: just predict the noise The schedule, worked with real numbers How it works The math The evidence Since then Solve it yourself Sampling and results The limits Why it still matters Questions Check yourself Where this sitsWhat changes against GANs: the hard part is made fixed and known
Rung 2's difficulty is that both halves of the game are learned, so nothing is stable. This rung's change is to make one direction fixed, simple and known in advance: define a process that takes an image and adds a little Gaussian noise, over and over, for many steps, until nothing is left but noise. That direction involves no learning at all — it is a schedule someone wrote down.
All the model has to learn is to undo one step of it. And because each forward step is a small Gaussian perturbation, the corresponding reverse step is also approximately Gaussian, which makes it something a network can be asked to predict. Generation is then: start from pure noise, apply the learned reverse step many times, arrive at an image.
The training objective is where this becomes remarkable. After simplification, what the network is asked to do is: given a noisy image and how noisy it is, predict the noise that was added — and the loss is a plain squared error on that prediction. Generative modelling has become regression. There is no adversary, so no saddle point and no instability; the loss is a number that decreases and means something; and because every training example is a real image with noise on it, there is no mechanism for mode collapse — the model never gets to choose which parts of the distribution to cover. Stated against rung 2, that is the whole argument, and it is why this family won.
The core intuition
Imagine dropping ink into water. It disperses until the glass is a uniform haze — an easy, predictable process to run forward. Now imagine running it backward: reassembling that haze into the original drop. Impossible to do exactly, but if you learned, at every tiny moment, how to nudge the haze one step back toward order, you could reverse the whole thing.
That's diffusion. The forward direction gradually destroys an image into noise — trivial. The reverse direction rebuilds an image from noise — hard, and exactly what we train a network to do. Generate by starting from pure noise and running the learned reverse steps until a picture appears.
The forward process: adding noise on a schedule
The forward process is a fixed Markov chain with no learnable parameters. Over T steps (the paper uses T = 1000), it repeatedly adds a little Gaussian noise. A noise schedule β₁ … β_T — small numbers that grow over time — sets how much noise each step injects:
In words: each step shrinks the current image slightly and sprinkles in fresh noise. Start with a clean image x₀; after enough steps you reach x_T, which is indistinguishable from pure Gaussian noise. This process is a given — its only purpose is to define the corruption the network must learn to undo.
The trick that makes training cheap
Adding noise a thousand times to make one training example would be painfully slow. A neat property of Gaussians rescues it: you can jump straight to any timestep in one shot. Define α_t = 1−β_t and ᾱ_t = α₁·α₂·…·α_t, and then
So to make a training example at noise level t, you take a clean image, pick a random t, sample one blob of noise ε, and combine them by the formula above — no thousand-step loop needed. This closed form is what makes DDPM training efficient, and it's the key to the objective coming up.
The reverse process: the learned part
Reversing the chain means going from x_t to a slightly cleaner x_{t-1}. The true reverse step is intractable, but if each forward step adds only a little noise, each reverse step is well-approximated by a Gaussian too — so we train a network to predict its mean.
That network is a U-Net: an encoder-decoder with skip connections, well suited to images, that also takes the timestep t as input so it knows how noisy things currently are. Apply it repeatedly — x_T → x_{T-1} → … → x₀ — and noise becomes an image. All the model's intelligence lives in this one denoising network.
The masterstroke: just predict the noise
Earlier diffusion work derived a complicated variational bound and tried to predict full distributions — fiddly and unstable. DDPM's decisive move was to reparameterize the problem. Since x_t = √(ᾱ_t)x₀ + √(1−ᾱ_t)ε, knowing the noise ε is equivalent to knowing the clean image. So just predict ε. The training loss collapses to plain mean-squared error:
The recipe is almost embarrassingly simple: take a clean image, add a known amount of noise, and ask the network to guess the noise you added. Penalize the squared error. That's it. This "simple objective" — a reweighted version of the variational bound — produced dramatically better samples than the true bound (the fixed-variance bound itself trained without trouble; the gain was in sample quality) — the entire reason diffusion suddenly worked.
Predicting noise turns generative modeling into ordinary supervised regression. No adversarial game, no delicate distribution matching — just "guess the noise," a loss any practitioner can train reliably. Simplicity was the breakthrough.
The schedule, worked with real numbers
The paper's exact recipe: T = 1000 steps, β rising linearly from 0.0001 to 0.02. Everything interesting lives in the cumulative product ᾱ_t = Π(1−β_s) — the fraction of original signal surviving at step t. Compute it:
| Step t | ᾱ_t | Signal √ᾱ_t | Noise √(1−ᾱ_t) | What the image looks like |
|---|---|---|---|---|
| 10 | 0.998 | 0.999 | 0.04 | essentially clean |
| 100 | 0.897 | 0.947 | 0.32 | visibly grainy, fully recognizable |
| 500 | 0.079 | 0.28 | 0.96 | mostly noise — structure barely ghosts through |
| 1000 | 0.00004 | 0.006 | 1.00 | indistinguishable from pure noise |
Two things to notice. The destruction is front-loaded gently — after 100 of 1000 steps, 95% of the signal amplitude survives; the schedule spends most of its budget in the middle. And at t = 1000 the signal fraction is 0.6% — which is why sampling can start from pure random noise: the endpoint of the forward process genuinely is one.
The reparameterization the whole paper turns on is one line of algebra on the shortcut formula. If you know the noise, you know the image:
Training teaches a network to estimate ε; the identity above converts that estimate back into an image, one denoising step at a time. Generative modeling became regression on noise.
How DDPM trains and samples, step by step
Ho, Jain and Abbeel's Denoising Diffusion Probabilistic Models took the diffusion probabilistic model of Sohl-Dickstein and colleagues (2015), chose a specific parameterization of its reverse process, and showed that the training loop then shrinks to three lines. The two procedures below are the paper's training and sampling algorithms in full.
Training
- Prepare data and schedule. Scale pixel values to [−1, 1]. Fix T = 1000 and a linear β schedule from 10^−4 to 0.02, and precompute αt = 1 − βt and ᾱt = α1⋯αt.
- Draw one training example. Take an image x0, a timestep t uniformly from 1 to T, and noise ε ~ N(0, I). Form xt = √ᾱt x0 + √(1 − ᾱt) ε in one shot, with no chain to run.
- Regress the noise. Take a gradient step on ‖ε − εθ(xt, t)‖^2, and repeat until converged.
Sampling
- Start from noise. Draw xT ~ N(0, I).
- Step down one level. For t = T down to 1, compute (1/√αt)(xt − (βt/√(1 − ᾱt)) εθ(xt, t)) and add σt z with fresh z ~ N(0, I), except at the last step, which adds no noise.
- Fix the variance. The paper does not learn σt^2. It tried βt and the posterior variance β̃t = βt(1 − ᾱt−1)/(1 − ᾱt) and got similar results. The first is optimal if the data were standard normal noise, the second if the dataset were a single point, so the two bracket the right answer.
- Output. After the last step, x0 is the sample. Each of the 1,000 steps is one full network evaluation.
The network and the training run
εθ is a U-Net in the style of an unmasked PixelCNN++, with group normalization, two residual blocks per resolution, self-attention at the 16×16 feature-map resolution, and the timestep injected through a Transformer-style sinusoidal embedding; one set of weights serves every t. The CIFAR-10 model had 35.7 million parameters, the 256×256 LSUN and CelebA-HQ models 114 million, and a larger LSUN Bedroom variant about 256 million. Training used Adam at a learning rate of 2×10^−4 (2×10^−5 at 256×256, where the higher rate was unstable), batch size 128 for CIFAR-10 and 64 for the larger images, an exponential moving average of the weights with decay 0.9999, random horizontal flips on CIFAR-10, and dropout 0.1 on CIFAR-10, without which samples showed overfitting artifacts. The CIFAR-10 model trained for 800,000 steps on a TPU v3-8 in about 10.6 hours, and a batch of 256 samples took about 17 seconds.
Why the last step is special
The final term of the bound is the likelihood of the discrete pixel values given x1. The paper models it with a discrete decoder: a Gaussian at the predicted mean, integrated over each pixel's bin of width 2/255, with the outermost bins extended to infinity. That keeps the reported likelihood a true bound in bits per dimension; at sampling time the predicted mean is shown without noise.
From the variational bound to the noise-prediction loss
LT— the first KL has no parameters, since β is fixed, so it is a constant.q(xt−1 | xt, x0)— the forward process run backward once x0 is known: Gaussian, closed form, so every Lt−1 is a KL between two Gaussians.μθ— written in the same form as μ̃t, with x0 replaced by its estimate from εθ, so the distance between means becomes a scaled error on ε.Lsimple— drops the weight in front and samples t uniformly.
The dropped weight is far from constant. With σt^2 = βt it equals βt/(2αt(1 − ᾱt)): about 0.5 at t = 1 and about 0.01 at t = 1000. Setting it to 1 everywhere down-weights the easy, nearly clean steps relative to the bound and spends effort on heavily corrupted ones, which is why Lsimple gives better samples and a slightly worse likelihood.
What DDPM scored on CIFAR-10, and the ablation behind the simple loss
The headline benchmark was unconditional CIFAR-10, scored by Inception Score (IS, higher is better), FID (lower is better) and negative log-likelihood in bits per dimension; 256×256 models were trained on CelebA-HQ and on LSUN Bedroom, Church and Cat. The decisive experiment is an ablation of what the network predicts and which loss trains it, on CIFAR-10. Dashes mark runs the paper reports as unstable, with poor samples.
| Network predicts | Trained with | IS | FID |
|---|---|---|---|
| Posterior mean μ̃ | True bound, learned diagonal variance | 7.28 | 23.69 |
| Posterior mean μ̃ | True bound, fixed variance | 8.06 | 13.22 |
| Posterior mean μ̃ | Unweighted MSE on μ̃ | — | — |
| Noise ε | True bound, learned diagonal variance | — | — |
| Noise ε | True bound, fixed variance | 7.67 | 13.51 |
| Noise ε | Lsimple | 9.46 | 3.17 |
Read across the rows. With fixed variances and the true bound, predicting ε and predicting μ̃ give about the same quality (FID 13.51 against 13.22), and learning the variances either hurt or made training unstable. The gain comes from the reweighted Lsimple, which needs the ε parameterization. The resulting IS 9.46 and FID 3.17 were, in the authors' words, better than most models in the literature at the time, including class-conditional ones.
The negative result is likelihood. The Lsimple model's test bound was 3.75 bits per dimension, and the model trained on the true bound reached 3.70. Both beat published estimates for energy-based models and score matching but are not competitive with other likelihood-based models; the Sparse Transformer was at 2.80. A rate–distortion analysis explains why: more than half of the lossless codelength goes to imperceptible detail, which a model tuned for appearance has little reason to spend capacity on. On the 256×256 LSUN sets, sample quality landed in the range of ProgressiveGAN, behind the StyleGAN family.
What the authors admit, and what happened next
The cost is stated plainly and it is severe: sampling requires many sequential network evaluations — on the order of a thousand in this paper — where a GAN generates in one. Diffusion traded a training problem for a sampling problem, and at publication that made it orders of magnitude slower to generate with. Rungs 5 and 7 are both attacks on this one sentence.
The objective is also acknowledged to be a reweighted version of the proper variational bound rather than the bound itself — the simplification that makes it a clean regression drops terms, and it is justified because it works better, not because it is exact. An honest and consequential piece of empirical pragmatism.
How it held up: it displaced rung 2 as the default for image generation within about two years, and the reasons are the ones above — stable training and full distribution coverage beat one-shot sampling speed, because speed turned out to be fixable and instability did not. Everything from rung 5 to rung 8 is a refinement of this rung, which makes it the most load-bearing paper on the ladder.
Diffuse and recover, in 25 lines
The full forward process on a 1-D "image," running in your browser through WebAssembly: build the paper's exact β schedule, watch ᾱ decay through the table's checkpoints, then prove the reparameterization — given the true noise, recovery of x₀ is exact at any step. The trained network's entire job is estimating that ε; everything else is this algebra.
Write the body of forward. Everything else in the file is
already written; this is the function the paper is about. Press ▶ Run to check it against
the 5 assertions below — they start red.
- Alpha-bar decays monotonically
- Endpoint is pure noise
- Recovery is exact given true noise
- No noise at t=0: surviving signal fraction is 1
- The linear beta schedule increases over time
Sampling and results
To generate, start from pure noise x_T ~ 𝒩(0, I). At each step, run the network to predict the noise, subtract off a scaled portion to get a cleaner estimate, add a touch of fresh noise for stochasticity, and repeat down to x₀. After all T steps you have a fresh image the model has effectively imagined from static.
| Property | GANs | DDPM |
|---|---|---|
| Generation | one forward pass | many denoising steps |
| Training | adversarial (unstable) | simple MSE (stable) |
| Sample diversity | prone to mode collapse | high, covers the data |
DDPM produced image quality competitive with the best GANs of the time — without the instability or mode collapse — establishing diffusion as a serious, and soon dominant, family of generative models.
The limits
The obvious cost is speed. Generating one image means running the network hundreds or a thousand times — orders of magnitude slower than a GAN's single pass. DDPM also operates directly in pixel space, so high-resolution generation is very expensive in both compute and memory.
Both limits drove the follow-up work. DDIM and other fast samplers cut the step count dramatically; latent diffusion moved the whole process into a compressed space to slash the per-step cost. DDPM is the sturdy foundation those improvements were built on, not the final, efficient product.
Why it still matters
DDPM is the paper that made diffusion work, and it launched the generation era we're living in. Every major image and video generator — DALL·E 2, Imagen, Midjourney, Stable Diffusion — descends from the forward/reverse framework and the noise-prediction objective defined here. When a model "denoises" its way to a picture, it's running DDPM's idea.
Its deeper lesson is about the power of the right reframing: a hard generative problem became a simple supervised one by choosing to predict noise. That move dethroned GANs as the default for high-fidelity generation and reoriented the whole field around iterative denoising.
Pair this with latent diffusion (which made it efficient enough for Stable Diffusion) and DDIM (which cut the 1000 sampling steps to ~50). DDPM is the mathematical bedrock beneath both.
Questions people ask about DDPM
How is the DDPM loss derived from the variational bound?
Start from the evidence lower bound on log p(x0) for the whole chain. Because the forward process is a fixed chain of Gaussians, the bound splits into one term per step: a constant prior-matching term at step T, a reconstruction term at step 1, and for every other step the KL from q(x_{t−1} | x_t, x_0), the forward process run backward given the clean image, to the model's reverse step. That posterior is Gaussian with a closed-form mean, so each KL is a squared distance between two means divided by the fixed variance. DDPM writes the model's mean in the same form as the posterior mean, with x0 replaced by an estimate built from predicted noise. The distance between means then becomes a weighted squared error on the noise, and dropping the weight gives the simple loss.
What are the steps of the DDPM sampling algorithm?
Draw x_T from a standard normal. Then, for t from T down to 1: run the network on x_t and t to predict the noise, subtract that prediction scaled by β_t / √(1 − ᾱ_t), divide by √α_t, and, unless t = 1, add fresh Gaussian noise scaled by σ_t. The result is x_{t−1}, and after the last step the output is the sample. With the paper's schedule of T = 1000 and β rising linearly from 0.0001 to 0.02, that is 1,000 sequential network evaluations per image; the CIFAR-10 model needed about 17 seconds for a batch of 256. The variance σ_t² was fixed to β_t or to the posterior variance β̃_t, and the two gave similar results.
Why does DDPM fix the reverse-process variance instead of learning it?
The paper sets the reverse variance to an untrained, time-dependent constant: either β_t or the posterior variance β̃_t, the two extremes that are optimal for opposite assumptions about the data. Both gave similar results. In the ablation, learning a diagonal variance hurt: with mean prediction it raised FID to 23.69 against 13.22 for a fixed variance, and with noise prediction training became unstable. Fixing the variance also leaves the network a single job, predicting noise, which is what lets the loss become plain regression. Later work revisited the choice: Nichol and Dhariwal's Improved DDPM learned an interpolation between the two fixed values with a hybrid loss, which improved likelihood and allowed sampling with fewer steps.
How is DDPM related to score matching and Langevin dynamics?
The noise a DDPM network predicts is, up to scale, the score of the noisy data distribution: the gradient of log q(x_t) with respect to x_t is approximately −ε_θ(x_t, t) / √(1 − ᾱ_t). Training with the noise loss is therefore denoising score matching across many noise levels at once, the objective Song and Ermon used for noise-conditional score networks, and DDPM's sampling step resembles annealed Langevin dynamics, which repeatedly steps along a learned score and adds fresh noise at decreasing noise levels. The paper presents this connection between variational diffusion models and score-based models as one of its contributions. Song and colleagues later unified both as discretizations of a stochastic differential equation.
What FID and likelihood did DDPM achieve on CIFAR-10?
The best unconditional CIFAR-10 model, trained with the simplified noise-prediction loss, reached an Inception Score of 9.46 and an FID of 3.17, which the authors describe as better sample quality than most models in the literature at the time, including class-conditional ones. Its negative log-likelihood bound was 3.75 bits per dimension on the test set. A model trained on the true variational bound did slightly better on likelihood, 3.70, but much worse on samples, with FID 13.51. Those likelihoods beat earlier energy-based and score-matching estimates but trailed strong likelihood models such as the Sparse Transformer at 2.80. The model had 35.7 million parameters and trained for 800,000 steps.
Why does the simplified DDPM loss give better samples but a worse likelihood than the true bound?
The true bound weights each step's noise error by β_t² / (2σ_t² α_t (1 − ᾱ_t)). With the paper's schedule that weight is roughly fifty times larger at the first, nearly noise-free step than at the last. The simplified loss sets every weight to one, so relative to the bound it down-weights the small-t terms, where denoising is easy and mostly about fine detail, and spends more effort on heavily corrupted steps that decide global structure. Likelihood is dominated by exactly that fine detail; the authors' rate-distortion analysis found more than half the codelength describes imperceptible distortions. Samples are judged by structure. The trade produced FID 3.17 instead of 13.51 at a cost of 0.05 bits per dimension.
4 questions to test what you just read
Work each one out before you open it — a number, a prediction or a reason, not a definition. Producing the answer is what makes it stick. Your progress is kept on this device.
Using σ_t² = β_t, what weight does the true bound put on the ε error at t = 1 and at t = 1000, and what does L_simple do to that ratio?
Show answer
The weight is βt/(2αt(1 − ᾱt)). At t = 1: 10^−4/(2 × 0.9999 × 10^−4) ≈ 0.5. At t = 1000: 0.02/(2 × 0.98 × 1) ≈ 0.0102, a ratio of about 49×. Lsimple sets both to 1, so relative to the bound it down-weights the easy early steps roughly 49-fold.
How much noise does the posterior variance β̃ add at the final step, t = 1, and why?
Show answer
β̃1 = β1(1 − ᾱ0)/(1 − ᾱ1), and ᾱ0 = 1 by definition, so β̃1 = 0. The posterior over x0 given x0 leaves nothing uncertain, and the sampler matches it by adding no noise at the last step.
At t = 1000, how much of the predicted noise does one sampling step remove, and what does that imply about the number of steps?
Show answer
The coefficient on εθ is βt/√(1 − ᾱt) ≈ 0.02/1 = 0.02, followed by a rescale of 1/√0.98 ≈ 1.010. Each step removes about 2% of the predicted noise and then adds fresh noise with standard deviation √0.02 ≈ 0.14, so progress per step is tiny at high noise and the chain needs many steps.
Why can DDPM ignore the L_T term of the bound entirely?
Show answer
LT = KL(q(xT | x0) ‖ p(xT)) involves only the fixed forward process and the fixed N(0, I) prior. With β fixed rather than learned, nothing in it depends on θ, so it is a constant with zero gradient. With ᾱ1000 ≈ 4×10^−5 it is also nearly zero.
Generating pixels
Ten papers from the first latent-variable generator to video and real-time 3D. The diffusion half is strictly cumulative — each rung removes a cost the last one paid.
Explore the topic
See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.
More Paper Breakdowns
- Attention Is All You NeedThe paper that introduced the Transformer — the architecture underneath GPT, BERT, Claude, and Gemini. Self-attention, Query/Key/Value, multi-head attention, positional encoding, and the real BLEU results, explained in depth with analogies and animated visuals, not just equations.Read →
- Word2VecHow words became math. Dense word vectors learned from the company a word keeps, so king − man + woman lands near queen. Skip-gram, CBOW, the distributional hypothesis, and the origin of every embedding model powering search and RAG.Read →
- ResNetThe skip connection that made deep learning deep. Why stacking layers made networks worse, and how residual learning let them reach 150+ layers and win ImageNet — the identity shortcut every Transformer still uses inside every block.Read →
- Vision Transformer (ViT)When an image became 16×16 words. Cut a picture into patches, treat each patch as a token, and feed them to a plain Transformer — no convolutions. Patch embeddings, the class token, and why data scale lets attention beat the CNNs that ruled computer vision for a decade.Read →
- Latent DiffusionThe paper behind Stable Diffusion. Compress an image into a small latent space with a VAE, run the diffusion denoising there instead of on pixels for a tens-of-times efficiency win, and steer it with text via cross-attention. The architecture that put text-to-image generation on consumer GPUs.Read →
- GANsThe counterfeiter and the detective. Two networks locked in a game: a generator forging fakes from noise and a discriminator trying to catch them. The minimax objective that taught machines to imagine, its notorious instabilities and mode collapse, and how diffusion later overtook it.Read →