lllyasviel/ControlNet · error · ValueError

Unsupported noise schedule {}. The schedule needs to be 'dis

Error message

Unsupported noise schedule {}. The schedule needs to be 'discrete' or 'linear' or 'cosine'

What it means

NoiseScheduleVP (DPM-Solver) supports exactly three noise schedules: 'discrete' (uses alphas_cumprod or betas), 'linear' (continuous beta_0/beta_1), and 'cosine'. Any other schedule string is rejected at construction.

Source

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

        ===============================================================
        Args:
            schedule: A `str`. The noise schedule of the forward SDE. 'discrete' for discrete-time DPMs,
                    'linear' or 'cosine' for continuous-time DPMs.
        Returns:
            A wrapper object of the forward SDE (VP type).

        ===============================================================
        Example:
        # For discrete-time DPMs, given betas (the beta array for n = 0, 1, ..., N - 1):
        >>> ns = NoiseScheduleVP('discrete', betas=betas)
        # For discrete-time DPMs, given alphas_cumprod (the \hat{alpha_n} array for n = 0, 1, ..., N - 1):
        >>> ns = NoiseScheduleVP('discrete', alphas_cumprod=alphas_cumprod)
        # For continuous-time DPMs (VPSDE), linear schedule:
        >>> ns = NoiseScheduleVP('linear', continuous_beta_0=0.1, continuous_beta_1=20.)
        """

        if schedule not in ['discrete', 'linear', 'cosine']:
            raise ValueError(
                "Unsupported noise schedule {}. The schedule needs to be 'discrete' or 'linear' or 'cosine'".format(
                    schedule))

        self.schedule = schedule
        if schedule == 'discrete':
            if betas is not None:
                log_alphas = 0.5 * torch.log(1 - betas).cumsum(dim=0)
            else:
                assert alphas_cumprod is not None
                log_alphas = 0.5 * torch.log(alphas_cumprod)
            self.total_N = len(log_alphas)
            self.T = 1.
            self.t_array = torch.linspace(0., 1., self.total_N + 1)[1:].reshape((1, -1))
            self.log_alpha_array = log_alphas.reshape((1, -1,))
        else:
            self.total_N = 1000
            self.beta_0 = continuous_beta_0
            self.beta_1 = continuous_beta_1

View on GitHub (pinned to ed85cd1e25)

Solutions

  1. Use exactly 'discrete', 'linear', or 'cosine'
  2. For a trained DDPM, use NoiseScheduleVP('discrete', alphas_cumprod=model.alphas_cumprod)
  3. Update to a newer DPM-Solver version if you need additional schedules

Example fix

# before
NoiseScheduleVP('Discrete', alphas_cumprod=ac)
# after
NoiseScheduleVP('discrete', alphas_cumprod=ac)
Defensive patterns

Strategy: validation

Validate before calling

assert schedule in ('discrete', 'linear', 'cosine'), f"unsupported schedule {schedule!r}"

Type guard

def is_valid_schedule(s: str) -> bool:
    return s in ('discrete', 'linear', 'cosine')

Prevention

When it happens

Trigger: Creating NoiseScheduleVP with schedule='Discrete', 'sigmoid', 'vp', etc., or a typo'd value passed from a sampling script config.

Common situations: Porting sampler code from k-diffusion or newer DPM-Solver++ forks with more schedule names; case-sensitivity mistakes; passing schedule=None.

Related errors


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