VerifiedarXiv:2010.0250225 min
Diffusion · Sampling

DDIM: Denoising Diffusion Implicit Models

Get 1,000-step diffusion quality from 20 to 100 steps, with the same trained network.

DDIM changes only the sampling loop of a diffusion model. It defines a family of samplers that all fit a network trained as a standard diffusion model (DDPM), and the deterministic member of that family can skip most of the 1,000 noise levels.

Explaining the paperDenoising Diffusion Implicit ModelsSong, Meng, Ermon · Stanford · ICLR 2021 · arXiv:2010.02502 ↗

Because the DDIM sampler is deterministic, the starting noise works as a latent code: the same code gives the same image at any step count, two codes can be blended, and a real image can be encoded and reconstructed.

Why DDPM sampling is slow

A denoising diffusion probabilistic model (DDPM) generates an image by starting from pure Gaussian noise and removing a little of it at a time. A standard DDPM uses T=1000T = 1000 noise levels, and every level costs one forward pass of a large U-Net, the image-to-image network that predicts the noise. The passes cannot run in parallel, because each one needs the output of the one before. The DDIM paper measures the cost on one Nvidia 2080 Ti: about 20 hours to sample 50,000 images of 32×3232\times32 pixels, against under a minute for a GAN, and nearly 1,000 hours for 50,000 images at 256×256256\times256.

Taking 50 large steps instead of 1,000 small ones would cut the cost 20×, but a DDPM sampler resists this because it was derived as the reverse of one particular noising process: a Markov chain in which each step adds a small amount of Gaussian noise to the previous step's output. The reverse of that chain is a 1,000-step procedure, and the DDPM derivation gives no reason why a 50-step version should work. DDIM's framework does justify skipping, for DDPM's sampler as well, but the results section shows the DDPM sampler still degrades fast when the steps are few.

DDIM keeps the trained network and derives a new sampler. The argument goes through four ideas, one section each after a short recap: the training loss only ever looks at one noise level at a time; so many different noising processes are compatible with the same trained network; one of them gives a deterministic sampler; and a deterministic sampler can take large steps and run backwards as an encoder.

What the trained network computes

DDIM reuses DDPM's training unchanged, so the notation comes first. The forward process turns an image x0\mathbf{x}_0 into noise over TT steps. For a 32×32 RGB image, x0\mathbf{x}_0 is a tensor of shape 3 × 32 × 32, 3,072 numbers scaled to [−1,1][-1, 1]. The forward process is built so that you can jump straight to any noise level tt in closed form:

q(xt∣x0)=N ⁣(αt x0, (1−αt)I),xt=αt x0+1−αt ϵ,ϵ∼N(0,I)q(\mathbf{x}_t \mid \mathbf{x}_0) = \mathcal{N}\!\big(\sqrt{\alpha_t}\,\mathbf{x}_0,\ (1-\alpha_t)\mathbf{I}\big), \qquad \mathbf{x}_t = \sqrt{\alpha_t}\,\mathbf{x}_0 + \sqrt{1-\alpha_t}\,\boldsymbol{\epsilon},\quad \boldsymbol{\epsilon}\sim\mathcal{N}(\mathbf{0},\mathbf{I})
(1)

αt\alpha_t is a number between 0 and 1 that falls as tt grows. It sets how much of the image survives: αt\sqrt{\alpha_t} scales the image down and 1−αt\sqrt{1-\alpha_t} scales the noise up, and because αt+(1−αt)=1\alpha_t + (1-\alpha_t) = 1 a unit-variance image stays at unit variance. With the CIFAR-10 schedule (per-step noise rising linearly from 10−410^{-4} to 0.02), α100=0.897\alpha_{100} = 0.897, α300=0.396\alpha_{300} = 0.396, α500=0.079\alpha_{500} = 0.079 and α1000=4.0×10−5\alpha_{1000} = 4.0\times10^{-5}. By convention α0=1\alpha_0 = 1, no noise at all.

The paper's αt\alpha_t is cumulative. It is the product of all the per-step signal factors up to step tt, the quantity the DDPM paper and most tutorials call αˉt\bar\alpha_t (alpha-bar). DDPM's per-step αt=1−βt\alpha_t = 1-\beta_t appears here as the ratio αt/αt−1\alpha_t/\alpha_{t-1}. The paper states this only in Appendix C.2, so formulas copied from a DDPM tutorial will look wrong next to it until the two notations are lined up. This page uses the cumulative αt\alpha_t throughout.

The network ϵθ(t)(xt)\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t) takes a noisy image and its noise level and returns a tensor of the same shape: its estimate of the noise ϵ\boldsymbol{\epsilon} that was mixed in. Training picks a training image, a level tt and a noise draw, builds xt\mathbf{x}_t with (1), and penalizes the squared error:

