Repository navigation
Conversation
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>
The training scripts' dataset changes that follow sit on the is_dataset_built_on_rank and get_batch code that NVIDIA#8754 moves to the model config's virtual-pipeline size, and their tests use NVIDIA#8017's forbid_global_process_groups and build_test_pg_collection, which NVIDIA#8754 brings. The merge is clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The checker classification that follows requires every allowlisted read in megatron/core to be warned or guarded, and its test lists the only two reads allowed to stay unwarned. NVIDIA#8752 warns before get_megatron_optimizer's use_mpu_process_groups() fallback, before clip_qk's global data-parallel group (with NVIDIA#8043, which NVIDIA#8752 brings) and describes the GTP shards in _backfill_gtp_sharded_param_map with the optimizer's own groups. Without it those four reads are unwarned and the classification test fails. megatron/core/optimizer/__init__.py conflicts on its imports: NVIDIA#8045's e09f5de (which NVIDIA#8749 brings) imports get_ep_rank_and_size next to get_global_unique_param_name, and NVIDIA#8752's 2d4d3cc adds resolve_process_groups to the process_groups_config import. The import takes both. NVIDIA#8752 also carries NVIDIA#6303, which this branch does not have yet, so tests/unit_tests/export/trtllm/test_trtllm_distributed_gpu_converter.py conflicts on its imports: NVIDIA#6303 imports ProcessGroupCollection and NVIDIA#8059 adds ProcessGroupFallbackWarning to the same import. The import takes both. 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>
The checker classification that follows requires every allowlisted read in megatron/core to be warned or guarded. NVIDIA#8755 warns the global fallbacks of the log and param-hash helpers, RoPE, MIMO partitioning, batch-invariant unpermute, the FP8/FP4 contexts and the CUDA-graph helpers, and brings NVIDIA#8017, NVIDIA#8032, NVIDIA#8035, NVIDIA#8047, NVIDIA#8049 and NVIDIA#8053 (NVIDIA#6303 already came in with NVIDIA#8752). megatron/core/extensions/transformer_engine.py conflicts on its parallel_state import: NVIDIA#8038 drops get_tensor_model_parallel_world_size and keeps model_parallel_is_initialized, and NVIDIA#8755's eac0b1c drops get_amax_reduction_group and model_parallel_is_initialized. The merged file calls none of the three, so the import keeps only get_context_parallel_group, get_hierarchical_context_parallel_groups and get_tensor_model_parallel_group. 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>
The checker classification that follows requires every allowlisted read in megatron/core to be warned or guarded. NVIDIA#8756 rejects unset tp and cp fields in the attention and MLP builders, validates the MIMO checkpoint groups and requires the refit metadata groups, instead of probing the collection and falling back to the global grid. megatron/core/extensions/transformer_engine.py conflicts on the process_groups_config import: NVIDIA#8755 imports amax_reduction_group and resolve_process_groups, and NVIDIA#8756 imports require_process_groups. The import takes all three. 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>
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>
The end-to-end seeding test that follows checks that the collection pretrain builds after initialize_megatron holds the same groups as the collection the RNG was seeded from. It builds that collection with training._build_pg_collection_from_parallel_state, the helper that NVIDIA#8037 adds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…8039 Seeding the RNG from the grid that initialize_megatron builds needs the collection that initialize_model_parallel returns, which NVIDIA#8039 adds. NVIDIA#8039's head also contains the Gloo fields of the collection (NVIDIA#6259). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8031, NVIDIA#8037 and NVIDIA#8039 each refreshed the allowlist against main. Merging them keeps the total of 195 that NVIDIA#8031 and NVIDIA#8037 share, since NVIDIA#8039's total equals main's, while the merged entries record 194 reads. Regenerate the file so that its total matches its entries. No entry changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
initialize_megatron seeds the random number generators from the model's collection when pretrain passes one. Stock training passes none, so _set_random_seed and model_parallel_cuda_manual_seed read the pipeline, data-parallel, tensor, expert and GTP-remat ranks from the global parallel state, although initialize_model_parallel has just returned the collection of the grid it built. _initialize_distributed now returns that collection, or None when it builds no grid (model-parallel setup skipped, a grid already initialized, or no CUDA device). initialize_megatron seeds from it unless the caller passes seed_pg_collection, and falls back to the global state only when no grid was built. The log lines that report the grid sizes read the same collection, so initialization reads no global group, rank or size once the grid exists. The collection holds the groups that initialize_model_parallel registers, so the seeds equal those of the global state, and the collection that pretrain builds afterwards from the registered groups holds the same group objects. With lazy_mpu_init, the provisional tensor-parallel rank that initialize_megatron sets to the global rank before the grid exists no longer replaces the group rank in the tensor-parallel seed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
When pretrain() is given a ProcessGroupCollection, it passes it to the model, the optimizer and the schedules, but the rest of the loop still read the global parallel state: the packed-sequence FLOPs deduplication, the logits saver and capture stage checks, the batch-size check, the skipped-iteration batch reads, the samples-seen reduction, the batch accounting, the full-validation tensor-parallel rank, the full-dataset length probe and the GPU sniff test. With a collection whose grid differs from the global one, these selected other ranks than the model trains on. Take these groups from the run's single-grid collection, or from the model's collection for per-model steps: - consume_seqlen_stats_in_iteration, dummy_train_step, post_training_step_callbacks and the private full-dataset helpers take an optional collection; train() and pretrain() pass the run's single-grid collection. - train_step, evaluate, evaluate_and_print_results and the logits hooks use the model's collection, then a single-grid run collection, and read the global grid only when given neither. - The batch accounting and the samples-seen reduction use dp_gtp_remat, the group get_data_parallel_group() returns by default. A multi-module collection keeps its run-level steps on the global parallel state, as before, and counts samples on its model's groups. Without a caller-provided collection, pretrain() has no run collection, so the run-level steps keep reading the global grid, and the per-model steps use the model's collection, which holds the global groups. Callers that pass no collection keep the previous behavior. The batch-size check becomes a ValueError whose message reports the size the microbatch calculator divides by, computed only when it fails. On the standard grid every step selects the same groups as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
update_packed_sequence_stats counts each packed microbatch once per data-parallel replica: on the last pipeline stage, tensor-parallel rank 0 and context-parallel rank 0. It read those ranks from the global parallel state, so a model on another grid counted samples on the wrong ranks. Accept an optional pg_collection and read the pipeline, tensor- and context-parallel ranks from it. Callers that pass none keep reading the global parallel state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
With restore_modelopt_state and no explicit use_arbitrary_attention_mask, default_layer_spec enables the arbitrary attention mask only without context parallelism. It read the context parallel size from the global parallel state, although GPTModelBuilder.build_model receives the collection the model is built on. Give default_layer_spec an optional pg_collection, read the context-parallel size from it, and pass the builder's collection. Callers that pass none keep reading the global parallel state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
train() hands the GPU sniff test no collection when it runs on a MultiModuleProcessGroupCollection, so run_gpu_sniff_test() builds one from the global parallel state. Heterogeneous MiMo (examples/mimo/pretrain_mimo.py) never initializes that state, so --gpu-sniff-test-interval fails there before the first benchmark: the data-parallel getter asserts that its group is not initialized. A multi-module run that did build a global grid would test groups its modules do not train on. Passing each rank's module collection instead is not safe. The sniff test all-gathers every metric over WORLD. A rank reports 0 or 2 reduce-scatter metrics and 0 or 2 all-to-all metrics, depending on whether its TP and EP groups have more than one rank, plus 2 send/recv metrics per stride of its DP group. MiMo modules size these groups independently: the encoder always has EP=1, and the language model takes --mimo-llm-ep. Ranks of different modules would issue different numbers of WORLD all-gathers, and the surplus would pair with the closing WORLD barrier or hang. train() now raises a ValueError when --gpu-sniff-test-interval is set with a multi-module collection. The check adds no collective. Every rank of such a run receives a MultiModuleProcessGroupCollection and the same flag value, so every rank raises at the same point, before any sniff-test collective. Single-grid runs and runs without a collection are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
When pretrain() is given a process-group collection for the run, the data loaders it builds still read the global grid: the samplers took their data-parallel rank and size from parallel_state, the TP-rank-0 check that decides which ranks build the data pipeline read the global TP rank, and full validation agreed on the number of evaluation iterations over the global DP x CP group. Pass the run's collection to build_train_valid_test_data_iterators, build_train_valid_test_data_loaders and build_pretraining_data_loader. The samplers shard over its GTP-inclusive data-parallel group (dp_gtp_remat, or dp for collections without the GTP fields), the pipeline is built on the first rank of its tensor-parallel group, and the evaluation iterations are reduced over dp_cp_gtp_remat, matching the default group of get_data_parallel_group(with_context_parallel= True). A MIMO run keeps the global defaults because its collection has one collection per module and its providers build their own loaders. The new pg_collection arguments default to None, which keeps the global groups for existing callers. Without a caller-provided collection, pretrain() has none to pass, and the loaders keep that global fallback. On the standard grid the collection holds the global groups, so the samplers and reductions are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8017 adds test helpers that forbid global grid reads and build process-group collections; its head also carries NVIDIA#6259's Gloo fields of the collection. The Flextron router weight-sync tests that follow import forbid_global_process_groups, so merge NVIDIA#8017 here. The merge is clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8049 adds ProcessGroupFallbackWarning, resolve_process_groups and require_process_groups, on top of NVIDIA#6293's deprecated global fallbacks. The post-training summary and the Flextron model provider resolve their groups through these helpers, the hybrid Flextron router requires them, and the new tests expect the warning class. The merge is clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…8742 The Flextron get_batch that follows calls is_first_or_last_pipeline_stage(vp_stage, pp_group=..., vp_size=...), whose pp_group and vp_size parameters NVIDIA#8742 adds. NVIDIA#8742 is based on main, so its get_batch and import lines conflict with NVIDIA#6293's, which NVIDIA#6303 and NVIDIA#8049 bring in. All three are resolved to NVIDIA#8742's side: - pretrain_gpt.py, pretrain_hybrid.py: get_batch passes the model's pp_group and vp_size instead of NVIDIA#6293's mpu.get_pipeline_model_parallel_group(), and computes is_first_or_last_stage with them. - pretrain_vlm.py: keep NVIDIA#8742's is_pp_first_stage/is_pp_last_stage import before the ProcessGroupCollection import that both sides add. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
initialize_megatron now seeds the model-parallel RNG from the collection that initialize_model_parallel returns (NVIDIA#8039, NVIDIA#8031), and the training utilities' fallback warnings that follow change the same seeding code in initialize.py. The merge is clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The merge of NVIDIA#8017 took its optimizer entries (one get_megatron_optimizer shim read, from NVIDIA#6259, in place of the two shim reads in _get_megatron_emerging_optimizer and _get_megatron_optimizer_based_on_param_groups) and kept NVIDIA#6303's total of 172, while the merged entries record 171 reads. Regenerate the file so that its total matches its entries. No entry changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The ModelOpt loss function read the global tensor-parallel grid: a sequence-parallel distillation loss took its slice of the loss mask by the global TP rank and size, and every distillation loss split across TP ranks was all-reduced over the global TP group. print_distributed_quant_summary chose the ranks that print by the global data-, tensor-, expert- and pipeline-parallel ranks. A model built on a collection whose groups differ from the global grid therefore reduced its distillation losses over the wrong ranks. loss_func passes the tp group of the model's pg_collection to _mask_loss, which slices the mask by the rank and size of that group and all-reduces over it. The group is a new tp_group argument of _mask_loss; a caller that omits it keeps the global group with a ProcessGroupFallbackWarning (deprecated in 0.21, removed in 0.23), and only when a distillation loss needs a group. loss_func still accepts model=None, which pretrain_gpt.loss_func forwards when ModelOpt is enabled and the caller, such as pretrain_vlm.py, binds no model: the plain loss needs no group, and a split loss takes the warned fallback. print_distributed_quant_summary reads the dp_cp_gtp_remat, tp, ep and pp groups of the model's collection. This diagnostic runs whenever a quantized checkpoint is loaded, so a model without a collection that sets those groups, such as MimoModel, keeps printing by the global ranks with the same warning instead of failing. On the standard grid the collection holds the global groups, so the losses and the printing ranks are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Flextron training read the global parallel grid throughout. The loss split and reduced distillation losses over the global TP group and gathered the per-budget report over the global data-parallel group. The Mamba and grouped-MLP elasticity hooks sized and sliced their masks by the global TP and expert-TP ranks. The router was named by the global pipeline rank, seeded its Gumbel noise and counted gradient-accumulation steps by the global DP rank and size, and built its linear layers without a group, so they fell back to the global TP group. The injected forward checked the global last stage, and pretrain_hybrid_flex.py read, broadcast and sharded batches, drew budgets and chose the dataset-building ranks on the global grid. A Flextron model built on groups other than the global ones therefore masked, reduced and seeded over the wrong ranks. Take every group from the collection of the model or the run: - loss_func passes the model's tp group to _mask_loss and gathers the distillation report over its dp_gtp_remat group; - the Mamba hook uses the mixer's tp_group, and the grouped-MLP hook the expert tensor-parallel tp_group of the module; - FlextronModelManager builds the router on the model's collection and names it by the rank in its pp group. FlextronRouter takes a pg_collection, seeds and counts accumulation steps over its dp_gtp_remat group and gives its tp group and the collection to its linear layers; the collection also supplies the groups of the router's sharded state dict. The injected forward checks the last stage of the model's pp group; - get_batch, get_grad_acc_based_random_choice, is_dataset_built_on_rank and train_valid_test_datasets_provider take a pg_collection. forward_step passes the model's collection, and get_batch reads its tp, pp, cp and dynamic_cp groups as pretrain_hybrid.py does. The new pg_collection and tp_group arguments default to None, which keeps the global groups with a ProcessGroupFallbackWarning (deprecated in 0.21, removed in 0.23); the silent global fallback of model_provider now warns too. get_batch and is_dataset_built_on_rank raise ValueError for a collection whose groups they need are None: torch.distributed treats a None group as WORLD, and a None tp group would build the datasets on every rank. The dataset provider gets the run's collection from training once training passes it to providers with a pg_collection parameter. The router and grouped-MLP tests pass their groups explicitly. On the standard grid every group is the same object as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
FlextronRouter._sync_router_weights broadcast every router parameter from global rank 0 over WORLD. The router's linear layers are sharded over the model's tp group, so at TP > 1 every TP rank received TP rank 0's shard. The full router weight became TP copies of one shard. The copies get identical gradients, so the router trains with 1/TP of its hidden width. On a job whose model spans fewer ranks than WORLD, the broadcast also mixed the routers of different models, or hung when the other ranks built no router. This affects Flextron runs with TP > 1 and Flextron models on a sub-grid. Broadcast each shard only among its replicas: over the model's pp group from its first rank, then over its dp_cp group from its first rank. Every pipeline stage builds a router and finalize all-reduces its gradients over pp, so the pp peers must start equal. dp_cp is the replica group of dense weights, the group that DDP's broadcast_params uses. It is not dp_cp_gtp_remat: with GTP active, the router's linear layers are also sharded over gtp_remat and record dp_cp as their replica group, so a broadcast over dp_cp_gtp_remat would overwrite distinct GTP shards. Which ranks enter the broadcasts: every rank of the model builds the same routers (one per model chunk, from the same config and full layer pattern), with the same parameters in the same order. So all members of a rank's pp group and of its dp_cp group enter the same broadcasts, in the same order, and no rank outside the model enters them. A group of size 1, or an axis set to None, is skipped by all of its members alike, so None never turns into WORLD. The router now requires pp and dp_cp in its collection, and raises ValueError without them. Tests: two CPU tests on 4 ranks check that each TP shard comes from the lowest of its PP x DP-CP replicas (TP2 x DP2 and TP2 x PP2), and that two 2-rank models in one job keep their own weights. Both fail on the parent commit. A third test checks that a collection without pp or dp_cp is rejected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8738 passes the training collection to the optimizer with Gloo groups on, on top of NVIDIA#6259, NVIDIA#8037 and NVIDIA#8055 (which carries NVIDIA#8049 and NVIDIA#6293). The training loop's changes that follow call NVIDIA#8037's collection builder, warn through NVIDIA#6293's and NVIDIA#8049's fallback helpers, and extend NVIDIA#8037's training collection test. NVIDIA#8737, merged above, now carries NVIDIA#8037 as well, so the allowlist conflicts on its total: NVIDIA#8737's side records 194 reads and NVIDIA#8738's 158. It takes 158, which matches the merged entries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The data-parallel group helper that follows replaces the DP x CP helper that NVIDIA#8741 adds to the training loop, and the training utilities' warnings extend NVIDIA#8741's packed-sequence statistics and GPT builder code. NVIDIA#8741 is based on main, without NVIDIA#8037's and NVIDIA#8048's neighbouring lines, so three files conflict. They are resolved as follows: - training.py: keep NVIDIA#8037's _build_pg_collection_from_parallel_state and _get_forward_backward_func next to NVIDIA#8741's _get_model_pg_collection and _get_data_parallel_world_size. train_step's pg_collection docstring takes NVIDIA#8037's text plus NVIDIA#8741's sentence on the single-grid fallback; its p2p_communicator docstring and evaluate's keep NVIDIA#8037's text. train's docstring also keeps NVIDIA#8037's text, with NVIDIA#8741's sentence that a multi-module collection rejects the GPU sniff test and its Raises section. - models/gpt.py: default_layer_spec takes (config, vp_stage, pp_rank=None, pg_collection=None), and GPTModelBuilder passes both NVIDIA#8048's pp_rank and NVIDIA#8741's pg_collection. - test_gpt_builder.py: keep NVIDIA#8741's ModelOpt CP test and expect default_layer_spec(config, 3, 1, pg_collection=pg). 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: - megatron/core/distributed/fsdp/mcore_fsdp_adapter.py: Main adds the ShortcutMoEBlock import (NVIDIA#8312) and the PR adds the resolve_process_groups import. The result keeps both in isort order, along with the PR's _init_dist_index rewrite, which no longer reads parallel_state. - megatron/core/models/common/embeddings/rotary_pos_embedding.py: Main adds the register_capture_constant import for its embedding cache (NVIDIA#8358) and the PR adds the warn_global_process_group_fallback import. The result keeps both, plus the PR's warned cp_group fallback. - pretrain_gpt.py, pretrain_hybrid.py: Main moves is_dataset_built_on_rank and core_gpt_dataset_config_from_args into megatron/training/datasets/providers.py (NVIDIA#8341, NVIDIA#8592). The result takes main's side and keeps the PR's pp_group in get_batch. - examples/t5/pretrain_t5.py: The result keeps main's tokenizer refactor (NVIDIA#8391) and the PR's pg_collection default passed to T5Model. The unused build_tokenizer import that main dropped stays dropped. 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 in is_dataset_built_on_rank_explicit, where main moved the code. 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>
…NVIDIA#8749, NVIDIA#8735, NVIDIA#8059, NVIDIA#8038, NVIDIA#8724 and NVIDIA#8725 after their update to main 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) splits unpermute into a fused path, a reference _unpermute_loop that takes ep_size, and a new public unpermute() that reads the global EP world size. The result keeps main's split and re-applies the PR's optional ep_size argument and warned resolve_process_groups fallback to the new unpermute(), so no new parallel_state read remains. Main's unpermute tests in test_moe_batch_invariant_unpermute.py and test_moe_kernels.py pass ep_size explicitly instead of setting the global EP world-size override. - megatron/core/transformer/cuda_graphs.py: Main adds CudaGraphManager._initialize_mempool and the PR adds _resolve_reuse_cudagraphs. The result keeps both, with reuse decided lazily from the pp group as the PR does. - megatron/core/tensor_parallel/random.py: CheckpointFunction.forward keeps the PR's explicit tp_group and main's new autocast capture. - tests/unit_tests/dist_checkpointing/utils.py: Both helpers keep main's config.finalize_optimizer_config() call (NVIDIA#8213) and then the PR's get_megatron_optimizer call with an explicit pg_collection. - pretrain_gpt.py, pretrain_hybrid.py: The dataset provider keeps the PR's pg_collection parameter, which its body passes to is_dataset_built_on_rank. - megatron/core/distributed/fsdp/mcore_fsdp_adapter.py, tests/unit_tests/ssm/test_gated_delta_product.py, tests/unit_tests/transformer/test_attention_variant_dsa_gqa.py: Import conflicts. The result keeps the imports of both sides. 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: - megatron/core/extensions/transformer_engine.py: In split_te_layernorm_column_parallel_linear, the TEColumnParallelLinear call gets pg_collection=fused_layer._pg_collection from the base PR, and main (NVIDIA#8426) appends .to(device=fused_layer.weight.device). The result keeps both. The other changes from main merge without conflict: TENorm .to(device), the RMSNorm is_rmsnorm_weight markers (NVIDIA#8246) and the mark_grouped_tensor helpers (NVIDIA#6828). - tests/unit_tests/extension/test_te_layernorm_column_parallel_linear.py: The imports combine the PR's process-group imports with main's parenthesized TENorm import. Main's new test_rmsnorm_gamma_marker (NVIDIA#8246) stays where main put it, and the PR's _all_ranks helper and TestShardedStateDictDpCpGroup class follow it unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…main 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>
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>
…NVIDIA#8731, NVIDIA#8722, NVIDIA#8723 and NVIDIA#8727 after their update to main Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - tests/unit_tests/distributed/mfsdp_v2/test_mcore_moe.py: Main (NVIDIA#8312) and the PR each add a new test after test_build_train_step_and_clip. The result keeps all of main's version: the grouped/sequential standard MoE test, the shortcut MoE test, their helpers and imports. It also keeps the PR's fully_sharded_optimizer import and its test_optimizer_names_experts_by_the_model_expert_layout unchanged. - pretrain_gpt.py, pretrain_hybrid.py: The conflicts come only from the criss-cross merge history. Main makes no net change to these files. The result keeps the PR's pg_collection parameter on train_valid_test_datasets_provider and its is_dataset_built_on_rank predicate bound to that collection. Adapted to main outside the conflicts: - tests/unit_tests/test_process_group_collection_end_to_end.py: Main's get_model_for_inference reads the run config and passes the tokenizer config to the model builder (NVIDIA#8391). The inference test takes the run_config fixture, and its stub builder takes the tokenizer config. 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>
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>
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>
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>
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>
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>
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>
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>
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 #7991, #8722, #8723, #8736, #8731, #8727, #8739, #8763, #8773 and #8775. Together they contain every other PR of this series except #8777, which sits beside this one on the same base. Please review the diff from their merge: scoped diff.
ParallelStateDeprecationWarningand its per-call-site record from Deprecate the parallel_state accessors of the global grid #8765,build_process_group_collection()from Extract build_process_group_collection from initialize_model_parallel #8039,get_registered_process_groups()from Add a public process-group registry to parallel_state #8747, and the optimizer's grad-stats fallback record from Warn on optimizer, TP and helper fallbacks to WORLD or the global grid #8734.t5_model.py,multi_token_prediction.py,fully_sharded_optimizer.py, the Gloo accessor docstrings ofparallel_state.pyand the duplicated-mode linears of the attention and MoE modules, and regenerate the process-group allowlist. Each merge commit lists its resolutions.Land this right before #8777, after everything it contains, #8772, #8773 and #8775 included.
Why. The tests that forbid the global grid each cover one component, mostly with stand-ins. No test ran model build, DDP and the optimizer, training steps, a
torch_distsave and load, and the inference build together on a collection whose TP and DP groups differ from the global ones. A component that reads the global grid, or that passes no group (WORLD) to a collective, could hide between those tests.What. New
tests/unit_tests/test_process_group_collection_end_to_end.py. No library change.Utils.initialize_model_parallel. A second collection comes frombuild_process_group_collection(order="dp-tp-cp-ep-pp")and is not registered. Its TP and DP groups differ from the global ones on every rank.forbid_global_process_groups()withProcessGroupFallbackWarningandParallelStateDeprecationWarningas errors. The once-per-process records of fallbacks, accessor call sites and optimizer grad-stats fallbacks are emptied first, so a warning from an earlier test cannot hide a fallback. A failure names the phase, and the chained error names the accessor or fallback.Float16Module, DDP with the distributed optimizer), build the optimizer withget_megatron_optimizer, run two steps withget_forward_backward_func, save and reload atorch_distcheckpoint, and build the model for inference withget_model_for_inferenceand run it throughGPTInferenceWrapper.get_model_for_inferencereads the run config and passes the tokenizer config to the model builder. The inference test takes therun_configfixture, and its stub builder takestokenizer_config.Float16Module), DDP buffers and bucket groups, the optimizer and its grad-stats group, and the inference wrapper keep groups with the collection's ranks. None of them keeps WORLD or a group object of the global grid, directly or in a list, tuple, dict or collection. Several groups have the same ranks in both layouts, so only the object tells them apart. The inference context resolves the model's collection._set_random_seed(..., pg_collection=...), asinitialize_megatron()does, so the CPU generator that initializes the learned position embeddings is seeded too.NVTE_FLASH_ATTNandNVTE_FUSED_ATTNbefore every test, and since Make MIMO vision encoder attention backend configurable #7362set_attention_backend()refuses values that disagree with the config's backend. The test clears them before each model it builds.Tests.
test_the_block_rejects_global_reads_and_fallbacksfailed on every rank.cpgroup or WORLD, and the shard check reported a broadcast over WORLD.test_process_group_collection_end_to_end.pypasses 10 of 10. The file is new, so all 10 are new tests. The same job runs 12 other test files of the series (data paths, dataset providers and ownership,get_batch, Megatron-FSDP MoE, optimizer parameter names, the high-level inference API, example process groups, owner linears and theparallel_statedeprecation tests): 637 tests pass here and 637 on the base, and none fail. There are no regressions against the base.test_process_group_collection_end_to_end.pypasses 10 of 10 on 4 GPUs.-W error::megatron.core.process_groups_config.ProcessGroupFallbackWarning. Run in one process aftertest_emerging_optimizers.py, all 113 tests passed. Before the NVTE fix, 3 of the 10 failed there because of the conftest variables.Compatibility.
determinism-exemptis needed only while the PRs below this one are unlanded. CI diffs against main, and the base contains registered kernel files. This PR's own diff passes the coverage check.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. The merge carries its bases' edits to those classes where the code moved; this PR's own diff does not change. On 4 GPUs against its new base, the Megatron-FSDP adapter tests (7 files) show no regressions: 81 passed here, 81 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