Repository navigation
Conversation
Carry the optional dense and expert optimizer Gloo groups in explicit collections and resolve the legacy global collection at the public optimizer factory boundary. Preserve the disabled-Gloo path and permit collection construction when Gloo groups were not created. Refresh against current main, preserve the nested optimizer regressions, and cover optional accessor checks plus Gloo presence and enablement. Signed-off-by: Yan Xu <yxu1@nvidia.com>
…o groups With use_gloo_process_groups=True, a process-group collection without Gloo groups used to fall back silently to running the distributed optimizer without Gloo. The global path raised in that case before this change. Raise ValueError instead, except under GTP_remat, which never builds Gloo groups. Signed-off-by: Yan Xu <yxu1@nvidia.com>
get_megatron_optimizer resolves the collection before calling its helpers, so a missing collection there is a caller error. Report it with ValueError instead of an assert, which is skipped under python -O. The previous hasattr(tp) check could never fail, because ProcessGroupCollection returns None for unset fields, so it is dropped. Signed-off-by: Yan Xu <yxu1@nvidia.com>
get_megatron_optimizer now resolves a missing pg_collection with ProcessGroupCollection.use_mpu_process_groups() up front, so the default path goes through the explicit-collection branch of setup_process_groups_for_optimizer. That branch returned no intra_dist_opt group unless ddp_config.use_distributed_optimizer was set. Megatron-FSDP leaves that flag False while OptimizerConfig enables the distributed optimizer, so its gradient-statistics group became None (TestMegatronFsdpGradStatsGroup in mfsdp_v1). Pass intra_dist_opt through from the collection whenever it is present, as the parallel_state branch always did. The initializer-cleanup factory tests patch every optimizer helper and never initialize model parallelism; stub the MPU fallback there instead of reaching the global grid. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
With Muon and the distributed optimizer, the emerging-optimizer path builds a separate DistributedOptimizer for the parameters Muon does not manage, and it set up that optimizer's process groups with Gloo hard-coded off. The collection now carries the Gloo groups, so honor the caller's use_gloo_process_groups instead. Without a Gloo group, the first memory-efficient fully reshardable checkpoint save failed the data_parallel_group assert in get_parameter_state_dp_zero. Tests: the layer-wise optimizer's DistributedOptimizer gets the collection's Gloo group (and none when Gloo is off), and the Muon + Lion checkpoint round trip also covers the memory-efficient fully reshardable format. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Without the distributed optimizer, the emerging-optimizer path reduced the gradient norm and zero count of expert parameters over tp_ep_pp, which leaves out the EGTP_remat axis. EGTP_remat peers hold distinct shards of each expert weight, so each peer computed the norm of its own shards only, and with gradient clipping the peers applied different clip factors and their replicas drifted apart. Use tp_ep_pp_with_egtp_remat, as the standard optimizer path does, falling back to tp_ep_pp for collections without it (the same group when EGTP_remat is off). Test: Muon with EP=2 and EGTP_remat=2 reports the norm over every expert shard on every rank. Before this change the two EGTP_remat peers reported 53.1 and 73.3 on 4 ranks, against a true norm of 89.1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The distributed optimizer shards its state over the collection's data-parallel group (dp_cp, or intra_dp_cp with more than one optimizer instance) and gathers that state over the matching Gloo group for checkpoint I/O. Taking the Gloo groups from the collection means they can now disagree: for example, a caller who starts from use_mpu_process_groups() and replaces dp_cp with their own group keeps parallel_state's Gloo group, and the save would then gather over other ranks, failing on a size mismatch or silently scrambling the optimizer checkpoint. Compare the rank lists of each Gloo group and the group it mirrors (dense and expert) and raise ValueError when they differ. Only expert parameters use the expert Gloo group, so require intra_expt_dp_gloo only when the collection has an expert data-parallel group. A dense model on its own grid can then enable Gloo by supplying intra_dp_cp_gloo alone. Tests: groups built by parallel_state pass with one and two optimizer instances; a Gloo group over other ranks raises, dense and expert; replacing dp_cp in an MPU collection with a same-size group over other ranks raises; a dense collection with only intra_dp_cp_gloo is accepted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The Gloo-collection test built its collection with use_mpu_process_groups(), so its Gloo groups were the parallel_state globals and the identity checks also passed for code that read the globals directly. Swap freshly created Gloo groups into the collection instead, and add an expert parameter so the expert distributed optimizer's Gloo group is checked too. The case where Gloo is requested in a job built without Gloo groups is now its own test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The CI ratchet from NVIDIA#6258 landed on main after this branch was written, so its allowlist still lists the two optimizer-helper fallbacks this change removes and lacks the one boundary read it consolidates them into. Refresh it: 210 -> 209 grandfathered reads. The addition was reviewed by hand: get_megatron_optimizer resolves a missing pg_collection with use_mpu_process_groups() once, at the entry point, replacing the fallbacks in _get_megatron_emerging_optimizer and _get_megatron_optimizer_based_on_param_groups that were already grandfathered. After adding it, `python tools/check_process_group_usage.py --update` dropped the two stale entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Signed-off-by: Yan Xu <yxu1@nvidia.com>
A collection without an embd field, or tied pipeline embedding/output stages without a usable embedding group, is a caller error. Report it with ValueError instead of an assert, which is skipped under python -O. Signed-off-by: Yan Xu <yxu1@nvidia.com>
Six sites in megatron/core called parallel_state accessors even though the correct group was already stored on the object (self.tp_group / self.cp_group). Pure substitution: no signature changes, no new arguments, no caller impact. SelfAttention.run_realtime_tests 3 sites -> self.tp_group SelfAttention.get_query_key_value_tensors 1 site -> self.tp_group MultiTokenPredictionLayer 1 site -> self.tp_group LLaVAModel 1 site -> self.cp_group Global process-group reads in megatron/core: 163 -> 157. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…scope Two more sites where the correct group was reachable without any API change. transformer_engine.py: in the cp_comm_type == 'a2a+p2p' branch the code read the global hierarchical CP groups, even though the caller-supplied branch directly above asserts hasattr(pg_collection, 'hcp') for exactly that case. The assert was already guaranteeing the group the code then declined to use. language_module.py: the word-embedding replica id derived its DP-CP rank from the global grid while the sharded tensor nine lines later is built against metadata['dp_cp_group']. Now both use the same group, so replica id and sharding agree under a caller-supplied grid. Global process-group reads in megatron/core: 157 -> 155. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
megatron/core/models/multimodal/context_parallel.py hard-coded the global CP grid in 11 places, across module-level helpers with no group parameter. This is the vision-encoder path, so it is exactly where an independent encoder grid silently used the LLM's groups instead. cp_group is now a required argument on the public helpers and is threaded through the private ones and the autograd Function. get_pg_size/get_pg_rank preserve the previous behaviour when CP is disabled (size 1, rank 0). The call graph is closed inside this repo: LLaVAModel already holds self.cp_group, and the only other callers are unit tests. The module is not re-exported and has no users in Megatron-Bridge or nemo-rl. Global process-group reads in megatron/core: 155 -> 144. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
_gather_from_tensor_parallel_region read the global TP grid for its size, rank and both collectives. Both callers are subclasses that already hold the group (self.tp_group on ColumnParallelLinear, self._tp_group on the TE variant), and the mapping helpers it calls already accept an explicit group. Global process-group reads in megatron/core: 144 -> 141. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
… in tests Caught by a distributed run: changing the autograd Function signature missed one direct .apply() call site in the unit tests. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
hybrid_context_parallel_forward_backward read the global TP and DP-CP grids for its broadcast source rank, broadcast group, rank checks and barrier. Its only caller is forward_backward_no_pipelining, which already holds pg_collection. dp_cp is asserted in the hybrid-CP branch rather than unconditionally, matching how TEDotProductAttention asserts hcp only for cp_comm_type == 'a2a+p2p'; the legacy schedule collection already requests dp_cp. get_tensor_model_parallel_src_rank() becomes torch.distributed.get_global_rank(tp_group, 0), which is its definition. hybrid_cp_schedule.py no longer imports parallel_state at all. Global process-group reads in megatron/core: 141 -> 136. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
run_realtime_tests compared Q/K layernorm parameters across the global DP grid. The DP group is required only by this debug check, so it is asserted there rather than in __init__, which asks use_mpu_process_groups for tp/cp only -- the same idiom TEDotProductAttention uses for hcp. megatron/core/transformer/attention.py no longer references parallel_state. Global process-group reads in megatron/core: 136 -> 133. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
mtp_on_this_rank read the global PP rank to decide whether MTP layers live on this stage. Both model callers (GPTModel, HybridModel) already hold self.pp_group from LanguageModule.__init__, which runs before the call. Global process-group reads in megatron/core: 125 -> 124. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
RotaryEmbedding and MultimodalRotaryEmbedding fell back to the global CP grid via a ternary when cp_group was not passed. 10 of the 22 constructor calls in this repo already passed one; the remaining 12 (3 in core, 9 in tests) now do too, so the fallback is gone rather than merely unused. megatron/core/models/common/embeddings/rotary_pos_embedding.py no longer references parallel_state. Global process-group reads in megatron/core: 124 -> 122. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…nd T5Model Both classes fell back to ProcessGroupCollection.use_mpu_process_groups() when no collection was passed. The fallback is now an assertion naming the missing argument, which is the 'fails loudly rather than silently' half of the goal. DotProductAttention: already dead in-repo -- Attention always passes pg_collection when building core_attention, and the one direct test construction passes it positionally. T5Model: 4 of 5 constructors did not pass one (3 tests, 1 example); they now do. This is a deliberate breaking change for external callers that construct these directly without a collection, which is the intent of the migration. Global process-group reads in megatron/core: 122 -> 120 (shims 20 -> 18). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…lock The use_mpu_process_groups fallback becomes an assertion naming the missing argument. All 7 constructors without one live in a single test module and now pass a collection. Global process-group reads in megatron/core: 120 -> 119 (shims 18 -> 17). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
LLaVAModel is the case the migration exists for: a vision encoder and an LLM may run on independent parallel grids, so falling back to the global grid silently picks the wrong one. The fallback becomes an assertion that says exactly that. All 8 constructors without a collection (7 tests, 1 example) now pass one. Global process-group reads in megatron/core: 119 -> 118 (shims 17 -> 16). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Attention, MultiLatentAttention (x2) and AbsorbedMLASelfAttention each fell back to use_mpu_process_groups when no collection was passed. All are dead in-repo: TransformerLayer sets attention_optional_kwargs['pg_collection'] unconditionally before build_module, and every direct constructor already passes one (verified by AST across megatron/, tests/ and examples/). Global process-group reads in megatron/core: 118 -> 114 (shims 16 -> 12). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Global process-group reads in megatron/core: 114 -> 113 (shims 12 -> 11). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
These were based on a faulty inventory. My constructor scan filtered on
len(node.args) < 2, which silently skipped every call site passing arguments
positionally, so 'no caller is missing pg_collection' was wrong.
A paired run showed 85 real failures:
63x AssertionError: MultiLatentAttention requires an explicit pg_collection
22x AssertionError: Attention requires an explicit pg_collection
10x TypeError: DSAIndexer.__init__() got multiple values for 'pg_collection'
(my inserted keyword duplicated an existing positional argument)
Reverting to the last validated state. The earlier fallback removals
(DotProductAttention, T5Model, MultiTokenPredictionBlock, LLaVAModel) were each
validated against a pristine baseline and are retained.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Yan Xu <yxu1@nvidia.com>
Redo of the reverted attempt, this time with a signature-aware inventory: both DSAIndexer constructors already pass pg_collection positionally, so the fallback is dead and the tests need no change. The previous attempt added a redundant keyword and produced 'got multiple values for argument pg_collection'. Global process-group reads in megatron/core: 118 -> 117 (shims 16 -> 15). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Second attempt, this time driven by the signature-aware scanner: 15 of 16 SelfAttention constructors were missing pg_collection (all in test modules) and now pass one. The earlier attempt used a scan that skipped positional call sites and had to be reverted. Global process-group reads in megatron/core: 117 -> 116 (shims 15 -> 14). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…sses Second attempt, driven by the signature-aware scanner. MultiLatentAttention (x2) and AbsorbedMLASelfAttention no longer fall back to use_mpu_process_groups. 18 of 19 MLASelfAttention constructors were missing pg_collection, all in one test module, and now pass one; AbsorbedMLASelfAttention's single constructor already did. Global process-group reads in megatron/core: 116 -> 113 (shims 14 -> 11). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Paired run: 24 failed / 43 passed against a pristine 20 / 57, with 110 'requires an explicit pg_collection' assertions. The failures are concentrated in TestFusedMLA*, i.e. a MultiLatentAttention subclass my scan never covered -- I scanned MLASelfAttention and AbsorbedMLASelfAttention by name and assumed those were the only constructors reaching the base __init__. The Attention removal in the preceding commit validated clean (5F/121P on both trees) and is retained. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8752 gives Float16OptimizerWithFloat16Params a keyword-only pg_collection and makes get_megatron_optimizer resolve its collection once, through resolve_process_groups, before it builds the optimizers. NVIDIA#8752 also carries NVIDIA#6303, whose imports its tests use. The config-logger change that follows forwards that collection to the optimizers' config log, so merge it here. Two files conflict with NVIDIA#8042, which this branch carries: - optimizer/__init__.py: keep both import changes, NVIDIA#8752's resolve_process_groups and NVIDIA#8045's get_ep_rank_and_size; in _get_megatron_optimizer_based_on_param_groups keep NVIDIA#8752's ValueError for a missing collection and NVIDIA#8042's set_duplicate_filter_groups call, which replaces the tp_group and expert_tp_group setattrs that NVIDIA#8752's side still read. - optimizer.py: import the union of both sides from process_groups_config (ProcessGroupCollection, require_process_groups, resolve_gtp_remat_group, resolve_process_groups). The process-group usage allowlist conflicts on NVIDIA#8042's entries; it is regenerated on the merged tree and equals NVIDIA#8752's file (170 reads: 149 accessor, 18 shim, 3 guarded). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8755 lets log_config_to_disk take the logging owner's process groups, through its pg_collection keyword, and adds test_config_logger_process_groups.py. The config-logger change that follows passes the optimizers' collection to that keyword and extends that test, so merge it here. Only the process-group usage allowlist conflicts. It is regenerated on the merged tree: 167 reads (136 accessor, 16 shim, 15 guarded). Against NVIDIA#8755's file, NVIDIA#8752's guarded reads in get_megatron_optimizer, _backfill_gtp_sharded_param_map and clip_qk replace their global reads. The merged .py files show no new undefined names or redefinitions (ruff F821/F811). Both branches carry NVIDIA#6303. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
log_config_to_disk names each dump by the ranks in the logging model's process groups and falls back, with a warning, to the global parallel state when it is called without them. The FP32, mixed-precision, distributed and fully sharded optimizers and both Megatron-FSDP wrappers still called it without their collection, so stock training with --config-logger-dir reached that fallback, and strict mode turned it into an error. The optimizers take a keyword-only pg_collection that get_megatron_optimizer passes, and the FSDP wrappers pass the collection they already hold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Connor-XY
force-pushed
the
yx/pstate-f6b-config-logger
branch
from
November 1, 2026 01:38
250066e to
c17120b
Compare
Connor-XY
added a commit
to Connor-XY/Megatron-LM
that referenced
this pull request
Nov 1, 2026
This base holds every other PR of the parallel_state deprecation series (NVIDIA#6307): the end-to-end test that follows asserts that no process-group fallback or deprecation warning fires anywhere on a collection that is not the global grid, and the strict-fallback functional tests turn every remaining fallback into an error, so both need the whole series below them. NVIDIA#8763 brings NVIDIA#8752, NVIDIA#8755 (with NVIDIA#6303), NVIDIA#8042 and NVIDIA#8045. Four files conflict: - extensions/transformer_engine.py: the process_groups_config import adds NVIDIA#8755's resolve_process_groups (eac0b1c). - models/T5/t5_model.py: drop the self.tp_group line that NVIDIA#6293 kept; NVIDIA#6303's b732c67, which NVIDIA#8763 brings, removes it because LanguageModule already sets self.tp_group from the collection. - optimizer/fully_sharded_optimizer.py: keep NVIDIA#8763's ProcessGroupCollection import (c17120b) and NVIDIA#8731's get_model_ep_rank_and_size import (3877940). - parallel_state.py, get_data_parallel_group_gloo and get_expert_data_parallel_group_gloo: take NVIDIA#6259's check_initialized argument and Args section, which NVIDIA#8763 brings, with NVIDIA#7991's deprecation paragraph before the Args section. The process-group usage allowlist is regenerated on the merged tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - examples/t5/pretrain_t5.py: Main adds `cfg = get_run_config()` to model_provider and drops the `build_tokenizer` import in favour of `get_tokenizer()`. The PR moves that import for isort and passes a ProcessGroupCollection into T5Model. The result keeps main's `cfg` line and the PR's pg_collection fallback and argument. It drops the `build_tokenizer` import, which would otherwise be unused. - megatron/core/models/common/embeddings/rotary_pos_embedding.py: Main imports `register_capture_constant` for its shared rotary cache. The PR imports `warn_global_process_group_fallback`. Both imports are kept, along with main's cache refactor and the PR's warning cp_group fallback. - pretrain_gpt.py, pretrain_hybrid.py: Main (NVIDIA#8341, NVIDIA#8592) moves `is_dataset_built_on_rank` into megatron/training/datasets/providers.py and the dataset config builder into argument_utils. The PR adds `pp_group` to the `mtp_on_this_rank` call in the local predicate. The result takes main's layout and keeps the PR's `pp_group` in get_batch. Adapted to main outside the conflicts: - megatron/training/datasets/providers.py: The PR's predicate edit is re-applied in main's shared `is_dataset_built_on_rank_explicit`. It passes `pp_group=mpu.get_pipeline_model_parallel_group()` to `mtp_on_this_rank`, so middle pipeline stages do not hit the fallback warning. The function's signature is unchanged. The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Adapted to main outside the conflicts: - tests/unit_tests/training/test_train_step_qk_clip_group.py: Main's NVIDIA#8149 makes train_step read the run config first, which asserts when none is set. The PR's new tests now use an autouse training_config fixture that sets micro_batch_size to 1. This is the same fixture main added to test_train_step_schedule_plumbing.py, so the tests reach clip_qk again. No production code changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - megatron/core/transformer/moe/batch_invariant.py: Main (NVIDIA#8559) moves the old body into a private _unpermute_loop() that takes a required ep_size, and adds a public unpermute() wrapper that reads the global EP size and picks the Triton kernel or the loop. The loop keeps main's version. The PR's change moves to the new wrapper: it takes ep_size=None, documents it as the dispatcher's EP size, and reads the global EP size only when ep_size is None. The shard assert and both branches use the resolved ep_size. Adapted to main outside the conflicts: - tests/unit_tests/transformer/moe/test_token_dispatcher.py: Main's new test_alltoall_combine_postprocess_releases_router_probs (NVIDIA#8297) builds the dispatcher without __init__. combine_postprocess now reads self.ep_size, so the test sets dispatcher.ep_size = 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - megatron/core/transformer/cuda_graphs.py: Main added the static _initialize_mempool method after CudaGraphManager.__init__ (NVIDIA#8124, NVIDIA#8345), and the PR added _resolve_reuse_cudagraphs in the same place. The result keeps both methods, with the PR's method unchanged. __init__ keeps the PR's lazy reuse_cudagraphs and no longer builds a global collection, and it uses main's mempool setup and side stream. The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Adapted to main outside the conflicts: - tests/unit_tests/transformer/test_quantization_context_amax_group.py: The bare MultiTokenPredictionLayer in test_projection_and_layer_contexts_use_the_layer_collection now sets is_hybrid_mtp = False instead of mtp_layer_pattern = None. Main's NVIDIA#7555 removed mtp_layer_pattern, and _proj_and_transformer_layer now branches on is_hybrid_mtp, which only __init__ sets. The GPT branch matches the test's mtp_model_layer stub. The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - examples/bert/pretrain_bert.py: The PR adds a ProcessGroupCollection import for the pg_collection default in model_provider, and main's tokenizer refactor (NVIDIA#8391) swaps build_tokenizer for get_tokenizer. The result keeps the PR's import list, imports get_tokenizer from global_vars, and drops the unused build_tokenizer import. - tests/unit_tests/pipeline_parallel/test_fine_grained_activation_offloading.py: The PR imports ProcessGroupCollection for its pg_collection arguments, and main splits the tensor_parallel.random import to add CheckpointWithoutOutput. The result keeps both imports. Adapted to main outside the conflicts: - tests/unit_tests/ssm/test_hybrid_block.py: Main's MTP overlap test now also requires the embd group. Without it, the PR's LanguageModule check raises before HybridModel reaches the guard the test expects. - tests/unit_tests/inference/coordinator_pairwise_utils.py, tests/unit_tests/inference/engines/batch_invariant_test_utils.py, tests/unit_tests/inference/engines/test_batch_invariant_models.py, tests/unit_tests/models/test_pos_embedding_cuda_graph.py, tests/unit_tests/models/test_hybrid_mhc.py: The GPTModel and HybridModel constructions that main added now pass pg_collection=ProcessGroupCollection.use_mpu_process_groups(). This keeps them off the deprecated fallback, as the PR does elsewhere. The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…ir update to main Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…NVIDIA#8032 and NVIDIA#8053 after their update to main Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - tests/unit_tests/dist_checkpointing/utils.py: Main (NVIDIA#8213) adds a config.finalize_optimizer_config() call before the optimizer is built in setup_model_and_optimizer and setup_moe_model_and_optimizer. The PR passes pg_collection=ProcessGroupCollection.use_mpu_process_groups() to get_megatron_optimizer in both helpers. The result runs finalize first, then the PR's pg_collection call. Adapted to main outside the conflicts: - tests/unit_tests/distributed/mfsdp_v2/test_mcore_moe.py: Main (NVIDIA#8312) adds test_shortcut_moe_training_and_clipping, which calls get_megatron_optimizer without pg_collection and so hits the PR's warned fallback. Both calls now pass pg_collection=ProcessGroupCollection.use_mpu_process_groups(), as the PR does in test_standard_moe_training_and_clipping. The groups are the same as before. The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - megatron/core/transformer/cuda_graphs.py: The PR added CudaGraphManager._resolve_reuse_cudagraphs and main added the static _initialize_mempool at the same spot. The result keeps both methods in the order the base PR uses. Both reuse_cudagraphs call sites still go through _resolve_reuse_cudagraphs. - megatron/core/transformer/moe/batch_invariant.py: Main (NVIDIA#8559) split unpermute into _unpermute_loop, which takes a required ep_size, and a public dispatcher that read the global EP size itself. The result keeps main's split and Triton kernels. The PR's optional ep_size keyword, its docstring sentence and its resolve_process_groups fallback move into the new public unpermute and replace main's global read. - tests/unit_tests/ssm/test_gated_delta_product.py: Both sides added imports. The result keeps main's Float16Module and is_causal_conv1d_min_version imports and the PR's global_amax_groups import. Adapted to main outside the conflicts: - tests/unit_tests/transformer/moe/test_moe_batch_invariant_unpermute.py: Main's new test set the EP size through parallel_state.set_expert_model_parallel_world_size, which unpermute no longer reads. The ep_world_size fixture is removed and each unpermute call passes ep_size explicitly, as the PR does for the RL tests. - tests/unit_tests/determinism/kernels/test_moe_kernels.py: Main's new test_batch_invariant_unpermute_replays patched get_expert_model_parallel_world_size. The patch is removed and the unpermute call passes ep_size=2. The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…ir update to main Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - examples/bert/pretrain_bert.py, examples/t5/pretrain_t5.py: Main moves both scripts to get_tokenizer and padded_vocab_size and drops build_tokenizer. The PR passes ProcessGroupCollection groups to the model provider. The result keeps both and removes the unused build_tokenizer import. - megatron/core/models/common/embeddings/rotary_pos_embedding.py, tests/unit_tests/pipeline_parallel/test_fine_grained_activation_offloading.py, tests/unit_tests/ssm/test_gated_delta_product.py: Import conflicts only. The result keeps the imports from both sides. - megatron/core/transformer/cuda_graphs.py: Main adds the _initialize_mempool staticmethod. The PR adds _resolve_reuse_cudagraphs, which decides graph reuse from the pipeline group. Both are kept, in the method order of NVIDIA#8755. - megatron/core/transformer/moe/batch_invariant.py: Main splits unpermute into a Triton kernel and a reference loop. The PR's ep_size keyword and its warned EP-group fallback move into main's new public unpermute. - pretrain_gpt.py, pretrain_hybrid.py: Main moves the dataset helpers into megatron/training. The result takes main's code and keeps the PR's pp_group in get_batch. - tests/unit_tests/dist_checkpointing/utils.py: The result calls main's new finalize_optimizer_config() and passes the PR's pg_collection to get_megatron_optimizer. Adapted to main outside the conflicts: - megatron/training/datasets/providers.py: The PR's pp_group argument to mtp_on_this_rank is re-applied where main moved is_dataset_built_on_rank. - tests/unit_tests/transformer/moe/test_moe_batch_invariant_unpermute.py: Main's new test passes ep_size explicitly, since unpermute no longer reads the global EP world size. The process-group allowlist records the reads main added since this PR was written. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Main's NVIDIA#8471 moves FullyShardedDataParallelV1 and FullyShardedDataParallelV2 out of mcore_fsdp_adapter.py into mcore_adapter_v1.py and mcore_adapter_v2.py, and keeps mcore_fsdp_adapter.py as the factory that re-exports them. This branch's edits to the two classes and their helpers are applied unchanged where the code moved, and the process-group allowlist follows the move. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
This was referenced Nov 3, 2026
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #8752, #8755, #8042 and #8045. Please review the diff from their merge: scoped diff.
log_config_to_diskname its dumps by a given collection, and adds the test file this PR extends.Float16OptimizerWithFloat16Paramsitspg_collectionand makesget_megatron_optimizerresolve the collection it passes on.ProcessGroupCollectionimport inoptimizer.pythat the new annotations use, and itsset_duplicate_filter_groupscalls sit next to this change. Name FSDP-DTensor experts by the model's expert-parallel layout #8045 changes thedistrib_optimizer.pyimports next to it.optimizer/__init__.pyandoptimizer.py, and the merges regenerate the process-group allowlist. Each merge commit lists its resolutions.#8731 changes the import block of
fully_sharded_optimizer.pynext to this change. Whichever lands second keeps both.Why.
log_config_to_disknames each dump by the ranks in the process groups of the object it logs. Called without them, it warns and falls back to the global parallel state (#8755). The FP32, mixed-precision, distributed and fully sharded optimizers and both Megatron-FSDP wrappers still called it without their collection. Stock training with--config-logger-dirtherefore warned, and failed when fallback warnings were errors.What.
MixedPrecisionOptimizer,FP32Optimizer,DistributedOptimizerandFullyShardedOptimizertake a keyword-onlypg_collectionand pass it tolog_config_to_disk. The subclasses forward it toMixedPrecisionOptimizer, andFloat16OptimizerWithFloat16Paramsforwards the collection it already takes.get_megatron_optimizerpasses its collection to these optimizers on the adam/sgd and the emerging-optimizer paths.FullyShardedDataParallelV1andFullyShardedDataParallelV2pass the collection they hold tolog_config_to_disk.Tests.
tests/unit_tests/test_config_logger_process_groups.pyaddstest_optimizers_pass_their_collectionforFP32OptimizerandFloat16OptimizerWithFloat16Params: each logs its config once, with its collection.On 4 GPUs against its base:
test_config_logger_process_groups.pypasses 7 tests here vs 5 on the base, and the 2 new tests pass.test_process_group_fallback.py(19 passed),transformer/test_cuda_graph_helper_process_groups.py(2 passed) andtransformer/test_cuda_graphs.py(83 passed, 3 skipped) give the same results on both sides. None of these files shows a regression. The integration run merges all #6307 PRs onto main and runs the full unit-test suite against main on 4 GPUs and 8 GPUs (two nodes). In it, this PR's test file passes 7 tests; the file is not on main, so main has no results for it. Across the full suite, no test that passes on main fails, apart from one fused-MHC kernel check that failed on one rank and has failed the same way on main. On the same merged tree, end-to-end training smokes on 4 GPUs give losses bit-identical to main and record no process-group fallback warning.Before the sync with main, the branch ran the test file on 4 CPU ranks with Gloo, with no regressions. The two new tests fail there, because both optimizers allocate a CUDA tensor right after they log. With that allocation stubbed out, both optimizers log once with their collection.
Compatibility. The new arguments are optional and keyword-only. Without them, dumps are named by the global ranks with a warning, as before this PR. On the standard grid the collection holds the global groups, so dump names do not change. Only runs with
--config-logger-dirare affected.determinism-exempt:optimizer/__init__.pyandoptimizer/optimizer.pyare registered kernel files. The change there only passes the collection along, and numerics do not change.Synced with main 77391e7 on 2026-11-01 by a merge commit that lists each conflict and its resolution, so existing commits and review links stay valid.
Later on 2026-11-01 the branch also merged main bfab98f. Its #8471 moves
FullyShardedDataParallelV1andFullyShardedDataParallelV2frommcore_fsdp_adapter.pyintomcore_adapter_v1.pyandmcore_adapter_v2.py, and keepsmcore_fsdp_adapter.pyas the factory that re-exports them. This PR's edits to those classes are applied unchanged where the code moved, and the process-group allowlist follows the move. On 4 GPUs against its new base, the Megatron-FSDP adapter tests and this PR's own tests (10 files) show no regressions: 169 passed here, 167 on the base. The two CUDA-graph end-to-end cases oftest_mcore_fully_sharded_data_parallel.pyfail on both sides, as they do on main.Part of #6307.
🤖 Generated with Claude Code