Lγ(ϵθ)=∑t=1Tγt Ex0, ϵ[∥ϵθ(t) ⁣(αt x0+1−αt ϵ)−ϵ∥22]L_{\boldsymbol{\gamma}}(\boldsymbol{\epsilon}_\theta) = \sum_{t=1}^{T} \gamma_t\, \mathbb{E}_{\mathbf{x}_0,\,\boldsymbol{\epsilon}}\Big[\big\lVert \boldsymbol{\epsilon}_\theta^{(t)}\!\big(\sqrt{\alpha_t}\,\mathbf{x}_0 + \sqrt{1-\alpha_t}\,\boldsymbol{\epsilon}\big) - \boldsymbol{\epsilon}\big\rVert_2^2\Big]
(2)

γ\boldsymbol{\gamma} is a vector of TT positive weights, one per noise level. DDPM trains with every weight equal to 1, which the paper writes L1L_{\mathbf{1}}. The subscript is the all-ones vector; the loss is a squared L2 error, not an L1 loss. The same L1L_{\mathbf{1}} objective trains the noise-conditional score networks of Song and Ermon, where it appears as denoising score matching, which is why DDPMs and score-based models can share one network.

Predicting the noise is equivalent to predicting the image, because (1) can be solved for x0\mathbf{x}_0. The network's guess of x0\mathbf{x}_0 is

x^0(xt)=xt−1−αt ϵθ(t)(xt)αt\hat{\mathbf{x}}_0(\mathbf{x}_t) = \frac{\mathbf{x}_t - \sqrt{1-\alpha_t}\ \boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t)}{\sqrt{\alpha_t}}
(3)

Take one pixel. Say αt=0.30\alpha_t = 0.30, the noisy pixel is xt=1.0x_t = 1.0, and the network predicts ϵ^=0.5\hat\epsilon = 0.5 for it. Then (3) gives

x^0=1.0−0.70⋅0.50.30=1.0−0.4180.548=1.062\hat x_0 = \frac{1.0 - \sqrt{0.70}\cdot 0.5}{\sqrt{0.30}} = \frac{1.0 - 0.418}{0.548} = 1.062

The loss only sees one noise level at a time

Look at what each term of (2) uses: one training image, one noise level, one noise draw. It builds xt\mathbf{x}_t directly from x0\mathbf{x}_0 with (1) and scores the network on undoing that single jump. No term involves xt\mathbf{x}_t and xt−1\mathbf{x}_{t-1} together, so the loss says nothing about how the noisy versions of one image at neighbouring levels are related. In probability terms, the loss depends only on the marginals q(xt∣x0)q(\mathbf{x}_t \mid \mathbf{x}_0), the distribution of the noisy image at each level on its own, and not on the joint distribution of the whole sequence x1,…,xT\mathbf{x}_1, \dots, \mathbf{x}_T.

An exam graded question by question against an answer key cannot tell in what order the student answered. In the same way, any noising process whose marginal at every level is (1) produces exactly the same loss, so the network trained for DDPM's process is also the trained network for any of them.

DDPM's Markov chain draws fresh noise at every step: xt\mathbf{x}_t is a scaled-down xt−1\mathbf{x}_{t-1} plus a small new Gaussian, a random walk whose per-step noise is sized so that its spread matches (1) at every level. A second process draws a single noise tensor ϵ\boldsymbol{\epsilon} once and builds every level from (1) with that same ϵ\boldsymbol{\epsilon}. Each xt\mathbf{x}_t on its own has distribution (1), so the marginals match, but the sequence is a smooth curve fixed by ϵ\boldsymbol{\epsilon}, where DDPM's is a jagged walk. The second process is the σ=0\sigma = 0 member of the family in the next section, the one behind DDIM. To reverse it, given xt\mathbf{x}_t and x0\mathbf{x}_0, recover ϵ\boldsymbol{\epsilon} from (1) and put it back at the lower level, with no new random draw.

A family of forward processes

The paper connects these two extremes with a family of processes indexed by a vector σ=(σ1,…,σT)\boldsymbol{\sigma} = (\sigma_1, \dots, \sigma_T) of non-negative numbers. Each member is specified by its reverse conditional, which says where xt−1\mathbf{x}_{t-1} is when both xt\mathbf{x}_t and x0\mathbf{x}_0 are known:

qσ(xt−1∣xt,x0)=N ⁣(αt−1 x0+1−αt−1−σt2⋅xt−αt x01−αt,  σt2I)q_{\boldsymbol{\sigma}}(\mathbf{x}_{t-1} \mid \mathbf{x}_t, \mathbf{x}_0) = \mathcal{N}\!\Big(\sqrt{\alpha_{t-1}}\,\mathbf{x}_0 + \sqrt{1-\alpha_{t-1}-\sigma_t^2}\cdot \frac{\mathbf{x}_t - \sqrt{\alpha_t}\,\mathbf{x}_0}{\sqrt{1-\alpha_t}},\ \ \sigma_t^2\mathbf{I}\Big)
(4)

