Diffusion Models: Forward and Reverse Processes
Imagine you want to generate photorealistic faces, but you only know how to destroy images, not create them. Diffusion models turn this apparent limitation into a strategy. Take real data, and gradually corrupt it into pure noise. This happens through a fixed Markov chain. Then train a neural network to walk that chain backward. It proceeds one small denoising step at a time. Each individual step is easy to learn. A small Gaussian perturbation is much simpler to invert than the entire data-generating distribution at once. Yet composing thousands of these easy steps yields a generator. It is powerful enough to produce state-of-the-art images, audio, and video. This matters because the alternative generative paradigms each pay a steep price. Generative Adversarial Networks require a delicate adversarial equilibrium. This equilibrium is notoriously unstable to train. Autoregressive models scale poorly to high-resolution, non-sequential data. Variational autoencoders often blur fine detail. This happens because they optimize a single-shot reconstruction. Diffusion models sidestep these issues by decomposing generation into many small, well-conditioned sub-problems. The cost is needing many sequential steps at sampling time. The big picture is a two-process design. There is a fixed, non-learned forward process that destroys structure. It does this by adding Gaussian noise over steps. There is also a learned reverse process that reconstructs structure. It does this by predicting and removing that noise. Training reduces to a simple regression problem — predict the noise that was added. This works thanks to a closed-form shortcut. The shortcut lets us jump to any noise level in one step. It avoids the need to simulate the chain during training. This connects tightly to The Reparameterization Trick. That trick is what makes the forward process differentiable and samplable in closed form. This article builds the forward chain from first principles. It derives the reparameterized closed form that makes training tractable. It walks through the training and sampling algorithms in full pseudocode. It proves why the training objective is a valid bound on the data likelihood. It closes with a worked numerical trace, common failure modes, and relevant history. That history connects this model family to non-equilibrium thermodynamics and score matching. This is picked up in Denoising and Score-Based Models.
- Diffusion models learn to generate data by reversing a fixed Gaussian noising Markov chain.
- The forward process adds small Gaussian noise at each of steps.
- A reparameterization gives a closed form , letting training sample any timestep directly.
- Training reduces to predicting the noise added to , via a simple mean-squared-error loss.
- Sampling runs the learned reverse chain from pure noise back to data, step by step.
- The objective is a variational bound (ELBO) on log-likelihood, giving a principled correctness guarantee.
Diffusion models replace one hard generation problem with thousands of easy denoising problems, chained together via a fixed forward noising process and its learned reverse.
The idea
A diffusion model defines two coupled stochastic processes over a sequence of latent variables , where is a real data point (an image, say) and is approximately standard Gaussian noise. The forward process is a fixed Markov chain that adds a small amount of Gaussian noise at each step according to a variance schedule :
This process has no learned parameters — it is a fixed corruption schedule, analogous to annealing a physical system toward thermal equilibrium. The reverse process is what we actually learn: a Markov chain that starts from and applies learned Gaussian transitions
to walk back from noise to data. Because each forward step adds only a small perturbation (for large and small ), the reverse transition is also approximately Gaussian — this is the key mathematical fact that makes the reverse process learnable with a simple neural network rather than an intractable arbitrary distribution. The crucial computational trick, using the reparameterization trick, is that the marginal has a closed form: letting and ,
This means we can sample a noised version of any data point at any timestep in a single step, with no need to iterate through intermediate steps. Training therefore never has to simulate the chain — it just picks a random , generates directly, and asks a network to recover the noise that was added. This is what makes diffusion training embarrassingly parallel and efficient, distinguishing it sharply from the sequential nature of sampling.
How it works
Step 1 — Choose a noise schedule. Fix (commonly 1000) and a schedule , e.g. linear from to , or a cosine schedule. Precompute and .
Step 2 — Training. For each minibatch, sample real data , sample a random timestep , sample noise , form using the closed-form reparameterization above, and train a network to predict via mean-squared error. The network is typically a U-Net with time-step embeddings (often sinusoidal, as in Transformers) injected at every resolution level.
Step 3 — Sampling. Start from . For , use to estimate the reverse mean , then sample from the Gaussian reverse transition (adding fresh noise except at the final step). After iterations, is a generated sample. ```
# ---------- Precompute schedule ---------- function PRECOMPUTE_SCHEDULE(T, beta_min, beta_max): beta[1..T] <- LINSPACE(beta_min, beta_max, T) alpha[1..T] <- 1 - beta alpha_bar[1..T] <- CUMULATIVE_PRODUCT(alpha) # alpha_bar[t] = prod_{s<=t} alpha[s] return beta, alpha, alpha_bar
# ---------- Training ---------- function TRAIN(data_distribution, T, beta, alpha, alpha_bar, epsilon_theta, num_steps): for step in 1..num_steps: x0 <- SAMPLE_BATCH(data_distribution) # shape [B, ...] t <- SAMPLE_UNIFORM_INT(1, T, size=B) # one timestep per example eps <- SAMPLE_GAUSSIAN(shape=x0.shape) # target noise sqrt_ab <- SQRT(alpha_bar[t]) # broadcast over batch sqrt_1mab <- SQRT(1 - alpha_bar[t]) x_t <- sqrt_ab x0 + sqrt_1mab eps # closed-form forward sample eps_pred <- epsilon_theta(x_t, t) # network's noise estimate loss <- MEAN_SQUARED_ERROR(eps_pred, eps) UPDATE_PARAMETERS(epsilon_theta, GRADIENT(loss)) return epsilon_theta
# ---------- Sampling (ancestral sampling, DDPM) ---------- function SAMPLE(T, beta, alpha, alpha_bar, epsilon_theta): x <- SAMPLE_GAUSSIAN(shape=DATA_SHAPE) # x_T ~ N(0, I) for t in T, T-1, ..., 1: eps_pred <- epsilon_theta(x, t) coef1 <- 1 / SQRT(alpha[t]) coef2 <- beta[t] / SQRT(1 - alpha_bar[t]) mu <- coef1 (x - coef2 eps_pred) # posterior mean estimate if t > 1: sigma <- SQRT(beta[t]) # or posterior variance, see below z <- SAMPLE_GAUSSIAN(shape=DATA_SHAPE) else: sigma <- 0 z <- 0 x <- mu + sigma z return x # approx sample from data distribution ``` The training loop's correctness hinges entirely on the closed-form line `x_t <- sqrt_abx0 + sqrt_1mabeps`: it is exactly* a sample from by the reparameterization trick applied to a Gaussian, so no chain simulation, and no bias, is introduced. The sampling loop's mean formula `mu` comes from Bayes' rule applied to the forward process (derived in the next section) — it is the mean of with replaced by its estimate implied by .
Complexity & correctness
Time complexity. Training one step costs where is the cost of one forward/backward pass of the denoising network (typically a U-Net), independent of — this is because the closed-form reparameterization lets us jump directly to any without simulating intermediate steps. Sampling one image costs , since the reverse chain must be simulated sequentially, one network evaluation per timestep; this is the well-known efficiency bottleneck of diffusion models relative to single-pass generators like GANs or VAEs. Accelerated samplers (e.g. DDIM, higher-order solvers) reduce the effective number of sampling steps to with (often 20–50), by treating the reverse process as a discretized ODE/SDE rather than a strict Markov chain, but this is a refinement built on the same forward/reverse formalism.
Space complexity. for the network parameters , plus per sample for the data dimensionality (a single image tensor is stored and overwritten at each denoising step; no need to store the whole trajectory unless it is being visualized).
Correctness — the variational bound. The reverse process is trained to make close to the true data distribution. Since is intractable to compute directly, training instead maximizes a variational lower bound (an ELBO), exactly as in a hierarchical VAE:
This bound follows from Jensen's inequality applied to , the same derivation pattern used for the standard ELBO in variational autoencoders. Because the forward posterior is Gaussian (a consequence of being a linear-Gaussian chain, using Bayes' rule on jointly Gaussian variables), each KL term between two Gaussians has a closed form, reducible to a squared difference of means. Substituting the reparameterized forms of shows that this difference of means is proportional to — precisely the training loss used in the pseudocode above. In other words, minimizing the simple noise-prediction MSE loss is provably minimizing (a reweighted version of) a true variational bound on data log-likelihood, not an ad hoc heuristic.
Honest tradeoffs. The forward process being fixed (not learned) sacrifices some flexibility for tractability and stable training — there is no adversarial game and no mode collapse in the GAN sense. The price is slow sampling ( sequential network calls), high compute cost, and sensitivity to the noise schedule and number of steps: too few steps make the Gaussian reverse-step assumption inaccurate; too many steps waste compute. The variational bound is also a lower bound on likelihood, so a model can score well on the training objective while still producing samples with subtly wrong tails or texture — an accepted looseness in exchange for tractable, stable training.
Worked example
Consider a toy 1-D "image" that is literally a single pixel value, , so we can hand-trace the arithmetic. Use with a simple linear schedule for illustration.
| 1 | 0.10 | 0.90 | 0.900 | 0.949 | 0.316 |
| 2 | 0.20 | 0.80 | 0.720 | 0.849 | 0.529 |
| 3 | 0.30 | 0.70 | 0.504 | 0.710 | 0.704 |
| 4 | 0.40 | 0.60 | 0.302 | 0.550 | 0.835 |
Training-time forward sampling (closed form). Suppose training draws and samples noise (a fixed value here for tracing, instead of random, to make the arithmetic checkable). Then
The network is asked to output a prediction close to ; suppose it (imperfectly) outputs . The squared-error loss contribution is , and this drives a gradient update pushing 's prediction upward, toward , at input .
Sampling-time reverse walk. Now suppose after training, is reasonably accurate. Start from noise (drawn from , here fixed for the trace). At : suppose . Compute
Adding noise gives . Repeating this for (each time re-evaluating at the new and the corresponding ) walks the chain back toward values clustering near the original data mode — not exactly recovering or because sampling is stochastic and the network is imperfect, but statistically consistent with the data distribution the network was trained on. This mirrors the real algorithm: training touches one random per example using the closed form; sampling must traverse every from down to sequentially.
Common pitfalls & traps
| Pitfall | Why it happens | Consequence |
|---|---|---|
| Confusing training-time and sampling-time computation | Forgetting that training uses the closed-form jump to , while sampling must iterate the chain | Implementing training with an unnecessary -step loop, wasting compute |
| Wrong variance schedule scaling | Using directly as the reverse-step variance without checking whether posterior variance is more appropriate | Blurry or noisy samples, unstable low-step sampling |
| Off-by-one in indexing | Cumulative product started at wrong index or term mishandled | itself gets corrupted, or is not close enough to standard Gaussian |
| Predicting vs. predicting inconsistently | Mixing parameterizations (-prediction, -prediction, velocity-prediction) without converting formulas correctly | Loss looks fine numerically but the sampler produces garbage |
| Too few sampling steps at inference | Assuming a model trained with can be sampled with very few DDPM steps without a special fast sampler | Coarse Gaussian-transition assumption breaks, quality collapses |
| Ignoring numerical underflow in for large | Product of many terms close to 1 can still underflow in low precision | NaNs late in the forward chain, unstable training near |
Pioneers & history
The mathematical seed of diffusion models is the observation, borrowed from non-equilibrium statistical physics, that a complex distribution can be reached by slowly perturbing a simple one and that the perturbation process is invertible if simulated finely enough. This connects diffusion models to two adjacent lineages: variational inference (making the reverse chain trainable via an ELBO) and score matching / Langevin dynamics (an alternative, closely related view developed independently and unified with diffusion models in later work, which is the bridge to Denoising and Score-Based Models).
Origins · 1 minJascha Sohl-Dickstein and how this was discovered
Where this matters
Diffusion models now underpin most state-of-the-art image generation systems, including Stable Diffusion, Midjourney's backend, DALL·E 2/3, and Google's Imagen, all of which train a U-Net-style (often operating in a compressed latent space rather than pixel space, for efficiency) using exactly the forward/reverse machinery described here. The same framework generalizes beyond images: diffusion is used for audio and speech synthesis, video generation, 3D shape and molecule generation (important in drug discovery, where the data lives on non-Euclidean manifolds and the forward process must be adapted accordingly), and even as a component of reinforcement learning policies (diffusion policies for robotic control). The core forward-noising/reverse-denoising abstraction is also the conceptual bridge into score-based generative modeling, where the reverse process is reinterpreted as integrating an estimated score function — a connection formalized through stochastic differential equations and central to understanding modern accelerated samplers.
Ask the tutor: How does the score-based (score matching + Langevin dynamics) view of diffusion relate mathematically to the noise-prediction network described here?
Why use Gaussian noise specifically, rather than some other corruption process?
Gaussian noise is chosen because it makes both the forward marginal and the true reverse posterior analytically tractable Gaussians, thanks to closure properties of Gaussian distributions under linear combinations. This tractability is what allows a closed-form training loss and a simple parametric family (Gaussian) for the learned reverse transition. Other corruption processes (e.g. masking, blurring, or discrete corruption for categorical data) have been explored and can work, but they generally lose the clean closed-form marginal and posterior that make Gaussian diffusion both mathematically elegant and computationally cheap to train. The Gaussian choice also connects diffusion to well-studied continuous-time stochastic processes (Brownian motion, Ornstein-Uhlenbeck processes), enabling the SDE-based generalizations used in score-based modeling.
How is the number of steps chosen, and what happens if it's too small or too large?
trades off sample quality against sampling cost. If is too small, each forward step must add a large amount of noise to reach within so few steps, which makes the true reverse posterior far from Gaussian — violating the core approximation that lets a Gaussian work well. This produces blurry or artifact-laden samples. If is too large, training is largely unaffected (since training samples directly via the closed form), but sampling becomes extremely slow, since the reverse chain must be simulated sequentially for all steps. In practice around 1000 is common for training, with fast samplers (DDIM, DPM-Solver) used at inference to effectively collapse this to 20-50 evaluations without retraining.
What is the difference between predicting , predicting , and predicting the "velocity"?
These are three mathematically equivalent parameterizations of the same reverse mean, related by the closed-form relationship : given any one of , , or a linear combination called velocity , the others can be algebraically recovered. Empirically, -prediction (as in the original DDPM) tends to work well at moderate noise levels but can behave poorly at very high noise ( near ), where the signal is nearly all noise and predicting becomes numerically more stable, motivating - or -prediction variants used in some modern systems. The choice affects loss weighting and numerical stability far more than it affects the underlying variational bound, which is invariant to reparameterization.
Are diffusion models a special case of variational autoencoders?
Yes, in a precise technical sense: a diffusion model is a deep, hierarchical VAE where the "encoder" (the forward process) is fixed rather than learned, and the latent variables have the same dimensionality as the data rather than a lower-dimensional bottleneck. The training objective is derived exactly the way the standard VAE ELBO is derived, via Jensen's inequality applied to an importance-weighted marginal likelihood. The key structural differences are that the encoder has no learnable parameters, there are typically hundreds to thousands of latent layers instead of one, and each individual KL term between adjacent-timestep Gaussians is analytically tractable, which is what makes an otherwise enormous hierarchical model trainable at scale.
How does classifier-free guidance fit into this forward/reverse framework?
Classifier-free guidance modifies the reverse process to steer sampling toward a condition (such as a text prompt), without changing the forward process at all. During training, the network learns both a conditional noise predictor and an unconditional one , typically by randomly dropping the condition during training. At sampling time, the two predictions are linearly combined with a guidance scale , extrapolating away from the unconditional prediction toward the conditional one. This is a sampling-time modification layered on top of the same reverse Markov chain machinery, which is why it works with any diffusion backbone without retraining the forward process.
Why is sampling described as sequential — could the reverse steps be parallelized across timesteps?
The reverse steps cannot be parallelized across in the standard formulation because each step's input is only defined once has been sampled — it is a genuine Markov chain, not an independent set of computations. This is fundamentally different from training, where each minibatch example independently samples its own random via the closed form and requires no dependency on other timesteps. Research on faster samplers (DDIM, consistency models, distillation techniques) works around this sequential bottleneck by either reducing the number of necessary steps or by training a separate model to jump directly from noise to data in very few evaluations, but a plain DDPM reverse chain fundamentally requires sequential network calls.