I've trained a Denoising Diffusion Probabilistic Model (DDPM), but the inference speed is killing my project. It takes nearly a minute to generate a single image because it requires 1000 sequential denoising steps. I've read that Denoising Diffusion Implicit Models (DDIM) can use the exact same pre-trained weights but generate high-quality images in just 20–50 steps.
How do I actually implement the non-Markovian sampling for DDIM? Specifically, how do I define the new sub-sequence of timesteps, and what does the deterministic update rule look like in code? Also, if I set $\eta = 0$, does that make the generation completely deterministic (same noise = same image every time)?
3 answers
If you're using PyTorch, you don't need to manually derive the noise schedules. Most developers in 2026 use the diffusers library, where switching to DDIM is a simple swap of the "Scheduler."
The beauty of DDIM is that it requires zero retraining. You use your existing $\epsilon_\theta$ (U-Net) that was trained for DDPM. The trick is changing the "path" you take through the noise. While DDPM assumes a Markov chain (where $x_{t-1}$ depends only on $x_t$), DDIM uses a non-Markovian approach that allows you to "jump" over timesteps.
To implement this, you first define a sub-sequence of timesteps $\tau$ (e.g., [1, 50, 100, ..., 1000]). The update rule then predicts a "clean" $x_0$ at every step and uses it to point toward the next less-noisy state. By setting the variance parameter $\sigma$ to 0 (often called $\eta=0$), the process becomes deterministic. This means if you start with the same initial Gaussian noise, you will always get the exact same image, which is incredibly useful for debugging or fine-tuning prompts.
For those looking for the absolute "speed king," DDIM also enables Inversion. You can take a real image, find the noise that generated it (deterministic reverse), edit the prompt, and generate a new image that preserves the original structure.
I agree with Steven. The deterministic nature of DDIM effectively turns the diffusion process into an ODE (Ordinary Differential Equation) solver. This is why we can use even more advanced solvers like DPMSolver++ now, which can get decent images in as few as 10–15 steps. If your project is latency-sensitive, start with DDIM at 20 steps and increase only if you see "ringing" artifacts in the fine details.
That’s true, but understanding the math helps when you're customizing the pipeline. The DDIM update rule is essentially:$$x_{\tau_{i-1}} = \sqrt{\alpha_{\tau_{i-1}}} \left( \frac{x_{\tau_i} - \sqrt{1 - \alpha_{\tau_i}} \epsilon_\theta(x_{\tau_i}, \tau_i)}{\sqrt{\alpha_{\tau_i}}} \right) + \sqrt{1 - \alpha_{\tau_{i-1}} - \sigma_{\tau_i}^2} \cdot \epsilon_\theta(x_{\tau_i}, \tau_i) + \sigma_{\tau_i} \epsilon$$When $\sigma=0$, that last random noise term ($\epsilon$) vanishes. In our tests, we found that DDIM at 50 steps often produces lower FID scores (better quality) than DDPM at 1000 steps because it avoids the "random walk" drift that happens with too many stochastic additions.