Read the mean in two parts. αt−1 x0\sqrt{\alpha_{t-1}}\,\mathbf{x}_0 is x0\mathbf{x}_0 scaled for level t−1t-1. The fraction (xt−αtx0)/1−αt(\mathbf{x}_t - \sqrt{\alpha_t}\mathbf{x}_0)/\sqrt{1-\alpha_t} is the unit noise that is in xt\mathbf{x}_t, recovered by solving (1); the mean reuses it with weight 1−αt−1−σt2\sqrt{1-\alpha_{t-1}-\sigma_t^2}. On top of the mean, the step adds fresh Gaussian noise with variance σt2\sigma_t^2.

The weight is chosen so that the noise variances add up to what (1) requires at level t−1t-1. The reused noise has unit variance, so it contributes 1−αt−1−σt21-\alpha_{t-1}-\sigma_t^2; the fresh noise contributes σt2\sigma_t^2; and independent variances add:

(1−αt−1−σt2)⏟reused noise+σt2⏟fresh noise=1−αt−1\underbrace{(1-\alpha_{t-1}-\sigma_t^2)}_{\text{reused noise}} + \underbrace{\sigma_t^2}_{\text{fresh noise}} = 1-\alpha_{t-1}

The sum is the noise variance of the marginal (1) at level t−1t-1, whatever σt\sigma_t is. The paper proves the general statement (Lemma 1): every σ\boldsymbol{\sigma} gives a process with marginals exactly (1) at every level. The square root needs σt2≤1−αt−1\sigma_t^2 \le 1-\alpha_{t-1}, a condition the paper leaves implicit. At σt=0\sigma_t = 0 the step adds nothing new and xt−1\mathbf{x}_{t-1} is a fixed function of xt\mathbf{x}_t and x0\mathbf{x}_0, the reuse-one-noise process from the previous section. At the particular σt\sigma_t given in (6) below, the family reproduces DDPM's Markov chain.

Figure 1 draws sample paths from the family for one clean pixel. The amber band is the marginal (1), which the family is built to keep fixed. Drag η\eta, a single scale on all the σt\sigma_t that (6) makes precise, and watch the paths change while the band stays put:

Figure 1 · same marginals, different joints
η = 0.00
The amber band is the marginal q(x_t | x₀), identical for every η. The teal paths are samples from the σ family, all ending at the same clean x₀. At η = 0 each path is a smooth curve fixed by its noise endpoint; at η = 1 it is a random walk. Drag η between them.

The paths at different η\eta are different processes, so a natural worry is that each needs its own trained network. The paper's Theorem 1 answers it. Each member of the family has its own variational training objective JσJ_{\boldsymbol{\sigma}} (the evidence lower bound a model would be trained on if that member were its forward process), and for every σ>0\boldsymbol{\sigma} > \mathbf{0} there exist positive weights γ\boldsymbol{\gamma} and a constant CC with

Jσ(ϵθ)=Lγ(ϵθ)+CJ_{\boldsymbol{\sigma}}(\boldsymbol{\epsilon}_\theta) = L_{\boldsymbol{\gamma}}(\boldsymbol{\epsilon}_\theta) + C

The weights γ\boldsymbol{\gamma} depend on σ\boldsymbol{\sigma}, so this is a reweighted version of (2), not L1L_{\mathbf{1}} itself. The step to "the DDPM network works for every σ" uses one more fact: if the network had separate weights for each noise level, each term of (2) could be minimized on its own, and the minimizer would not depend on γ\boldsymbol{\gamma}. A real network shares one set of weights across all levels, so that step is an idealization. The experiments show that the L1L_{\mathbf{1}}-trained network samples well across the family.

How one DDIM sampling step works

At sampling time x0\mathbf{x}_0 is unknown. The sampler substitutes the network's guess x^0\hat{\mathbf{x}}_0 from (3) into the reverse conditional (4), and the recovered unit noise becomes the network's prediction ϵθ\boldsymbol{\epsilon}_\theta. That gives one update rule for every member of the family:

xt−1=αt−1 x^0(xt)⏟predicted x0+1−αt−1−σt2 ϵθ(t)(xt)⏟direction pointing to xt+σt ϵt⏟random noise\mathbf{x}_{t-1} = \sqrt{\alpha_{t-1}}\ \underbrace{\hat{\mathbf{x}}_0(\mathbf{x}_t)}_{\text{predicted } \mathbf{x}_0} + \underbrace{\sqrt{1-\alpha_{t-1}-\sigma_t^2}\ \boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t)}_{\text{direction pointing to } \mathbf{x}_t} + \underbrace{\sigma_t\,\boldsymbol{\epsilon}_t}_{\text{random noise}}
(5)

The labels are the paper's. The first term places the predicted image at the next level's scale. The second adds back the predicted noise, scaled for the next level; it points from the guess toward xt\mathbf{x}_t, and it is deterministic, because ϵθ(t)(xt)\boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t) is a fixed output of the network. Only the third term, a fresh draw ϵt∼N(0,I)\boldsymbol{\epsilon}_t \sim \mathcal{N}(\mathbf{0},\mathbf{I}) times σt\sigma_t, is random.

