Stability-AI/generative-models · error · NotImplementedError
Unknown optimizer_idx {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.
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)
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.