lllyasviel/ControlNet · error · NotImplementedError

unknown loss type '{loss_type}'

Error message

unknown loss type '{loss_type}'

What it means

DDPM get_loss supports only 'l1' and 'l2' loss types; any other value in the diffusion config's loss_type parameter raises NotImplementedError. Note the message is a plain string so the placeholder will not interpolate — the raw '{loss_type}' text appears.

Source

Thrown at ldm/models/diffusion/ddpm.py:378

    def get_v(self, x, noise, t):
        return (
                extract_into_tensor(self.sqrt_alphas_cumprod, t, x.shape) * noise -
                extract_into_tensor(self.sqrt_one_minus_alphas_cumprod, t, x.shape) * x
        )

    def get_loss(self, pred, target, mean=True):
        if self.loss_type == 'l1':
            loss = (target - pred).abs()
            if mean:
                loss = loss.mean()
        elif self.loss_type == 'l2':
            if mean:
                loss = torch.nn.functional.mse_loss(target, pred)
            else:
                loss = torch.nn.functional.mse_loss(target, pred, reduction='none')
        else:
            raise NotImplementedError("unknown loss type '{loss_type}'")

        return loss

    def p_losses(self, x_start, t, noise=None):
        noise = default(noise, lambda: torch.randn_like(x_start))
        x_noisy = self.q_sample(x_start=x_start, t=t, noise=noise)
        model_out = self.model(x_noisy, t)

        loss_dict = {}
        if self.parameterization == "eps":
            target = noise
        elif self.parameterization == "x0":
            target = x_start
        elif self.parameterization == "v":
            target = self.get_v(x_start, noise, t)
        else:
            raise NotImplementedError(f"Parameterization {self.parameterization} not yet supported")

View on GitHub (pinned to ed85cd1e25)

Solutions

  1. Set loss_type to 'l1' or 'l2' exactly (lowercase) in your diffusion YAML
  2. If you need another loss, subclass DDPM and override get_loss
  3. Check for accidental capitalization like 'L2'

Example fix

# before
loss_type: mse
# after
loss_type: l2
Defensive patterns

Strategy: validation

Validate before calling

assert loss_type in ('l1', 'l2'), f"unsupported loss_type {loss_type!r}"

Type guard

def is_valid_loss_type(lt: str) -> bool:
    return lt in ('l1', 'l2')

Prevention

When it happens

Trigger: Configuring LatentDiffusion with parameters.loss_type set to something like 'mse', 'huber', or 'l1+l2', then running a training step (forward -> p_losses -> get_loss).

Common situations: Migrating configs from other diffusion repos (e.g. stable-diffusion uses 'L1'/'L2' uppercase in some forks); experimenting with perceptual losses not supported here.

Related errors


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