Part G · Sampling › Sampling is solving an ODE

Module 4·Part G — Sampling·15 min

Sampling is solving an ODE

The reverse SDE has a deterministic twin with the same marginals. Once you see the probability-flow ODE, DDIM stops being a trick and becomes Euler.

The core mental model

The forward process is an SDE, and every diffusion SDE has a reverse-time SDE that undoes it, whose drift needs exactly one unknown quantity — the score, which Module 1 showed your network already estimates. That reverse SDE is DDPM sampling. The important result is the next one: ,

SDEstep+noisestep+noisestep+noisestep+noisestep+noisesamplestochasticPF-ODEone smooth trajectory — solvable, invertiblesampledeterministict: noise → data
The same marginals, two ways of reaching them. The SDE injects fresh noise at every step, so each run traces a different path and the sample is a draw. The probability-flow ODE drops the noise term: one smooth trajectory per starting point, reproducible, invertible, and solvable by any integrator you like. Identical distributions at every time; completely different objects to compute with.
dxdt=f(x,t)12g(t)2xlogpt(x),\frac{dx}{dt} = f(x,t) - \tfrac{1}{2} g(t)^2 \nabla_x \log p_t(x),

the probability-flow ODE. Same marginals means that if you start from the same prior and integrate it exactly, you sample from the same distribution as the SDE — you have simply removed the injected noise and put the randomness entirely in the initial condition.

That reframing pays immediately, and it is worth being explicit about why. Sampling is now numerical integration of a smooth vector field, so the entire ODE-solver literature applies: step-size control, higher-order methods, local truncation error, stiffness. The step count stops being a mysterious quality knob and becomes a discretisation budget with known error behaviour. DDIM, which was originally derived as a non-Markovian variant of DDPM, turns out to be exactly the first-order Euler discretisation of this ODE in a particular parameterisation — which is why it works with far fewer steps than DDPM and why its output is a deterministic function of the initial noise.

Determinism is the second payoff and it is not merely aesthetic. A deterministic map from xTx_T to x0x_0 is invertible: run the ODE backwards from a real image to recover the noise that would produce it (DDIM inversion), which is the basis of real-image editing, and it makes the latent space genuinely navigable — interpolating between two noises produces a smooth semantic interpolation, which is not true of the stochastic sampler. The cost is that stochasticity was doing something useful: injected noise corrects accumulated error, because it keeps pulling the trajectory back toward the true marginal. Purely deterministic sampling has no such mechanism, so its errors compound.

The formulas and the numbers

The samplers, ordered by how many network evaluations each needs before it stops looking wrong:

SamplerOrderSteps for good qualityDeterministic
DDPM (ancestral)1250–1000no
DDIM120–50yes (η=0\eta=0)
Heun / EDM220–36 (2 NFE per step)yes
DPM-Solver++ (2M)215–25yes
UniPC2–310–20yes
Ancestral / SDE variants130–100no
ConceptStatement
Reverse SDE driftfg2logptf - g^2\nabla\log p_t, plus gdwˉg\,d\bar w
Probability-flow ODE driftf12g2logptf - \tfrac12 g^2\nabla\log p_t — the factor of two is the whole difference
DDIM updatext1=αˉt1x^0+1αˉt1ε^x_{t-1} = \sqrt{\bar\alpha_{t-1}}\hat x_0 + \sqrt{1-\bar\alpha_{t-1}}\,\hat\varepsilon
DDIM η\eta00 = ODE, 11 = DDPM; interpolates
NFEnetwork evaluations — the only cost that matters
Local truncation errorO(hp+1)O(h^{p+1}) per step, O(hp)O(h^p) global, for order pp

Critical thinking

If the ODE and the SDE have the same marginals, why keep the SDE at all?

Because “same marginals” holds for exact integration, and you are not integrating exactly.

The stochastic sampler has a self-correcting property. Each step injects fresh noise and then partially denoises it, which repeatedly re-projects the trajectory toward the true marginal at that noise level. If a step lands you slightly off the manifold of plausible xtx_t, the next injection plus denoise pulls you back. Errors do not accumulate so much as get repeatedly washed out.

