Skip to content

Fix ChainedOptimizer step sync when a chained member is itself chained - #7354

Merged
ericharper merged 1 commit into
NVIDIA:mainfrom
deepakn94:dnarayanan/chained_optimizer_step_sync
Sep 17, 2026
Merged

ericharper merged 1 commit into
NVIDIA:mainfrom
deepakn94:dnarayanan/chained_optimizer_step_sync

Conversation

@deepakn94

@deepakn94 deepakn94 commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor
  • I, the PR author, have personally reviewed every line of this PR.

What does this PR do?

Fixes a crash at the first checkpoint save when a ChainedOptimizer holds another ChainedOptimizer.

_synchronize_steps reaches through optimizer.optimizer.param_groups (megatron/core/optimizer/optimizer.py:2110 and :2117). The .optimizer property asserts when the chained member is itself a ChainedOptimizer.

LayerWiseDistributedOptimizer subclasses ChainedOptimizer and holds more than one inner optimizer whenever the model mixes optimizers, muon plus AdamW for instance. Nesting one inside an outer chain therefore kills the run at its first checkpoint save.

The change

Use the param_groups property instead of .optimizer.param_groups. It aggregates nested chains and returns the same param_group dicts the loop below mutates, so the writes still land on the real groups.

Tests

tests/unit_tests/test_optimizer.py gains coverage for a chain whose member is itself a chain.

Pre-checks

  • I have added relevant unit tests
  • I have added relevant functional tests
  • I have added proper typing to my code
  • I have added relevant documentation
  • I have run the autoformatter on my PR

black, isort, pylint (10.00/10) and ruff clean. Unit tests need a GPU and were not run locally.

🤖 Generated with Claude Code

@copy-pr-bot

copy-pr-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

_synchronize_steps reaches through optimizer.optimizer.param_groups, which
asserts when a chained member is itself a ChainedOptimizer.
LayerWiseDistributedOptimizer is one whenever --muon-tp-mode and
--muon-expert-tp-mode resolve differently, so those runs die at their first
checkpoint save. Use the param_groups property instead: it aggregates nested
chains and hands back the same dicts the write loop mutates.

Signed-off-by: Deepak Narayanan <dnarayanan@nvidia.com>
@deepakn94
deepakn94 force-pushed the dnarayanan/chained_optimizer_step_sync branch from 70a39ae to f55cf4a Compare September 15, 2026 17:42
@deepakn94
deepakn94 marked this pull request as ready for review September 15, 2026 17:45
@deepakn94
deepakn94 requested review from a team as code owners September 15, 2026 17:45
@svcnvidia-nemo-ci svcnvidia-nemo-ci added Approved All necessary approvals have been made and removed Final Review PR is in the "final review" stage labels Sep 16, 2026
@ericharper
ericharper added this pull request to the merge queue Sep 16, 2026
@nemo-automation-bot

Copy link
Copy Markdown

🔄 Merge queue validation started!

You can track the progress here: https://github.com/NVIDIA/Megatron-LM/actions/runs/35155420871

Merged via the queue into NVIDIA:main with commit c230f59 Sep 17, 2026
139 of 143 checks passed
@deepakn94
deepakn94 deleted the dnarayanan/chained_optimizer_step_sync branch September 17, 2026 03:50

This branch was previously deployed

2 inactive 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.

5 participants