lllyasviel/Fooocus · error · ValueError

solver_type must be 'heun' or 'midpoint'

Error message

solver_type must be 'heun' or 'midpoint'

What it means

sample_dpmpp_2m_sde implements the 2M SDE variant with two internal derivative predictors — midpoint and Heun — selected by solver_type. The step-update math is written per variant, so any other string raises ValueError before the noise sampler is constructed (the check runs before BrownianTreeNoiseSampler setup).

Source

Thrown at ldm_patched/k_diffusion/sampling.py:600

            callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised})
        t, t_next = t_fn(sigmas[i]), t_fn(sigmas[i + 1])
        h = t_next - t
        if old_denoised is None or sigmas[i + 1] == 0:
            x = (sigma_fn(t_next) / sigma_fn(t)) * x - (-h).expm1() * denoised
        else:
            h_last = t - t_fn(sigmas[i - 1])
            r = h_last / h
            denoised_d = (1 + 1 / (2 * r)) * denoised - (1 / (2 * r)) * old_denoised
            x = (sigma_fn(t_next) / sigma_fn(t)) * x - (-h).expm1() * denoised_d
        old_denoised = denoised
    return x

@torch.no_grad()
def sample_dpmpp_2m_sde(model, x, sigmas, extra_args=None, callback=None, disable=None, eta=1., s_noise=1., noise_sampler=None, solver_type='midpoint'):
    """DPM-Solver++(2M) SDE."""

    if solver_type not in {'heun', 'midpoint'}:
        raise ValueError('solver_type must be \'heun\' or \'midpoint\'')

    seed = extra_args.get("seed", None)
    sigma_min, sigma_max = sigmas[sigmas > 0].min(), sigmas.max()
    noise_sampler = BrownianTreeNoiseSampler(x, sigma_min, sigma_max, seed=seed, cpu=True) if noise_sampler is None else noise_sampler
    extra_args = {} if extra_args is None else extra_args
    s_in = x.new_ones([x.shape[0]])

    old_denoised = None
    h_last = None
    h = None

    for i in trange(len(sigmas) - 1, disable=disable):
        denoised = model(x, sigmas[i] * s_in, **extra_args)
        if callback is not None:
            callback({'x': x, 'i': i, 'sigma': sigmas[i], 'sigma_hat': sigmas[i], 'denoised': denoised})
        if sigmas[i + 1] == 0:
            # Denoising step
            x = denoised

View on GitHub (pinned to ae05379cc9)

Solutions

  1. Use solver_type='midpoint' (default) or solver_type='heun'.
  2. Normalize user input: solver_type.strip().lower() before the call.
  3. Validate against {'heun','midpoint'} in your config schema/UI before queueing.
  4. If you wanted a different SDE solver, pick the appropriate sampler function instead of changing solver_type.

Example fix

# before
x = sample_dpmpp_2m_sde(model, x, sigmas, solver_type='euler')  # ValueError

# after
x = sample_dpmpp_2m_sde(model, x, sigmas, solver_type='midpoint')
Defensive patterns

Strategy: validation

Validate before calling

solver_type = solver_type.strip().lower()
if solver_type not in {'heun', 'midpoint'}:
    raise ValueError(f"solver_type must be 'heun' or 'midpoint', got {solver_type!r}")

Type guard

def is_valid_solver_type(s: str) -> bool:
    return isinstance(s, str) and s.strip().lower() in {'heun', 'midpoint'}

Try / catch

try:
    x = sample_dpmpp_2m_sde(model, x, sigmas, solver_type=solver_type)
except ValueError as e:
    if 'solver_type' in str(e):
        x = sample_dpmpp_2m_sde(model, x, sigmas, solver_type='midpoint')
    else:
        raise

Prevention

When it happens

Trigger: Calling sample_dpmpp_2m_sude(..., solver_type='heun ') with trailing whitespace, 'midpoint2', 'euler', or capitalized 'Midpoint'; or forwarding a UI dropdown value that does not exactly match.

Common situations: Frontends that offer extra solver names for other samplers (e.g. 'ddim', 'euler') and pass them through; hand-typed config strings; copy-paste from sample_dpmpp_sde docs where the accepted set differs.

Related errors


AI-assisted analysis of lllyasviel/Fooocus@ae05379cc9 (2026-08-15). Data as JSON: /api/errors/9b9daf6617619e00. Report an issue: GitHub.