The deterministic sampler has no such mechanism. Every local truncation error is carried forward and compounds, so with too few steps you get systematic artefacts rather than noisy ones — and because the map is deterministic, those artefacts are reproducible rather than averaging away.

The practical trade, then:

  • Few steps, need speed → deterministic, higher-order solver. Error is dominated by discretisation, and higher order attacks it directly.
  • Many steps, want maximum quality/diversity → some stochasticity. EDM’s “churn” parameter makes this explicit, adding a controlled amount of noise per step as a tunable knob rather than a binary choice.
  • Need invertibility, editing, or reproducibility → deterministic, no option.

EDM’s framing is the right one: stochasticity is not part of the model, it is a solver setting that trades error correction against added variance, and it should be tuned like a step size.

Show that DDIM is Euler on the probability-flow ODE.

Write the DDIM update in its standard form:

xt1=αˉt1x^0(xt)+1αˉt1ε^(xt),x^0=xt1αˉtε^αˉt.x_{t-1} = \sqrt{\bar\alpha_{t-1}}\,\hat x_0(x_t) + \sqrt{1-\bar\alpha_{t-1}}\,\hat\varepsilon(x_t), \qquad \hat x_0 = \frac{x_t - \sqrt{1-\bar\alpha_t}\,\hat\varepsilon}{\sqrt{\bar\alpha_t}} .

Now change variables to xˉ=x/αˉ\bar x = x/\sqrt{\bar\alpha} and σ=(1αˉ)/αˉ\sigma = \sqrt{(1-\bar\alpha)/\bar\alpha} — the VE coordinates from Module 1. Substituting, the update collapses to

xˉt1=xˉt+(σt1σt)ε^(xt),\bar x_{t-1} = \bar x_t + (\sigma_{t-1} - \sigma_t)\,\hat\varepsilon(x_t),

which is precisely an Euler step of dxˉ/dσ=ε^d\bar x/d\sigma = \hat\varepsilon with step size σt1σt\sigma_{t-1}-\sigma_t. And ε^\hat\varepsilon is the score up to a factor, so this is the probability-flow ODE.

Three things follow that are not obvious from the original derivation:

  • The step count is a discretisation budget, so error is O(h)O(h) globally and halving the step size roughly halves the error. Higher-order solvers do better than that, which is the entire point of Module 5.
  • Non-uniform spacing is legitimate and expected — Module 3’s step placement is adaptive quadrature, not a hack.
  • DDIM is the worst solver you would ever choose given the same NFE budget, because it is first-order. It survives as a default only because it is simple and was first.

What does DDIM inversion actually give you, and where does it break?

It gives an approximate inverse of the sampling map: integrate the ODE forward in noise from a real image x0x_0 to obtain the xTx_T that would regenerate it. That noise is then an editable handle — change the prompt, re-sample from the same xTx_T, and you get a modified version of the same image rather than an unrelated one. This is the foundation of most real-image editing pipelines.

Where it breaks, in the order you will hit the problems:

  1. Guidance. Inversion assumes the vector field you integrate backward is the one you will integrate forward. With classifier-free guidance at scale w>1w > 1 (Module 6) the sampling field is not the model’s score field, so the round trip does not close. Reconstruction error grows sharply with ww, and this is why null-text inversion and its successors exist — they optimise the unconditional embedding to make the round trip close under guidance.
  2. Discretisation asymmetry. Forward and reverse integration use the same step count but linearise at different points, so the two trajectories differ at O(h)O(h) even with perfect score. More steps helps and costs linearly.
  3. Off-manifold drift. The recovered xTx_T is usually not distributed like N(0,I)\mathcal{N}(0,I); it lands somewhere the model was never trained on, so edits can behave unpredictably.

The framing that makes it tractable: inversion inherits every property of the solver. It is exact only in the limit of exact integration of the same field you will use going forward, and every deviation from that — guidance, step count, a different scheduler — shows up as reconstruction error.