Set σt=0\sigma_t = 0 at every step and nothing random is left after the initial draw of xT\mathbf{x}_T. The paper calls the resulting model the denoising diffusion implicit model. "Implicit" is used in the sense of an implicit probabilistic model, one that produces samples by pushing a latent variable (here xT\mathbf{x}_T) through a fixed procedure (here the sampling loop), as a GAN does, instead of defining a density step by step.

Continue the one-pixel example, stepping from αt=0.30\alpha_t = 0.30 to αt−1=0.45\alpha_{t-1} = 0.45. The noise budget at the new level is 1−αt−1=0.551-\alpha_{t-1} = 0.55. With σt=0\sigma_t = 0 all of it goes to the reused noise:

xt−1=0.45⋅1.062+0.55⋅0.5=0.712+0.371=1.083x_{t-1} = \sqrt{0.45}\cdot 1.062 + \sqrt{0.55}\cdot 0.5 = 0.712 + 0.371 = 1.083

This puts the pixel exactly where it would sit at level t−1t-1 if x^0=1.062\hat x_0 = 1.062 were the true image and 0.50.5 the true noise. With the DDPM value of σt\sigma_t from (6) below, σt=0.512\sigma_t = 0.512 and the direction coefficient drops to 0.55−0.262=0.537\sqrt{0.55 - 0.262} = 0.537, so the mean is 0.712+0.537⋅0.5=0.9810.712 + 0.537\cdot 0.5 = 0.981 and the pixel lands at 0.981+0.512 z0.981 + 0.512\,z for a fresh standard normal zz. Figure 2 does the same split in two dimensions, with an exact denoiser for a four-cluster toy dataset:

Figure 2 · one sampling step, three terms
η = 0.00
From the noisy xₜ the denoiser predicts x̂₀. The next point is the scaled guess plus a teal deterministic step plus a violet cloud of fresh noise. The bar shows the two noise variances against the budget 1 − αₜ₋₁ = 0.55. Drag η past 1 to the edge where the deterministic term is zero; the button switches to the σ̂ update, whose variance overshoots the budget.

To compare deterministic and random sampling with one knob, the paper scales a fixed shape of σ\boldsymbol{\sigma} by a scalar η≥0\eta \ge 0:

σt(η)=η 1−αt−11−αt 1−αtαt−1\sigma_{t}(\eta) = \eta\,\sqrt{\frac{1-\alpha_{t-1}}{1-\alpha_{t}}}\,\sqrt{1-\frac{\alpha_{t}}{\alpha_{t-1}}}
(6)

η=0\eta = 0 is DDIM. η=1\eta = 1 is DDPM: with this σ\boldsymbol{\sigma} the forward process becomes Markovian again and (5) is DDPM's own sampler. Values in between are valid samplers that use the same network. In the worked step, η\eta can go up to 1.449 before σt2\sigma_t^2 uses the whole budget and the direction term vanishes; that is the right end of the slider in Figure 2.

The paper also tests a third setting, σ^t=1−αt/αt−1\hat\sigma_t = \sqrt{1-\alpha_t/\alpha_{t-1}}, the larger variance used in Ho et al.'s code for their CIFAR-10 samples. It is not a point on the η\eta line. Appendix D.3 gives its update: the same first two terms as η=1\eta = 1, with noise σ^tϵt\hat\sigma_t\boldsymbol{\epsilon}_t in place of σt(1) ϵt\sigma_t(1)\,\boldsymbol{\epsilon}_t. In the worked step σ^t=0.577\hat\sigma_t = 0.577, so the total noise variance is 0.288+0.333=0.6210.288 + 0.333 = 0.621, 13% more than the 0.55 that (1) calls for. Between adjacent levels of the 1,000-step CIFAR-10 schedule the excess is at most 10−410^{-4}; across a large skip it is large, and the paper attributes σ^\hat\sigma's poor few-step results to this extra noise.

Skipping steps

The marginals argument also allows skipping. The derivation of (4) and (5) never used the fact that t−1t-1 is adjacent to tt; it only needs the marginal (1) at the two levels involved. So pick an increasing subsequence τ=(τ1,…,τS)\tau = (\tau_1, \dots, \tau_S) of 1,…,T1, \dots, T, define the process on those levels alone, and sample along τ\tau in reverse, replacing tt and t−1t-1 in (5) with τi\tau_i and τi−1\tau_{i-1}. The cost is SS network calls instead of TT, and the network is the one trained on all 1,000 levels.

