Skip to content

fix(training): guard EMA updates on skipped optimizer step with AMP - #15189

Open
nrenvo wants to merge 1 commit into
huggingface:mainfrom
nrenvo:fix/ema-skipped-step-v2
Open

nrenvo wants to merge 1 commit into
huggingface:mainfrom
nrenvo:fix/ema-skipped-step-v2

Conversation

@nrenvo

@nrenvo nrenvo commented Nov 5, 2026 •

Copy link
Copy Markdown

When AMP skips an optimizer step due to gradient overflow, model weights are unchanged. The previous code still updated EMA with those unchanged weights, biasing the moving average.

Guard the EMA update and per-step bookkeeping with not accelerator.optimizer_step_was_skipped so EMA only steps when the optimizer actually applied gradients.

Also move train_loss = 0.0 outside the skipped-step guard so the loss accumulator resets on every sync_gradients boundary, including overflowed ones.

Affected scripts: train_text_to_image, train_text_to_image_sdxl, train_instruct_pix2pix, train_instruct_pix2pix_sdxl, train_unconditional, train_amused, train_vqgan.

Adds a parametrized test that simulates an overflow on step 2 and asserts EMA is never called for a skipped step.

Splits out from #15173 as requested.

Fixes #15112

@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Hi @nrenvo, thanks for the PR! It does not appear to link an issue it fixes. If this PR addresses an existing issue, please add a closing keyword (e.g. Fixes #1234) to the PR description so the issue is linked. See the contribution guide for more details. If this PR intentionally does not fix a tracked issue, a maintainer can add the no-issue-needed label to silence this reminder.

Please note that PRs without a linked issue are likely to be automatically closed 10 days after this notice.

Once the PR links an issue (or gets the no-issue-needed label), you can ignore this message — it stays here as a comment, but it no longer applies.

When AMP skips an optimizer step due to gradient overflow, model weights
are unchanged. Guard the EMA update and per-step bookkeeping with
not accelerator.optimizer_step_was_skipped so EMA only steps when the
optimizer actually applied gradients.

Also move train_loss = 0.0 outside the skipped-step guard so the loss
accumulator resets on every sync_gradients boundary, including overflowed ones.

Affected scripts:
- examples/text_to_image/train_text_to_image.py
- examples/text_to_image/train_text_to_image_sdxl.py
- examples/instruct_pix2pix/train_instruct_pix2pix.py
- examples/instruct_pix2pix/train_instruct_pix2pix_sdxl.py
- examples/unconditional_image_generation/train_unconditional.py
- examples/amused/train_amused.py
- examples/vqgan/train_vqgan.py
@nrenvo
nrenvo force-pushed the fix/ema-skipped-step-v2 branch from 49b5100 to 205621b Compare November 10, 2026 11:12
@github-actions github-actions Bot added fixes-issue size/S PR with diff < 50 LOC and removed size/M PR with diff < 200 LOC labels Nov 10, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text-to-image example updates EMA when AMP skips the optimizer step

1 participant