Stability-AI/generative-models · error · NotImplementedError
Unknown optimizer_idx
Error message
Unknown optimizer_idx {optimizer_idx} What it means
The discriminator loss module's forward computes either the generator loss (optimizer_idx 0) or discriminator loss (optimizer_idx 1); any other value hits the else and raises this NotImplementedError. Like error 6, it means the training loop is invoking the loss with an unexpected optimizer index.
Solutions
- Pass optimizer_idx 0 (generator) or 1 (discriminator) only when calling the loss.
- Ensure the Lightning module's configure_optimizers returns exactly two optimizers when using this dual-objective loss.
- If manual optimization is used, loop over exactly [0, 1] and pass the matching index into each forward call.
Example fix
// before
for idx in range(3):
loss, log = disc_loss(inputs, reconstructions, split="train", optimizer_idx=idx)
// after
for idx in (0, 1):
loss, log = disc_loss(inputs, reconstructions, split="train", optimizer_idx=idx) Defensive patterns
Strategy: validation
Validate before calling
# before each loss call in manual optimization
assert optimizer_idx in (0, 1), f"optimizer_idx must be 0 (gen) or 1 (disc), got {optimizer_idx}" Try / catch
try:
loss, log = disc_loss(x, rec, split="train", optimizer_idx=idx)
except NotImplementedError as e:
if "Unknown optimizer_idx" in str(e):
raise RuntimeError("Loss supports optimizer_idx 0/1 only") from e Prevention
- Iterate exactly over (0, 1) in dual-generator/discriminator loops.
- Prefer Lightning automatic optimization over hand-rolled optimizer_idx loops.
When it happens
Trigger: Calling LPIPSWithDiscriminator(..., optimizer_idx=2) directly, or training a Lightning module whose loop passes an optimizer_idx outside {0,1} into this loss's forward.
Common situations: Older-Lightning-style manual optimization loops passing optimizer_idx; custom training scripts iterating over more than two optimizers; copied training_step code with wrong indexing.
Related errors
AI-assisted analysis of Stability-AI/generative-models@e8cd657656 (2026-08-29).
Data as JSON: /api/errors/242d976ae0f51c0d.
Report an issue: GitHub.
Appendix: source
Thrown at sgm/modules/autoencoding/losses/discriminator_loss.py:292
return loss, log
elif optimizer_idx == 1:
# second pass for discriminator update
logits_real = self.discriminator(inputs.contiguous().detach())
logits_fake = self.discriminator(reconstructions.contiguous().detach())
if global_step >= self.discriminator_iter_start or not self.training:
d_loss = self.disc_factor * self.disc_loss(logits_real, logits_fake)
else:
d_loss = torch.tensor(0.0, requires_grad=True)
log = {
f"{split}/loss/disc": d_loss.clone().detach().mean(),
f"{split}/logits/real": logits_real.detach().mean(),
f"{split}/logits/fake": logits_fake.detach().mean(),
}
return d_loss, log
else:
raise NotImplementedError(f"Unknown optimizer_idx {optimizer_idx}")
def get_nll_loss(
self,
rec_loss: torch.Tensor,
weights: Optional[Union[float, torch.Tensor]] = None,
) -> Tuple[torch.Tensor, torch.Tensor]:
nll_loss = rec_loss / torch.exp(self.logvar) + self.logvar
weighted_nll_loss = nll_loss
if weights is not None:
weighted_nll_loss = weights * nll_loss
weighted_nll_loss = torch.sum(weighted_nll_loss) / weighted_nll_loss.shape[0]
nll_loss = torch.sum(nll_loss) / nll_loss.shape[0]
return nll_loss, weighted_nll_loss
View on GitHub (pinned to e8cd657656)