The paper tries two spacings, each of the form τi=⌊c i⌋\tau_i = \lfloor c\,i\rfloor (linear) or τi=⌊c i2⌋\tau_i = \lfloor c\,i^2\rfloor (quadratic), with cc set so the last level is close to TT. Quadratic spacing puts more steps at low noise, where fine detail is resolved. It used quadratic for CIFAR-10 and linear for the other datasets, reporting that each gave slightly better FID than the alternative on its dataset. Figure 3 plots both against the CIFAR-10 schedule's noise variance:

Figure 3 · which levels the sampler visits
S = 20
The 1,000 training levels from clean (left) to noise (right), with the noise variance 1 − αₜ of the CIFAR-10 schedule. Teal dots are the S levels the sampler visits, joined by the jumps it takes. Drag S from 1 to 100 and switch between linear and quadratic spacing; the readout counts how many visited levels fall at t ≤ 200.

Under this schedule the noise variance passes 0.92 by t=500t = 500, so with linear spacing about half of the visited levels sit where the image is almost all noise. At S=20S = 20, linear spacing puts 4 levels at t≤200t \le 200 and quadratic puts 8.

Whether skipping works well depends on η\eta. A large jump makes x^0\hat{\mathbf{x}}_0 a cruder estimate, because the network has to guess x0\mathbf{x}_0 from a much noisier input. The deterministic update then carries that estimate's own predicted noise forward, while the stochastic one replaces part of it with fresh noise that the remaining few steps must remove. The full sampler is one loop for every setting:

# One sampling run. Same trained eps_theta for every setting;
# only tau (which levels) and eta (how much fresh noise) change.
def sample(eps_theta, alpha, tau, eta):  # alpha[t]: cumulative, alpha[0] = 1
    x = randn(3, 32, 32)                 # x_T: pure Gaussian noise
    for i in reversed(range(len(tau))):  # walk reversed(tau): noise -> data
        t = tau[i]                       # current level
        s = tau[i - 1] if i > 0 else 0   # next, less noisy level
        a_t, a_s = alpha[t], alpha[s]
        eps = eps_theta(x, t)                          # one network call
        x0 = (x - sqrt(1 - a_t) * eps) / sqrt(a_t)     # eq (3)
        sig = eta * sqrt((1 - a_s) / (1 - a_t)) * sqrt(1 - a_t / a_s)  # eq (6)
        dir = sqrt(1 - a_s - sig**2) * eps             # deterministic
        x = sqrt(a_s) * x0 + dir + sig * randn(3, 32, 32)  # eq (5)
    return x                                           # a sample x_0

Each pass through the loop is one network call, so S=50S = 50 costs 50 forward passes. With eta = 0 the randn inside the loop is multiplied by zero and the only randomness is the first line.

How much faster, at what quality

The paper trains one model per dataset at T=1000T = 1000 with L1L_{\mathbf{1}} and changes only τ\tau and η\eta. Quality is measured with FID (Fréchet Inception Distance), which compares statistics of generated and real images in the feature space of an image classifier; lower is better. Figure 4 plots the paper's Table 1 for DDIM, DDPM and σ^\hat\sigma:

Figure 4 · FID against number of steps
S = 10
FID (log scale, lower is better) against sampling steps S for one trained model, from the paper's Table 1. DDIM stays usable at 10 steps; DDPM and σ̂ degrade fast as S falls, and σ̂ is the best of the three at S = 1000. Drag S and switch the dataset.

On CIFAR-10 at 10 steps, DDIM scores 13.36, DDPM 41.07 and σ^\hat\sigma 367.43. At 100 steps DDIM reaches 4.16, close to its own 1,000-step 4.04. On CelebA the 100-step DDPM (13.93) matches the 20-step DDIM (13.73), so DDIM gets there with a fifth of the network calls. The two intermediate settings in Table 1 fall in between at every step count: at 10 steps on CIFAR-10, η=0.2\eta = 0.2 gives 14.04 and η=0.5\eta = 0.5 gives 16.66.

The paper's headline is that DDIM matches 1,000-step quality in 20 to 100 steps, which it states as a 10× to 50× speedup in wall-clock time. Sampling time is linear in the number of steps, so a 50-step run takes about 1/20 of the 1,000-step time; the 20 hours for 50,000 CIFAR-10 images become roughly one. The paper also writes "10× to 100×" in two places, as the range of step reductions it tests (1,000 steps down to 100 or 10), not as a matched-quality figure.

At the full 1,000 steps the order flips: σ^\hat\sigma scores 3.17 on CIFAR-10 against DDIM's 4.04, and 3.26 against 3.51 on CelebA. With every step taken, the added noise helps a little; DDIM's advantage is confined to small step counts, the regime that sets sampling cost.

The starting noise as a latent code

With σt=0\sigma_t = 0 the sample is a deterministic function of xT\mathbf{x}_T. The paper finds that this function barely depends on the step count: for a fixed xT\mathbf{x}_T, images generated with 10, 20, 50, 100 and 1,000 steps share their high-level features, such as pose, layout and colors, and the 20-step image is often already very close to the 1,000-step one.

