lllyasviel/ControlNet · error · ValueError

'solver_type' must be either 'dpm_solver' or 'taylor', got {

Error message

'solver_type' must be either 'dpm_solver' or 'taylor', got {}

What it means

Second-order singlestep updates accept solver_type 'dpm_solver' (recommended) or 'taylor' (Taylor expansion variant). Any other string raises this ValueError at the start of singlestep_dpm_solver_second_update, reached via singlestep_dpm_solver_update or dpm_solver_adaptive.

Source

Thrown at ldm/models/diffusion/dpm_solver/dpm_solver.py:533

    def singlestep_dpm_solver_second_update(self, x, s, t, r1=0.5, model_s=None, return_intermediate=False,
                                            solver_type='dpm_solver'):
        """
        Singlestep solver DPM-Solver-2 from time `s` to time `t`.
        Args:
            x: A pytorch tensor. The initial value at time `s`.
            s: A pytorch tensor. The starting time, with the shape (x.shape[0],).
            t: A pytorch tensor. The ending time, with the shape (x.shape[0],).
            r1: A `float`. The hyperparameter of the second-order solver.
            model_s: A pytorch tensor. The model function evaluated at time `s`.
                If `model_s` is None, we evaluate the model by `x` and `s`; otherwise we directly use it.
            return_intermediate: A `bool`. If true, also return the model value at time `s` and `s1` (the intermediate time).
            solver_type: either 'dpm_solver' or 'taylor'. The type for the high-order solvers.
                The type slightly impacts the performance. We recommend to use 'dpm_solver' type.
        Returns:
            x_t: A pytorch tensor. The approximated solution at time `t`.
        """
        if solver_type not in ['dpm_solver', 'taylor']:
            raise ValueError("'solver_type' must be either 'dpm_solver' or 'taylor', got {}".format(solver_type))
        if r1 is None:
            r1 = 0.5
        ns = self.noise_schedule
        dims = x.dim()
        lambda_s, lambda_t = ns.marginal_lambda(s), ns.marginal_lambda(t)
        h = lambda_t - lambda_s
        lambda_s1 = lambda_s + r1 * h
        s1 = ns.inverse_lambda(lambda_s1)
        log_alpha_s, log_alpha_s1, log_alpha_t = ns.marginal_log_mean_coeff(s), ns.marginal_log_mean_coeff(
            s1), ns.marginal_log_mean_coeff(t)
        sigma_s, sigma_s1, sigma_t = ns.marginal_std(s), ns.marginal_std(s1), ns.marginal_std(t)
        alpha_s1, alpha_t = torch.exp(log_alpha_s1), torch.exp(log_alpha_t)

        if self.predict_x0:
            phi_11 = torch.expm1(-r1 * h)
            phi_1 = torch.expm1(-h)

            if model_s is None:

View on GitHub (pinned to ed85cd1e25)

Solutions

  1. Use solver_type='dpm_solver' (default, recommended) or 'taylor'
  2. Omit the parameter to take the default rather than passing a guess
  3. Validate against the allowed set in your sampling config loader

Example fix

# before
update = dpm.singlestep_dpm_solver_update(x, s, t, order=2, solver_type='dpm_solver++')
# after
update = dpm.singlestep_dpm_solver_update(x, s, t, order=2, solver_type='dpm_solver')
Defensive patterns

Strategy: validation

Validate before calling

assert solver_type in ('dpm_solver', 'taylor'), f"unsupported solver_type {solver_type!r}"

Type guard

def is_valid_solver_type(s: str) -> bool:
    return s in ('dpm_solver', 'taylor')

Prevention

When it happens

Trigger: Passing solver_type='dpm_solver++', 'DPM', 'taylor1', or None to a second-order update path (order=2 sampling or adaptive solver).

Common situations: Confusing this DPM-Solver release with DPM-Solver++ option names; typos in sampler parameter dicts.

Related errors


AI-assisted analysis of lllyasviel/ControlNet@ed85cd1e25 (2026-08-27). Data as JSON: /api/errors/84b2e9dff3cc23f4. Report an issue: GitHub.