Comfy-Org/ComfyUI · error · ValueError
eta must be 0 for reverse sampling
Error message
eta must be 0 for reverse sampling
What it means
Raised by DPMSolver.dpm_solver_fast. DPM-Solver-Fast integrates from t_start (high sigma) toward t_end; eta adds stochastic noise whose Brownian correction is only defined in the forward (denoising) direction. If t_end <= t_start (a reverse pass) and eta is nonzero, the solver refuses instead of producing incorrect SDE dynamics.
Source
Thrown at comfy/k_diffusion/sampling.py:530
return x_2, eps_cache
def dpm_solver_3_step(self, x, t, t_next, r1=1 / 3, r2=2 / 3, eps_cache=None):
eps_cache = {} if eps_cache is None else eps_cache
h = t_next - t
eps, eps_cache = self.eps(eps_cache, 'eps', x, t)
s1 = t + r1 * h
s2 = t + r2 * h
u1 = x - self.sigma(s1) * (r1 * h).expm1() * eps
eps_r1, eps_cache = self.eps(eps_cache, 'eps_r1', u1, s1)
u2 = x - self.sigma(s2) * (r2 * h).expm1() * eps - self.sigma(s2) * (r2 / r1) * ((r2 * h).expm1() / (r2 * h) - 1) * (eps_r1 - eps)
eps_r2, eps_cache = self.eps(eps_cache, 'eps_r2', u2, s2)
x_3 = x - self.sigma(t_next) * h.expm1() * eps - self.sigma(t_next) / r2 * (h.expm1() / h - 1) * (eps_r2 - eps)
return x_3, eps_cache
def dpm_solver_fast(self, x, t_start, t_end, nfe, eta=0., s_noise=1., noise_sampler=None):
noise_sampler = default_noise_sampler(x, seed=self.extra_args.get("seed", None)) if noise_sampler is None else noise_sampler
if not t_end > t_start and eta:
raise ValueError('eta must be 0 for reverse sampling')
m = math.floor(nfe / 3) + 1
ts = torch.linspace(t_start, t_end, m + 1, device=x.device)
if nfe % 3 == 0:
orders = [3] * (m - 2) + [2, 1]
else:
orders = [3] * (m - 1) + [nfe % 3]
for i in range(len(orders)):
eps_cache = {}
t, t_next = ts[i], ts[i + 1]
if eta:
sd, su = get_ancestral_step(self.sigma(t), self.sigma(t_next), eta)
t_next_ = torch.minimum(t_end, self.t(sd))
su = (self.sigma(t_next) ** 2 - self.sigma(t_next_) ** 2) ** 0.5
else:
t_next_, su = t_next, 0.View on GitHub (pinned to 1c6d8d45b3)
Solutions
- Pass bounds in denoising order: sigma_max first (e.g. 14.6) then sigma_min (e.g. 0.03)
- If you truly need reverse integration, set eta=0.0 and s_noise handling accordingly
- Double-check custom sampler wrappers for swapped positional args
Example fix
# before sample_dpm_fast(model, x, sigma_min=14.6, sigma_max=0.03, n=20, eta=1.0) # after sample_dpm_fast(model, x, sigma_min=0.03, sigma_max=14.6, n=20, eta=1.0)
Defensive patterns
Strategy: validation
Validate before calling
assert sigma_max > sigma_min > 0, 'bounds must be in denoising order and positive'
if sigma_max < sigma_min:
eta = 0.0
sample_dpm_fast(model, x, sigma_min, sigma_max, n, eta=eta) Prevention
- Keep sigma_max (large) first and sigma_min (small) second in dpm_fast/adaptive calls
- Force eta=0 whenever running reverse integration
When it happens
Trigger: Calling sample_dpm_fast with eta > 0 while sigma_max < sigma_min (reversed bounds), or programmatically invoking dpm_solver_fast(x, t_start, t_end) with t_end < t_start and eta != 0.
Common situations: Custom nodes swapping sigma_min/sigma_max arguments; scripts reusing sample_dpm_adaptive/fast argument order from another sampler; experiments that try to run the diffusion process 'backwards' (adding noise) with eta left at default 1.
Related errors
- Passing a list or tuple of seeds to BatchedBrownianTree requ
- order should be 2 or 3
- sigma_min and sigma_max must not be 0
- solver_type must be 'heun' or 'midpoint'
- Unsupported noise schedule {}. The schedule needs to be 'dis
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/e536f616f99f85e6.
Report an issue: GitHub.