Commit e614064
committed
Fix fp16 ZeRO stage-0 loss scaling in engine.backward()
When fp16 is enabled with ZeRO stage 0, engine.backward() falls through
to loss.backward() directly. FP16_Optimizer.step() always divides
gradients by cur_scale (typically 32768), so gradients that were never
pre-scaled are unscaled by the same factor, making effective parameter
updates ~cur_scale times too small and stalling training.
Add an explicit elif branch for fp16 + ZeRO-0 that routes through
FP16_Optimizer.backward(), which pre-scales the loss by cur_scale before
calling backward(), matching what step() expects.
The existing # TODO comment on line 3325 acknowledges this path was
left incomplete. The ZeRO stages > 0 and AMP paths are handled correctly;
only the fp16 non-ZeRO path was missing.
Tested with a CIFAR-10 MoE benchmark (fp16, ZeRO stage 0, 8 experts):
- Before: accuracy 22-28%, loss stalls at ~1.8
- After: accuracy 49%, loss converges to ~0.7
Signed-off-by: Roohollah Etemadi <Roohollah.Etemadi@amd.com>1 parent 56de570 commit e614064
1 file changed
Lines changed: 10 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3325 | 3325 | | |
3326 | 3326 | | |
3327 | 3327 | | |
| 3328 | + | |
| 3329 | + | |
| 3330 | + | |
| 3331 | + | |
| 3332 | + | |
| 3333 | + | |
| 3334 | + | |
| 3335 | + | |
| 3336 | + | |
| 3337 | + | |
3328 | 3338 | | |
3329 | 3339 | | |
3330 | 3340 | | |
| |||
0 commit comments