RuntimeError: 在 loss.backward() 之前调用了 step()。请确保在 optimizer.step() 之前调用 loss.backward()。
RuntimeError: step() called before loss.backward(). Ensure you call loss.backward() before optimizer.step().
ID: pytorch/optimizer-step-without-loss-backward
版本兼容性
| 版本 | 状态 | 引入 | 弃用 | 备注 |
|---|---|---|---|---|
| PyTorch 1.12.0 | active | — | — | — |
| PyTorch 2.0.0 | active | — | — | — |
| PyTorch 2.1.0 | active | — | — | — |
根因分析
优化器的 step() 方法在没有先调用 backward() 的情况下被调用,意味着梯度未计算,优化器尝试使用过时或零梯度更新参数。
English
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.
官方文档
https://pytorch.org/docs/stable/optim.html#taking-an-optimization-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()
-
Add a conditional check before optimizer.step(): if loss.grad_fn is not None: optimizer.step() else: print('Skipping step: no gradient') -
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.
无效尝试
常见但无效的做法:
-
Call optimizer.zero_grad() before loss.backward() to reset gradients
80% 失败
zero_grad() only clears gradients, it does not compute them. The core issue is missing backward() call, not gradient accumulation.
-
Set requires_grad=False on all model parameters
95% 失败
This disables gradient computation entirely, making the optimizer step meaningless and preventing learning.
-
Use a learning rate scheduler step before optimizer step
90% 失败
Scheduler step does not trigger gradient computation; it only adjusts the learning rate. The error persists.