DDP Hang Due to Unused Parameters in Forward Pass
When find_unused_parameters=False (the default), DDP assumes every parameter in the model will receive a gradient. If a parameter is skipped in the forward pass (e.g., due to a conditional if-statement), its gradient is never computed. DDP waits indefinitely in the backward pass for the all-reduce operation on that missing gradient, deadlocking the training step.
When find_unused_parameters=False (the default), DDP assumes every parameter in the model will receive a gradient.
- Symptom
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one.- Root cause
- When find_unused_parameters=False (the default), DDP assumes every parameter in the model will receive a gradient. If a parameter is skipped in the forward pass (e.g.
- Recommended fix
- Enable find_unused_parameters if the graph is truly dynamic. model = DDP(model, device_ids=[rank], find_unused_parameters=True) Instructs DDP to traverse the autograd graph before the backward pass to discover which parameters are unused and proactively mark them as ready for reduction.
- How Denpex helps
- Denpex investigates DDP Hang Due to Unused Parameters in Forward Pass using the evidence you provide or your connected workload collects. Earlier rank, host or application evidence is needed to distinguish an initiating failure from a downstream report.
What this failure is
DDP Hang Due to Unused Parameters in Forward Pass is a Synchronization failure seen during ML training runs. When find_unused_parameters=False (the default), DDP assumes every parameter in the model will receive a gradient. If a parameter is skipped in the forward pass (e.g., due to a conditional if-statement), its gradient is never computed. DDP waits indefinitely in the backward pass for the all-reduce operation on that missing gradient, deadlocking the training step. Common tags: Autograd Graph Deadlock.
Is this what broke your run? Paste your log.
You're reading about DDP Hang Due to Unused Parameters in Forward Pass. Paste your own traceback and relevant evidence for an investigation of your workload, with a next action or a specific missing fact. A reference entry does not establish your cause. No account or card for the free diagnosis. Review data handling before submitting sensitive logs.
Before uploading, review cloud data handling and local options.
Upload your log file. Large files are processed in your browser. Only selected evidence is submitted when you run diagnosis.
Why it happens (the mechanism)
The script produces no crash or error message immediately. It simply hangs. Naive diagnosis might assume an NCCL network issue, GPU hardware failure, or a slow data loader, whereas the true issue is entirely in the autograd computation graph.
What you'll observe
- RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one.
- Process hangs indefinitely during loss.backward()
Common symptoms and what they mean
| Symptom | Why it happens |
|---|---|
| The training script completely freezes during the backward pass. | When find_unused_parameters=False (the default), DDP assumes every parameter in the model will receive a gradient. If a parameter is skipped in the forward pass (e.g., due to a conditional if-statement), its gradient is never computed. DDP waits indefinitely in the backward pass for the all-reduce operation on that missing gradient, deadlocking the training step. |
| No CPU or GPU utilization spikes; processes just sit idle waiting for communication. | When find_unused_parameters=False (the default), DDP assumes every parameter in the model will receive a gradient. If a parameter is skipped in the forward pass (e.g., due to a conditional if-statement), its gradient is never computed. DDP waits indefinitely in the backward pass for the all-reduce operation on that missing gradient, deadlocking the training step. |
Which systems are affected
- PyTorch
- DistributedDataParallel (DDP)
How to confirm this is the problem
Use this checklist to test the hypothesis against a small reproduction. No single line proves the root cause, so preserve the preceding events and compare one variable at a time.
- ✓Set environment variable TORCH_DISTRIBUTED_DEBUG=DETAIL to see exact parameter wait logs.
- ✓Check if any layers in the model's forward pass are inside conditional blocks that might not execute.
- ✓Temporarily set find_unused_parameters=True to see if the hang resolves.
Root cause
- When find_unused_parameters=False (the default), DDP assumes every parameter in the model will receive a gradient. If a parameter is skipped in the forward pass (e.g., due to a conditional if-statement), its gradient is never computed. DDP waits indefinitely in the backward pass for the all-reduce operation on that missing gradient, deadlocking the training step.
The fix and how to prevent it
Searchable error signature
RuntimeError: Expected to have finished reduction in the prior iteration before starting a new one.Use this text as a lookup key in logs and upstream issue trackers. It is not presented as a captured customer log. Confirm the cause from your own preceding events, versions, configuration and the cited references.
The fix and the prevention pattern
The root cause is on this page and stays free. A free account adds the exact remediation steps, saved history, and the fix on every entry in the encyclopedia.
Sign up free. Unlock the full analysisNo credit card. Daily allowance follows verified trust tier. Instant access.
Diagnose this failure in VS Code
Select the traceback or open the failed terminal, then run Denpex locally to see the initiating rank, collateral failures, exact fix, and verification command without uploading the log.
Install the free VS Code extensionDon't just read the fix, diagnose your run
The encyclopedia tells you what went wrong. Denpex tells you what went wrong in YOUR training run. With your logs, your config, and your stack.