pytorch runtime_error ai_generated true

RuntimeError: step() called before loss.backward(). Ensure you call loss.backward() before optimizer.step().

ID: pytorch/optimizer-step-without-loss-backward

Also available as: JSON · Markdown · 中文
95%Fix Rate
90%Confidence
1Evidence
2023-04-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
PyTorch 1.12.0 active
PyTorch 2.0.0 active
PyTorch 2.1.0 active

Root Cause

The optimizer's step() method is invoked without a preceding backward() call, meaning gradients are not computed, and the optimizer attempts to update parameters with stale or zero gradients.

generic

中文

优化器的 step() 方法在没有先调用 backward() 的情况下被调用,意味着梯度未计算,优化器尝试使用过时或零梯度更新参数。

Official Documentation

https://pytorch.org/docs/stable/optim.html#taking-an-optimization-step

Workarounds

  1. 95% success Ensure the training loop order is correct: for inputs, targets in dataloader: outputs = model(inputs); loss = criterion(outputs, targets); optimizer.zero_grad(); loss.backward(); optimizer.step()
    Ensure the training loop order is correct: for inputs, targets in dataloader: outputs = model(inputs); loss = criterion(outputs, targets); optimizer.zero_grad(); loss.backward(); optimizer.step()
  2. 85% success Add a conditional check before optimizer.step(): if loss.grad_fn is not None: optimizer.step() else: print('Skipping step: no gradient')
    Add a conditional check before optimizer.step(): if loss.grad_fn is not None: optimizer.step() else: print('Skipping step: no gradient')
  3. 90% success Use torch.no_grad() context manager only around inference, not around the backward pass. Example: with torch.no_grad(): outputs = model(inputs) for validation only.
    Use torch.no_grad() context manager only around inference, not around the backward pass. Example: with torch.no_grad(): outputs = model(inputs) for validation only.

中文步骤

  1. Ensure the training loop order is correct: for inputs, targets in dataloader: outputs = model(inputs); loss = criterion(outputs, targets); optimizer.zero_grad(); loss.backward(); optimizer.step()
  2. Add a conditional check before optimizer.step(): if loss.grad_fn is not None: optimizer.step() else: print('Skipping step: no gradient')
  3. Use torch.no_grad() context manager only around inference, not around the backward pass. Example: with torch.no_grad(): outputs = model(inputs) for validation only.

Dead Ends

Common approaches that don't work:

  1. Call optimizer.zero_grad() before loss.backward() to reset gradients 80% fail

    zero_grad() only clears gradients, it does not compute them. The core issue is missing backward() call, not gradient accumulation.

  2. Set requires_grad=False on all model parameters 95% fail

    This disables gradient computation entirely, making the optimizer step meaningless and preventing learning.

  3. Use a learning rate scheduler step before optimizer step 90% fail

    Scheduler step does not trigger gradient computation; it only adjusts the learning rate. The error persists.