Figure 5 shows the same effect in a toy. Eight fixed starting points are each decoded by the exact denoiser of an eight-cluster dataset. A ring marks where each lands with a 100-step run, a dot where it lands with SS steps. Under DDIM the dots sit on their rings from about 4 steps up. Switch to DDPM and the dots move off their rings at every SS, including 100, because the reference run draws its own fresh noise:

Figure 5 · same start, same result
S = 6
Eight fixed starts x_T decoded by the same denoiser. A ring marks a separate 100-step run, a dot the S-step run. Drag S from 1 to 100 and switch between DDIM and DDPM. At S = 1 every start lands near the middle, since one step returns the averaged guess x̂₀.

Since xT\mathbf{x}_T determines the image, it works like the latent code of a GAN or a variational autoencoder. The paper interpolates in it: draw two codes xT(0)\mathbf{x}_T^{(0)} and xT(1)\mathbf{x}_T^{(1)}, blend them, decode each blend with 50 DDIM steps, and the images change smoothly from one sample to the other. The blend is spherical linear interpolation (slerp), not a straight average:

xT(λ)=sin⁡((1−λ)θ)sin⁡θ xT(0)+sin⁡(λθ)sin⁡θ xT(1),θ=arccos⁡xT(0)⋅xT(1)∥xT(0)∥ ∥xT(1)∥\mathbf{x}_T^{(\lambda)} = \frac{\sin\big((1-\lambda)\theta\big)}{\sin\theta}\,\mathbf{x}_T^{(0)} + \frac{\sin(\lambda\theta)}{\sin\theta}\,\mathbf{x}_T^{(1)}, \qquad \theta = \arccos\frac{\mathbf{x}_T^{(0)}\cdot\mathbf{x}_T^{(1)}}{\lVert\mathbf{x}_T^{(0)}\rVert\,\lVert\mathbf{x}_T^{(1)}\rVert}

The paper does not say why it chose slerp, but the geometry of high-dimensional Gaussians gives a reason. A 3,072-dimensional standard normal vector almost always has length close to 3072≈55.4\sqrt{3072} \approx 55.4, give or take about 2. Two independent codes are nearly orthogonal, so their straight-line midpoint has length about 55.4/2≈39.255.4/\sqrt 2 \approx 39.2, a length the network never saw at t=Tt = T. Slerp moves along the arc between the codes and keeps the length near 55.4. Figure 6 plots the length along both blends:

Figure 6 · straight versus spherical blend
λ = 0.50
d = 3072
Length of the blended code divided by √d, from z₁ to z₂. Violet: straight-line blend. Teal: slerp. The amber band holds 99% of standard-normal codes. Drag λ along the blend and d from 2 up to 12,288; the band narrows as d grows and the straight-line midpoint leaves it.

A DDPM cannot do this with one code, because its output also depends on the fresh noise drawn at every step: the same xT\mathbf{x}_T gives a different image on each run. The paper notes that interpolating all TT noise draws might work instead. Running the deterministic sampler backwards gives the remaining latent-code operation, finding the code of a real image, covered in the next section.

DDIM as an ODE solver

The deterministic update can be rewritten as one step of Euler's method, the simplest numerical method for an ordinary differential equation (ODE): from the current point, move a step along the current velocity. Change variables to xˉ=x/α\bar{\mathbf{x}} = \mathbf{x}/\sqrt{\alpha} and σ=1−α/α\sigma = \sqrt{1-\alpha}/\sqrt{\alpha}. By (1), xˉt=x0+σt ϵ\bar{\mathbf{x}}_t = \mathbf{x}_0 + \sigma_t\,\boldsymbol{\epsilon}: the clean image plus σt\sigma_t times unit noise, with σt\sigma_t growing from 0 at the clean end to 157 at t=1000t = 1000 on the CIFAR-10 schedule. (This σt\sigma_t is a different quantity from the sampler's noise scale in (4) to (6); the overloaded symbol is the paper's.) The DDIM update (5) with σt=0\sigma_t = 0 becomes

xˉt−1=xˉt+ϵθ(t)(xt) (σt−1−σt)\bar{\mathbf{x}}_{t-1} = \bar{\mathbf{x}}_t + \boldsymbol{\epsilon}_\theta^{(t)}(\mathbf{x}_t)\,\big(\sigma_{t-1} - \sigma_t\big)

an Euler step with step size σt−1−σt\sigma_{t-1}-\sigma_t for the ODE

dxˉ(t)=ϵθ(t) ⁣(xˉ(t)σ2+1) dσ(t)\mathrm{d}\bar{\mathbf{x}}(t) = \boldsymbol{\epsilon}_\theta^{(t)}\!\Big(\frac{\bar{\mathbf{x}}(t)}{\sqrt{\sigma^2+1}}\Big)\,\mathrm{d}\sigma(t)
(7)