How would you decide, empirically, whether your sampler or your model is the limiting factor?

Push the solver toward exactness and see whether the problem survives.

The test. Sample with a high-order solver at very large NFE — say DPM-Solver++ at 200 steps, or Heun at 100 — and compare against your production setting. Anything that disappears was discretisation error; anything that remains is the model, and no sampler will fix it.

That single experiment separates the two most commonly confused failure modes, and it is cheap because you only need enough samples to see the difference, not a full evaluation run.

Then localise it. If it is the solver:

  • Sweep NFE and plot your metric. A curve still descending at your operating point means you are simply under-integrating.
  • Compare solvers at equal NFE, never equal step count.
  • Check step placement (Module 3) before reaching for a fancier solver; misplaced steps often cost more than solver order gains.

If it is the model, the next question is which noise band is at fault, which sends you back to Module 2’s per-λ\lambda loss and Module 3’s schedule.

A useful sanity check on top: with a deterministic solver, fix the seed and vary only NFE. If the image’s content changes rather than just its detail, you are integrating so coarsely that the trajectory is landing in a different basin — a much more serious regime than mere blur, and one that no amount of step tuning at the low-noise end will address.

Self-check

Write the probability-flow ODE and say what distinguishes it from the reverse SDE.

dx/dt=f(x,t)12g(t)2xlogpt(x)dx/dt = f(x,t) - \tfrac12 g(t)^2\nabla_x \log p_t(x). The reverse SDE has g2g^2 rather than 12g2\tfrac12 g^2 in the drift, plus a gdwˉg\,d\bar w noise term. They share marginals at every tt, so exact integration of either samples the same distribution — the ODE just moves all randomness into the initial condition.

Sketch why DDIM is Euler on that ODE.

In VE coordinates xˉ=x/αˉ\bar x = x/\sqrt{\bar\alpha}, σ=(1αˉ)/αˉ\sigma = \sqrt{(1-\bar\alpha)/\bar\alpha}, the DDIM update becomes xˉt1=xˉt+(σt1σt)ε^\bar x_{t-1} = \bar x_t + (\sigma_{t-1}-\sigma_t)\hat\varepsilon — an Euler step of dxˉ/dσ=ε^d\bar x/d\sigma = \hat\varepsilon, and ε^\hat\varepsilon is the score up to a factor. So step count is a discretisation budget with O(h)O(h) global error, non-uniform spacing is principled, and DDIM is the weakest solver you would pick at fixed NFE.

Why keep any stochasticity if the ODE has the same marginals?

Because equality of marginals assumes exact integration. Injected noise re-projects the trajectory toward the true marginal each step, washing out local error; the deterministic sampler compounds it into reproducible, systematic artefacts. So: few steps → deterministic higher-order; many steps and maximum quality → some churn; editing or reproducibility → deterministic necessarily. EDM treats stochasticity as a tunable solver setting rather than a property of the model.

Why must sampler comparisons be made at equal NFE?

Because a second-order solver evaluates the network twice per step, so 20 Heun steps cost the same as 40 DDIM steps. NFE is the only quantity that maps to wall-clock and money; step count does not. Comparisons at equal step count systematically flatter higher-order methods, and a number of published speedups do not survive the correction.

Name the main reason DDIM inversion fails to round-trip.

Classifier-free guidance. Inversion assumes you integrate back along the same vector field you will integrate forward, but at guidance scale w>1w>1 the sampling field is not the model’s score field, so the round trip does not close and reconstruction error grows with ww. Secondary causes: O(h)O(h) discretisation asymmetry between the two directions, and the recovered xTx_T not being distributed like N(0,I)\mathcal{N}(0,I).

How do you tell whether the sampler or the model is your bottleneck?

Sample at very high NFE with a high-order solver and compare against production settings. Whatever disappears was discretisation error; whatever remains is the model. Then sweep NFE and plot the metric, compare solvers at equal NFE, and check step placement before reaching for a fancier solver. If content rather than detail changes as NFE varies at fixed seed, you are integrating so coarsely that trajectories land in different basins.