# RuntimeError: GradScaler unscale_() encountered None gradient. Ensure loss.backward() and optimizer.step() are called correctly.

- **ID:** `pytorch/grad-scale-unscale-error`
- **Domain:** pytorch
- **Category:** runtime_error
- **Verification:** ai_generated
- **Fix Rate:** 88%

## Root Cause

GradScaler's unscale_() method was called on a parameter whose gradient is None, typically because the parameter was not used in the forward pass or was excluded from gradient computation.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| torch>=1.10 | active | — | — |
| torch<=2.5.1 | active | — | — |

## Workarounds

1. **Exclude parameters that are not used in the forward pass from the optimizer. For example, if a submodule is conditionally used, filter its parameters: optimizer = torch.optim.SGD([p for p in model.parameters() if p.requires_grad and p.grad is not None], lr=0.01)** (90% success)
   ```
   Exclude parameters that are not used in the forward pass from the optimizer. For example, if a submodule is conditionally used, filter its parameters: optimizer = torch.optim.SGD([p for p in model.parameters() if p.requires_grad and p.grad is not None], lr=0.01)
   ```
2. **Use torch.no_grad() context or set requires_grad=False on parameters that are not part of the computation graph to avoid gradient computation.** (85% success)
   ```
   Use torch.no_grad() context or set requires_grad=False on parameters that are not part of the computation graph to avoid gradient computation.
   ```

## Dead Ends

- **Setting all parameters to require grad=True** — If a parameter is truly unused in the forward pass, setting requires_grad=True will still result in a None gradient after backward, because no gradient flows through it. (60% fail)
- **Calling unscale_() multiple times to clear None gradients** — The GradScaler's internal state does not allow multiple unscale_() calls per optimizer step; it raises a different error about double unscale. (80% fail)