The network's noise prediction is the velocity and σ\sigma plays the role of time. Since σ2+1=1/α\sigma^2 + 1 = 1/\alpha, the network input xˉ/σ2+1\bar{\mathbf{x}}/\sqrt{\sigma^2+1} is just xt\mathbf{x}_t, the kind of noisy image it was trained on. Check it on the one-pixel example, where σt=0.70/0.30=1.528\sigma_t = \sqrt{0.70/0.30} = 1.528, σt−1=0.55/0.45=1.106\sigma_{t-1} = \sqrt{0.55/0.45} = 1.106 and xˉt=1.0/0.30=1.826\bar x_t = 1.0/\sqrt{0.30} = 1.826. The Euler step lands on the DDIM result from before:

xˉt−1=1.826+0.5 (1.106−1.528)=1.615xt−1=1.615⋅0.45=1.083\begin{aligned} \bar x_{t-1} &= 1.826 + 0.5\,(1.106 - 1.528) = 1.615 \\ x_{t-1} &= 1.615\cdot\sqrt{0.45} = 1.083 \end{aligned}

An ODE can be integrated in either direction. Run the same update from the clean end toward the noisy end and it encodes an image into its xT\mathbf{x}_T; run it back and it decodes. Each direction makes discretization error, so the round trip lands near the start, not on it, and the gap shrinks as steps are added. Figure 7 runs both directions on a one-dimensional toy with three data clusters, where the denoiser is exact and only step size causes error:

Figure 7 · encode, then decode
S = 6
x₀ = 1.30
Time runs left (data, t = 0) to right (code, t = 1000); faint lines are 1000-step paths. The teal polyline encodes the chosen x₀ in S steps, the amber one decodes the result in S steps. Drag S and the start x₀; the button switches between the round trip, encoding alone and decoding the 1000-step code.

In the default view (6 steps, x0=1.30x_0 = 1.30), the code comes out at 0.77 instead of the 1,000-step value 1.04, and decoding it lands at 0.80, between two clusters and 0.50 away from the start. At 20 steps the miss is 0.012, and at 100 steps 0.004. The paper measures the same thing on the CIFAR-10 test set, encoding and decoding with the same SS and reporting per-dimension squared error with pixels scaled to [0,1][0, 1]:

steps S (encode and decode)squared error per pixel
100.014
200.0065
500.0023
1000.0009
2000.0004
5000.0001
10000.0001

An error of 0.0009 is a root-mean-square pixel error of 0.03, about 8 levels out of 255. A DDPM has no such round trip, because decoding draws new noise at every step. The encoder is the sampling loop run forwards:

# Encoding: the same update with eta = 0, run from clean to noisy.
def encode(eps_theta, alpha, tau, x):    # x: a real image x_0
    levels = [0] + list(tau)             # 0 -> tau_1 -> ... -> tau_S
    for t, s in zip(levels[:-1], levels[1:]):   # s > t: noisier
        eps = eps_theta(x, t)
        x0 = (x - sqrt(1 - alpha[t]) * eps) / sqrt(alpha[t])
        x = sqrt(alpha[s]) * x0 + sqrt(1 - alpha[s]) * eps
    return x                             # x_T, the image's code

Equation (7) also connects DDIM to score-based SDEs, which describe diffusion in continuous time and come with a deterministic "probability flow" ODE. Proposition 1 of the paper shows that, with the optimal network, (7) is the probability flow ODE of the variance-exploding SDE, the continuous-time form of the NCSN noise process. That ODE is usually written in dt\mathrm{d}t with a factor 12g(t)2\tfrac12 g(t)^2; (7) is written in dσ\mathrm{d}\sigma with no ½, and the change of variables dσ2/dt=2σ dσ/dt\mathrm{d}\sigma^2/\mathrm{d}t = 2\sigma\,\mathrm{d}\sigma/\mathrm{d}t absorbs the ½. The two samplers still differ: DDIM takes Euler steps in σ\sigma, the score-SDE sampler takes them in tt, and with few steps those land in different places. The view of sampling as solving an ODE with a learned velocity also links DDIM to Neural ODEs, which Section 5.4 cites alongside normalizing flows when describing the round trip.

