{"record":{"id":"bc09e4df913fa6ed","repo":"lllyasviel/Fooocus","slug":"eta-must-be-0-for-reverse-sampling","errorCode":null,"errorMessage":"eta must be 0 for reverse sampling","messagePattern":"eta must be 0 for reverse sampling","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ldm_patched/k_diffusion/sampling.py","lineNumber":376,"sourceCode":"        return x_2, eps_cache\n\n    def dpm_solver_3_step(self, x, t, t_next, r1=1 / 3, r2=2 / 3, eps_cache=None):\n        eps_cache = {} if eps_cache is None else eps_cache\n        h = t_next - t\n        eps, eps_cache = self.eps(eps_cache, 'eps', x, t)\n        s1 = t + r1 * h\n        s2 = t + r2 * h\n        u1 = x - self.sigma(s1) * (r1 * h).expm1() * eps\n        eps_r1, eps_cache = self.eps(eps_cache, 'eps_r1', u1, s1)\n        u2 = x - self.sigma(s2) * (r2 * h).expm1() * eps - self.sigma(s2) * (r2 / r1) * ((r2 * h).expm1() / (r2 * h) - 1) * (eps_r1 - eps)\n        eps_r2, eps_cache = self.eps(eps_cache, 'eps_r2', u2, s2)\n        x_3 = x - self.sigma(t_next) * h.expm1() * eps - self.sigma(t_next) / r2 * (h.expm1() / h - 1) * (eps_r2 - eps)\n        return x_3, eps_cache\n\n    def dpm_solver_fast(self, x, t_start, t_end, nfe, eta=0., s_noise=1., noise_sampler=None):\n        noise_sampler = default_noise_sampler(x) if noise_sampler is None else noise_sampler\n        if not t_end > t_start and eta:\n            raise ValueError('eta must be 0 for reverse sampling')\n\n        m = math.floor(nfe / 3) + 1\n        ts = torch.linspace(t_start, t_end, m + 1, device=x.device)\n\n        if nfe % 3 == 0:\n            orders = [3] * (m - 2) + [2, 1]\n        else:\n            orders = [3] * (m - 1) + [nfe % 3]\n\n        for i in range(len(orders)):\n            eps_cache = {}\n            t, t_next = ts[i], ts[i + 1]\n            if eta:\n                sd, su = get_ancestral_step(self.sigma(t), self.sigma(t_next), eta)\n                t_next_ = torch.minimum(t_end, self.t(sd))\n                su = (self.sigma(t_next) ** 2 - self.sigma(t_next_) ** 2) ** 0.5\n            else:\n                t_next_, su = t_next, 0.","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/lllyasviel/Fooocus/blob/ae05379cc97bc4361ec8b4ec90193dab21be763f/ldm_patched/k_diffusion/sampling.py#L358-L394","documentation":"In DPMSolver.dpm_solver_fast, stochastic noise injection (eta>0) is only physically defined when integrating forward in log-SNR time (t_end > t_start); the Brownian correction assumes increasing t. When t_end <= t_start (reverse/inversion direction) and eta is nonzero, it raises ValueError. sample_dpm_fast forwards eta through, so callers can trigger it via the wrapper.","triggerScenarios":"Calling sample_dpm_fast(..., sigma_min > sigma_max, eta=1.0) — i.e. swapped sigma bounds producing a reversed schedule — or calling dpm_solver_fast directly with t_end < t_start and eta != 0.","commonSituations":"Prompt-inversion / noise-scheduling experiments that run the ODE backwards; accidentally swapping sigma_min and sigma_max arguments; UIs exposing an eta slider while sigma order is reversed.","solutions":["Set eta=0 when sampling in reverse (t_end <= t_start).","For forward sampling ensure sigma_max > sigma_min (schedule goes high noise -> low noise).","Use sample_dpm_adaptive or the deterministic dpm_solver variants for reverse ODE work.","Validate argument order at the call site: sample_dpm_fast(model, x, sigma_min=0.1, sigma_max=10.0, ...)."],"exampleFix":"# before\nx = sample_dpm_fast(model, x, 10.0, 0.1, n=20, eta=1.0)  # reversed + eta -> ValueError\n\n# after (reverse pass must be deterministic)\nx = sample_dpm_fast(model, x, 10.0, 0.1, n=20, eta=0.0)","handlingStrategy":"validation","validationCode":"if eta != 0 and sigma_min >= sigma_max:\n    raise ValueError('eta must be 0 when sampling in reverse (sigma_min >= sigma_max)')\neta = 0 if sigma_min >= sigma_max else eta","typeGuard":"def can_use_eta(sigma_min: float, sigma_max: float, eta: float) -> bool:\n    return eta == 0 or sigma_max > sigma_min","tryCatchPattern":"try:\n    x = sample_dpm_fast(model, x, sigma_min, sigma_max, n, eta=eta)\nexcept ValueError as e:\n    if 'eta must be 0' in str(e):\n        x = sample_dpm_fast(model, x, sigma_min, sigma_max, n, eta=0.)\n    else:\n        raise","preventionTips":["Force eta=0 for reverse-direction (inversion) runs.","Validate 0 < sigma_min < sigma_max whenever eta > 0.","Keep deterministic and stochastic sampler configs separate."],"tags":["k-diffusion","dpm-solver","sampler-config","eta"],"backgroundTag":null,"analyzedSha":"ae05379cc97bc4361ec8b4ec90193dab21be763f","analyzedAt":"2026-08-15T04:23:59.533Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}