Provenance Verified against primary literatureHow we verify
DDPM (Ho, Jain & Abbeel, 2020)The forward process, the noise-prediction network and the γ = 1 objective, all reused unchanged. DDIM trains nothing new.
NCSN (Song & Ermon, 2019); Vincent (2011)The γ = 1 objective is the denoising score matching objective of noise-conditional score networks; the paper says so in Section 2.
Score SDEs (Song et al., 2021)Proposition 1: with the optimal model, DDIM's ODE (14) is equivalent to the probability flow ODE of the variance-exploding SDE. The two samplers still differ: DDIM takes Euler steps in σ, the score-SDE sampler in t.
Neural ODEs (Chen et al., 2018)Section 5.4 compares DDIM's encode-then-decode round trip to Neural ODEs and normalizing flows.
Shoemake (1985)Spherical linear interpolation, used in Appendix D.5 (Eq. 67) to interpolate between two noise codes x_T.
Official code, ermongroup/ddimfunctions/denoising.py lines 25-29 compute Eq. (16) and Eq. (12) exactly (c1 = σ, c2 = the direction coefficient). The σ̂ sampler (ddpm_steps) clips x̂₀ to [-1, 1] (line 54) and uses variance 1 - α_t/α_{t-1} (line 64). runners/diffusion.py lines 343-353: uniform τ = range(0, T, T//S); quadratic τ = int(linspace(0, √(0.8T), S)²), so the quadratic schedule stops near t = 800 of 1000.
caveatNotation, not an error: the paper's α_t is the cumulative product of the per-step signal factors, the quantity DDPM and most tutorials write as ᾱ_t (alpha-bar). DDPM's per-step α_t = 1 − β_t corresponds here to the ratio α_t/α_{t-1}. The paper states this mapping only in Appendix C.2, so a reader coming from DDPM sees equations that look wrong until they find it. Every equation on this page uses the cumulative α.

Questions you might still have

?

Do I need to retrain my diffusion model to use DDIM?
No. Every DDIM result in the paper uses one network per dataset, trained with the ordinary DDPM loss at T = 1000. Theorem 1 shows that each member of the σ family has a training objective equal to a weighted DDPM loss plus a constant. If the network had separate parameters for each noise level, the loss weighting γ would not matter and the DDPM-trained network would be optimal for every σ. Real networks share parameters across levels, so the transfer is an idealization that the experiments confirm.

?

Is DDIM just DDPM with fewer steps?
No. Both can skip steps, since the skipping argument only uses the marginals. The difference is the update: DDPM (η = 1) adds fresh noise at every step, DDIM (η = 0) adds none. With 10 steps on CIFAR-10 the same network scores FID 13.36 under DDIM and 41.07 under DDPM.

?

Why is it called "implicit"?
In the sense of an implicit probabilistic model: samples come from a latent variable through a fixed procedure, as in a GAN, rather than from a density you can write down step by step. With σ = 0 the latent is the starting noise x_T and the procedure is the deterministic sampling loop. The update formula itself is explicit.

?

If DDIM is deterministic, where does sample diversity come from?
From x_T. Each sample starts from a fresh Gaussian draw of the full image size (3,072 numbers for a 32×32 RGB image), and the deterministic loop maps different draws to different images. Determinism means the same draw always gives the same image.

?

Is DDIM always better than DDPM?
In the η family, yes, in every column of Table 1: FID rises with η at every step count, and at 1,000 steps CIFAR-10 goes 4.04, 4.09, 4.29, 4.73 for η = 0, 0.2, 0.5, 1. The exception is σ̂, the larger-variance DDPM from Ho et al.'s code, which beats DDIM at 1,000 steps (3.17 vs 4.04 on CIFAR-10, 3.26 vs 3.51 on CelebA) and is far worse at 10 steps (367.43).

?

Can DDPM interpolate between images too?
Not by blending one x_T, because a DDPM sample also depends on the fresh noise drawn at every step, so the same x_T gives different images. The paper notes in a footnote that interpolating all T noise draws, as done for NCSN, might work. DDIM needs only the one code.

?

How does DDIM relate to the probability flow ODE of score SDEs?
With the optimal network they describe the same ODE: DDIM's update is an Euler step of the variance-exploding probability flow ODE written in terms of σ. They differ as samplers, because DDIM takes each Euler step in σ between the chosen levels while the score-SDE sampler steps in t, and with few steps the two land in different places. The Score SDEs explainer covers the continuous-time view.

Footnotes & further reading

  1. The paper: Song, Meng, Ermon, Denoising Diffusion Implicit Models (Stanford, ICLR 2021). Official code.
  2. The model and objective DDIM reuses: Ho, Jain, Abbeel, Denoising Diffusion Probabilistic Models (our explainer: DDPM). The α/ᾱ notation map is in DDIM's Appendix C.2.
  3. The score, SDE and probability flow ODE view: Song et al., Score-Based Generative Modeling through Stochastic Differential Equations (our explainer: Score SDEs), and the denoising score matching objective in NCSN.
  4. Residual networks read as Euler integration of an ODE: Chen et al., Neural Ordinary Differential Equations (our explainer: Neural ODEs).
  5. Figure 4 and the reconstruction table are transcribed from the paper's Tables 1 and 2. Figures 2, 5 and 7 use exact denoisers for small Gaussian-mixture datasets, so their errors come from step size alone; the CIFAR-10 schedule values (α₁₀₀ = 0.897, α₅₀₀ = 0.079, σ at t = 1000 ≈ 157) are computed from the linear schedule in the official config.
  6. For how DDPM, score matching and SDEs fit together, see the diffusion tutorial explainer; for another deterministic generator trained by regression, see flow matching; and for a model whose paper samples with DDIM, see latent diffusion.