Repository navigation
Conversation
get_gpt_modelopt_spec keeps the layers of one pipeline stage: it counts them with get_num_layers_to_build and, for MoE models, slices the dense/MoE layer pattern at get_transformer_layer_offset. It called both helpers without a pipeline rank or virtual stage, so they read the global pipeline rank. A model built on its own pipeline grid (a distillation teacher, an RL inference model, any builder given a ProcessGroupCollection) got the layers of the global stage, while TransformerBlock numbered them by its collection's rank. With a PP=2 collection over a global PP=1 grid and three layers split 1 + 2, the second stage built one layer instead of two. With a virtual pipeline, the MoE slice asserted because vp_stage was missing. Add vp_stage and pp_rank parameters and forward them to both helpers, as get_gpt_decoder_block_spec does. Pass the collection's pipeline rank from the callers that hold one: GPTModelBuilder through default_layer_spec, which also passes its vp_stage; modelopt_gpt_hybrid_builder; and the distillation teacher, which is built on the student's collection. Both parameters default to None, so callers that pass neither keep the global rank. The training loop builds its collection from the global grid, so the rank it passes is the same as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Record the five inference reads removed in the previous commit and the shim read in InferenceConfig.resolve_pg_collection that became a guarded resolve_process_groups call: 173 -> 168 reads, 1 guarded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
When a caller passed neither a process-group collection nor a pipeline communicator, each forward_backward schedule built both from parallel_state, with no warning and no removal date. That default collection also stored the GTP-remat-inclusive data-parallel groups under dp and dp_cp, while use_mpu_process_groups() and the HyperCommGrid builders hold the replicate groups there. A collection the caller did pass was checked with hasattr asserts, which always pass for declared fields, so a collection without tp or cp failed later with an AttributeError on None. Add _resolve_schedule_groups, shared by the three schedules. Without a collection it goes through resolve_process_groups, which warns once per schedule (deprecated in 0.21, removed in 0.23) and builds only the fields that the schedules and finalize_model_grads read; the default communicator is built over the resolved pp group. dp_cp is the replicate group, as in use_mpu_process_groups(). Its readers use dp_cp_gtp_remat when it is set, so they reduce over the same ranks as before. The dp field had no reader and is no longer built. A collection the caller passes must set tp and cp, or the schedule raises ValueError. The hasattr checks on the communicator's config go too: both communicator classes set it in their constructor. get_forward_backward_func warns when it selects the schedule from the global pipeline sizes. get_pp_rank_microbatches takes its communicator as a required keyword argument; every caller already passes one. Depends on NVIDIA#8049. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The schedules no longer read the global process groups in their default collection and communicators, nor in get_pp_rank_microbatches. The default collection's fallback is one guarded resolve_process_groups call, which the checker records in place of the reads it replaces. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
TransformerBlock read pg_collection.pp behind a hasattr check, which is always true because ProcessGroupCollection returns None for unset fields. A collection without pp therefore gave pipeline rank 0 on every stage, and each stage silently built the first stage's layers with the first stage's layer numbers. TransformerLayer and Float16Module had the same gap. With pipeline parallelism, TransformerBlock, TransformerLayer and Float16Module now require pg_collection.pp to be this rank's pipeline group and reject an unset field or None. Without pipeline parallelism pp may stay unset or None, as before. The block and the layer also require tp. When the caller omits the collection, TransformerBlock and TransformerLayer fall back through resolve_process_groups. It emits a ProcessGroupFallbackWarning (deprecated in 0.21, removed in 0.23) and builds only the fields that the layers' modules read, each the same global group as before. Float16Module takes a pg_collection argument and warns when neither the caller nor the wrapped module provides one. In multi_token_prediction.py, the pp_rank fallbacks of get_mtp_layer_offset and get_mtp_num_layers_to_build and the metric_avg_group fallback of process_mtp_loss warn. The acceptance-count guard no longer probes the global grid: process_mtp_loss takes the tensor-parallel size from the config, so vocab-sharded logits without a tp_group raise on any grid. MultiTokenPredictionLayer checks that its collection sets tp, cp and pp. Depends on NVIDIA#8049 (and NVIDIA#6293). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
TransformerBlock and TransformerLayer now fall back through resolve_process_groups, which --update records as guarded reads in place of the use_mpu_process_groups shims. The MTP acceptance-count guard no longer reads the global tensor-parallel size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflict resolutions: - parallel_state.py: keep the registered-callback teardown. Main's inline MoonEP finalize in destroy_model_parallel() becomes a RELEASE_COMMUNICATION callback that virtual_expert_load_balancer.py registers. The callback looks up VirtualExpertLoadBalancer.finalize() on the class at call time, as main's inline code did. Keep main's resets of _WEIGHT_REPLICA_RANK_SETS and the dynamic TP x DP-CP group map. - full_cuda_graph.py: keep main's deferred-validation clearing in reset_cuda_graph(). Teardown now registers _release_full_cuda_graphs(), which calls reset_cuda_graph() only when a full-iteration graph exists, so teardown does not implicitly initialize the rerun state machine. - cuda_graphs.py, test_cuda_graphs.py: keep the imports and new tests of both sides. - test_schedule_chunk_1f1b.py: take main's version. Its class-scoped model-parallel context already shares one layout across tests. Also drop main's DeepEP v2 elastic buffer in reset_fused_a2a_buffers(), cover the new teardown callbacks in test_parallel_state_teardown_resources.py, and refresh the process-group usage allowlist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
When T5Model is called without pg_collection, LanguageModule falls back to the global grid and stores the result in self.pg_collection, but T5Model kept using its local argument. With rope position embeddings it then read pg_collection.cp from None and raised AttributeError, and the embedding and the encoder and decoder blocks each fell back to the global grid again on their own. Use self.pg_collection after LanguageModule has resolved it, and cover the rope path in the process-group constructor test. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The TrainingConfig migration (NVIDIA#8149) moved train_sync_interval, the weight hash check interval, the GPU sniff test interval and the manual GC settings from args to the run config's train section. The test only set them in args, so after a rebase past NVIDIA#8149, post_training_step_callbacks failed on cfg.train. Set the same values in both, which passes before and after the migration. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The fallback warnings said they were deprecated since Megatron Core 0.20 and would be removed in 0.22. No release emits them yet: neither core_r0.20.0 nor main has the warning code, and package_info is at 0.21.0, so they first ship in 0.21. Removing them in 0.22 would leave users a single release of warnings, short of the N+2 policy in docs/api-backwards-compatibility-check.md that the comment cites. Set the defaults to 0.21 and 0.23, say in the comment why, and check the dated text in the warning test instead of comparing the message with the constants it is built from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
get_model_for_inference() and tools/run_text_generation_server.py pass modelopt_gpt_hybrid_builder straight to get_model(). The builder takes args as its first positional parameter, but get_model() calls its provider with keyword arguments only (pre_process, post_process, config, pg_collection), so with ModelOpt enabled both entry points raise "missing 1 required positional argument: 'args'" before any model is built. The regression came in with NVIDIA#5169, which replaced partial(model_provider, builder) by the bare builder. Bind args with functools.partial at both call sites, which is what model_provider() did for this builder before. Add CPU tests that drive both entry points with a stand-in builder of the same signature and a stand-in get_model that calls the provider the way get_model() does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The comments above the ModelOpt get_model() calls in get_model_for_inference() and tools/run_text_generation_server.py say that get_model() runs the ModelOpt-checkpoint auto-detection. It does nothing there: both entry points take this branch only when args.modelopt_enabled is already set, and maybe_enable_modelopt() returns at once in that case. Remove the claim and fold the note about binding args into the remaining comment. Since NVIDIA#5169 moved the builder choice ahead of get_model(), these entry points also no longer pick the ModelOpt builder for a ModelOpt checkpoint served without --modelopt-enabled. Restoring that is a separate behaviour change and is left to its own fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
On current main (NVIDIA#8391), get_model_for_inference() reads get_run_config() before it picks a builder, so the first test fails with "run config is not initialized" before it reaches the ModelOpt branch. Use the run_config fixture, which sets a run config for the test and exists on this base as well. Both tests also asserted that the builder receives pg_collection=None. Once the text generation server passes the registered process groups to get_model(), that holds only while nothing is registered. Record the groups the get_model() stand-in receives and check that the builder gets exactly those. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The wide-residual tests build their layers with an empty ProcessGroupCollection. TransformerLayer now requires the collection to set tp, so construction raised before the tests reached their checks. The tests run in one process without tensor parallelism, so they set tp to None. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The get_model() stand-in passed pg_collection=None straight through, while the real get_model() swaps None for the global groups first. On main, a wrapper that dropped pg_collection would therefore still pass. The stand-in now swaps None for a distinct object, so the builder must receive exactly the groups get_model() built with. The tests compared the bound args by value, which a copy of the Namespace also satisfies; they now also check identity. The stand-in builder copies the real builder's signature by hand, so add a test that compares the two where ModelOpt is installed and the real module imports. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
The wrapper resolves its groups through InferenceConfig.resolve_pg_collection, but test_wrapper_rejects_mhc_pipeline_inference handed it a SimpleNamespace config, so all three cases failed with an AttributeError before reaching the mHC check. The test now builds an InferenceConfig on a ProcessGroupCollection that sets every group inference reads. Signed-off-by: Yan Xu <yxu1@nvidia.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The device fixture read torch.cuda.current_device(), which is cuda:0 on every rank until Utils.initialize_distributed binds the rank's GPU. pytest resolves device before vision_cp_group, which is what first initializes distributed when the file runs on its own. So the first vision context-parallel test put every rank's tensors on cuda:0, and NCCL failed with "Multiple ranks detected using the same GPU", then aborted the communicators for the tests after it. The fixture now initializes distributed before it reads the device. Signed-off-by: Yan Xu <yxu1@nvidia.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…anch NVIDIA#6293 now dates the global process-group fallbacks from Megatron Core 0.21, the first release that emits them, with removal in 0.23. Take its defaults and keep this branch's note that a fallback which starts to warn in a later release passes its own versions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#6293 now dates the fallback defaults from 0.21, the first release that emits them, with removal in 0.23. The docstring of warn_global_process_group_fallback still said that a fallback which starts to warn after 0.20 passes its own versions; that cohort now starts after 0.21. Two tests checked that explicit versions reach the message by passing 0.21 and 0.23. Those now equal the defaults, so the tests would pass even if the arguments were ignored. Pass 0.22 and 0.24 instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
build_process_group_collection() records the groups it creates in _global_process_group_list for update_pg_timeout(). With NVIDIA#7029, destroy_model_parallel() destroys every group on that list, so the groups of a collection that was built but never registered are destroyed by the next teardown too. test_build_matches_registered_groups_without_parallel_state builds a grid while another one is registered, then re-initializes with the same layout to compare. Under NVIDIA#7029 the re-initialization destroyed the built groups, so reading their ranks raised KeyError, and the cleanup raised "Invalid process group specified" for groups that no longer existed. test_build_rank_window's cleanup failed the same way on the ranks inside the window. Read the built groups' ranks before re-initializing, and destroy only the built groups that teardown has not destroyed already. Both tests pass with and without NVIDIA#7029. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Tests for components that take an explicit ProcessGroupCollection have no shared way to prove that the component ignores the global parallel grid. Each test hand-rolls a patch of a few parallel_state accessors, which misses names a module imported directly, or builds a collection whose groups match the global ones, so a stray global read still passes. Add shared helpers to tests/unit_tests/test_utilities.py: - forbid_global_process_groups(): inside the block, every accessor that tools/check_process_group_usage.py counts raises AssertionError, on parallel_state and in every imported megatron module that bound it by name. The use_mpu_process_groups() shim and the pipeline-stage predicates are forbidden by default. Calls made by parallel_state itself keep working, and everything is restored on exit. - new_group_with_same_ranks(): a distinct communicator over the same ranks, so an identity check catches a component that used the global group. Every rank creates every group of that kind, in one order. - build_test_pg_collection() and destroy_test_pg_collection(): the collection of a standard grid built on HyperCommGrid without the parallel_state globals, with the same ranks as initialize_model_parallel. Fields it does not build are explicitly None, so no resolver falls back to the global grid. - A grid_pg_collection fixture in conftest.py that builds a collection from indirect parameters and destroys its groups after the test. The new test file checks each helper, including rank parity with initialize_model_parallel on eight grid shapes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#7047 (DCP V2) added the ProcessGroupCollection fields dynamic_cp and dynamic_tp_cp. build_test_pg_collection() was written before it and did not set them, so test_build_test_pg_collection_matches_initialize_model_parallel failed its field-set check on every parametrization against current main (8 of 8 with 4 gloo ranks on CPU). Set both to empty maps: the helper builds a grid without dynamic context parallelism, and that is what initialize_model_parallel() and use_mpu_process_groups() give such a grid. Because the collection now holds dicts, destroy_test_pg_collection() destroys only the ProcessGroup values, and the test compares dict fields key by key instead of passing a dict to get_process_group_ranks() (an empty dict silently stood for WORLD). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8049 now dates the global process-group fallbacks from Megatron Core 0.21, with removal in 0.23, and aligns its docstring and explicit-version tests with those dates. Merge its current head so this branch builds on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8049 now dates the global process-group fallbacks from Megatron Core 0.21, with removal in 0.23, and aligns its docstring and explicit-version tests with those dates. Merge its current head so this branch builds on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#8049 now dates the global process-group fallbacks from Megatron Core 0.21, with removal in 0.23, and aligns its docstring and explicit-version tests with those dates. Merge its current head so this branch builds on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#6259 adds the ProcessGroupCollection fields intra_dp_cp_gloo and intra_expt_dp_gloo. Merge it so this branch can fill them in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
…anch NVIDIA#6293 now dates the global process-group fallbacks from Megatron Core 0.21, with removal in 0.23, and gives the LLaVA test model a device that matches the test's. Merge its current head so this branch builds on it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#6259 adds the ProcessGroupCollection fields intra_dp_cp_gloo and intra_expt_dp_gloo. Merge it so this branch can fill them in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#6259 added the ProcessGroupCollection fields intra_dp_cp_gloo and intra_expt_dp_gloo. build_process_group_collection() already creates both Gloo groups but did not pass them to the collection it returns, so with both PRs merged the collection lacks the two fields and the builder tests' field-set checks fail. Pass both groups to the collection, so the builder returns every field initialize_model_parallel() records. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
NVIDIA#6259 added the ProcessGroupCollection fields intra_dp_cp_gloo and intra_expt_dp_gloo. NVIDIA#8017's build_test_pg_collection() predates them, so with both PRs merged its collection lacks the two fields and test_build_test_pg_collection_matches_initialize_model_parallel fails its field-set check (8 of 8 with 4 gloo ranks on CPU). The helper builds the NCCL groups model components use and no Gloo groups. Set both fields to None, as in a job built without Gloo groups (the documented meaning of None for these fields), and list them with the other fields the helper does not build. 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>
…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/inference/contexts/dynamic_context.py: The PR rounds the vLLM fused-MoE padding to the context's own TP size through a shared per_rank_worst_case_token_count. Main (NVIDIA#4743) scales the MoE row count by tp_ep_size instead of ep_size. The result keeps both: moe_max_rows is max(max_tokens, per_rank_worst_case_token_count * tp_ep_size). Adapted to main outside the conflicts: - tests/unit_tests/inference/contexts/test_context_process_groups.py: Main (NVIDIA#4743) renames the allocate_buffers keyword ep_group to tp_ep_group. The PR's MoE buffer test now checks tp_ep_group against pg_collection.tp_ep, which spans the EP ranks when expert TP size is 1. 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>
Adapted to main outside the conflicts: - megatron/core/inference/config.py: resolve_pg_collection now also requires tp_ep, both to use the model's collection and in the deprecated global fallback. Main's NVIDIA#4743 reads tp_ep in the dynamic context and engine. Without this, the fallback left tp_ep unset, so EP>1 or ETP>1 runs read it as None and sized it to 1. A collection set on InferenceConfig.pg_collection is still used as-is. A model collection without tp_ep now takes the warned global fallback. - tests/unit_tests/inference/test_inference_process_group_fallbacks.py: the tests check that the fallback builds tp_ep from the global group and that a model collection lacking only tp_ep falls back. 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: - train_rl.py: Main adds a PackedSeqParams import for its rewritten forward_step, and the PR replaces the global is_pipeline_last_stage import with is_pp_last_stage. The result keeps both. The PR's forward_step check, which reads the pipeline group from the model's pg_collection, applies cleanly to main's rewritten forward_step. - tests/unit_tests/rl/test_rl_utils.py: Main adds an import of weakref for its cached-embedding check, and the PR adds contextmanager for its forbid_global_grid helper. The result keeps both imports, along with main's new tests and the PR's new tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Yan Xu <yxu1@nvidia.com>
Conflicts: - tools/run_inference_performance_test.py: The PR adds the is_pp_first_stage/is_pp_last_stage import and drops the mpu import. It does this so get_inference_engine checks the stages on the wrapper's own pp_group. Main (NVIDIA#8391) drops the build_tokenizer import and switches main() to get_tokenizer(). The result keeps both sides, so the file no longer refers to mpu or build_tokenizer. 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: - megatron/core/extensions/transformer_engine.py: Both sides added module-level code at the same place. The result keeps the PR's TE autocast check and global-state reset with their teardown registrations, followed by main's grouped-tensor marker helpers from NVIDIA#6828. - megatron/core/full_cuda_graph.py: reset_cuda_graph keeps the PR's classmethod form and main's synchronize before release and reuse-event reset from NVIDIA#7780 and NVIDIA#8358. gc.collect() runs only when a graph was captured, as in the PR. - megatron/core/transformer/cuda_graphs.py: The result keeps the PR's all_runners set and main's capture-constant tracking and captured_runners. The PR's _reset_cuda_graph_runner helper now carries main's graph.reset() and capture-constant release, and both delete_cuda_graphs and release_all_cuda_graphs use it. - megatron/core/transformer/moe/token_dispatcher.py: Import-only conflict; both main's PackedSeqParams import and the PR's teardown import are kept. Adapted to main outside the conflicts: - megatron/core/transformer/cuda_graphs.py: delete_cuda_graphs follows main's NVIDIA#8358 contract and also releases training graphs that create_cudagraphs created. Its docstring and the release_all_cuda_graphs docstring now describe that contract instead of the PR's earlier claim that training graphs survive an inference suspend. - tests/unit_tests/transformer/test_cuda_graphs.py: The fake graph gets a reset() and the fixture isolates captured_runners and stubs torch.cuda.synchronize, which main's release path now calls. The training-graph test now asserts that delete_cuda_graphs releases created training graphs. 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/training/training.py: Main restructured the train data iterator path and dropped the RL branch, and the PR passes pg_collection through the data-loader builders. The result takes main's structure with the PR's pg_collection plumbing re-applied, and matches the resolution of the same conflict in NVIDIA#8742. - megatron/elastification/pretrain_hybrid_flex.py: Main moved the dataset provider body to the shared build_gpt_datasets (NVIDIA#8341), and the PR made is_dataset_built_on_rank and the provider take pg_collection. The result delegates to build_gpt_datasets and passes is_dataset_built_on_rank bound to pg_collection when one is given. is_dataset_built_on_rank keeps the PR's pg_collection body and gains main's is_packed_sequence parameter. With no pg_collection, the deprecation warning and global fallback now happen inside is_dataset_built_on_rank on each call rather than once in the provider. Adapted to main outside the conflicts: - tests/unit_tests/elastification/test_elastification_process_groups.py: The provider test patches the shared provider's dataset builder and run config, since the flex module no longer builds datasets itself. - tests/unit_tests/training/test_dataset_providers.py: Main's signature check accepts the trailing pg_collection parameter of the hybrid-flex provider. 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, examples/t5/pretrain_t5.py: The PR adds the ProcessGroupCollection import and pg_collection plumbing. Main's tokenizer refactor (NVIDIA#8391) removes the build_tokenizer import and adds get_run_config. The result keeps the PR's pg_collection handling and main's tokenizer and config changes, without build_tokenizer. - megatron/core/models/common/embeddings/rotary_pos_embedding.py, tests/unit_tests/pipeline_parallel/test_fine_grained_activation_offloading.py: Only the imports conflict. The result keeps the PR's imports and main's new ones (NVIDIA#8358, NVIDIA#7961). - pretrain_gpt.py, pretrain_hybrid.py: Main (NVIDIA#8341, NVIDIA#8592) moves the dataset rank predicate and config builder into megatron/training/datasets/providers.py. The result takes main's move and keeps the PR's pp_group in get_batch. Adapted to main outside the conflicts: - megatron/training/datasets/providers.py: The mtp_on_this_rank call in the moved predicate now passes the pipeline group, as the PR did in the scripts, so GPT and hybrid runs do not take the deprecated fallback. 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/training/training.py: Main restructured pretrain(), setup_model_and_optimizer(), train() and the data loader builders. The result keeps main's new code and adds the PR's pg_collection plumbing back into it. Main's NVIDIA#7472 added its own _get_model_pg_collection(model_chunk), which shadowed the PR's helper of the same name. The two are now one helper, (model_chunk, pg_collection=None, *, owner=...), which falls back to the global groups with a warning. Every caller passes model[0], including main's tensor-metric observer calls and the save_grads, save_activations and save_dgrads calls from this PR. - pretrain_gpt.py, pretrain_hybrid.py: Main moved the dataset helpers to megatron/training/datasets/providers.py, so the result takes the deletion. The PR's pp_group argument to mtp_on_this_rank is re-applied in the moved rank predicate in providers.py. - examples/t5/pretrain_t5.py: Keeps the PR's pg_collection default and main's get_run_config() call, and drops the unused build_tokenizer import that main removed. - megatron/core/models/common/embeddings/rotary_pos_embedding.py, tests/unit_tests/training/models/test_gpt_builder.py: Import-only conflicts. Both sides' imports are kept. - tests/unit_tests/test_training.py: Keeps the new tests from both sides. The PR's test no longer patches get_megatron_optimizer_config, which main's OptimizerConfig migration (NVIDIA#8213) removed. Adapted to main outside the conflicts: - tests/unit_tests/training/test_checkpointing_fallback_warnings.py: Three tests take the run_config fixture, since main's OptimizerConfig migration (NVIDIA#8213) moved the settings they read into the run config. - tests/unit_tests/training/test_training_fallback_warnings.py, test_training_loop_pg_collection.py, test_training_pg_collection.py: Updated for the single model-chunk helper, train()'s keyword-only next_train_iterator and run_eval, and the optimizer config read from run_config.optimizer. - megatron/rl/training_setup.py: Main moved the GRPO microbatch re-init here, and it reads the global data-parallel world size. The PR's sample-collection read in train() no longer applies to it. 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/training/training.py: Main added the tensor-metric observers, the caller-managed data path, build_train_dataloader and moved the RL code out of train(). The result keeps all of that and layers the PR's pg_collection plumbing on top, including the pg_collection argument to build_train_valid_test_datasets and its docstrings. Main's and the PR's _get_model_pg_collection helpers are combined into one, (model_chunk, pg_collection=None, *, owner), and every caller passes model[0]. - pretrain_gpt.py, pretrain_hybrid.py: Main moved the provider body to build_gpt_datasets in megatron/training/datasets/providers.py. The result takes main's refactor and re-applies the PR's provider signature, which binds pg_collection into the is_dataset_built_on_rank predicate. The PR's get_batch is kept. - tests/unit_tests/data/test_get_batch.py: Keeps main's parametrization and stub config and adds the PR's ProcessGroupCollection to the is_dataset_built_on_rank call. Adapted to main outside the conflicts: - megatron/training/datasets/providers.py: Main moved is_dataset_built_on_rank here, so the PR's change is re-applied to it and to is_dataset_built_on_rank_explicit. The tp and pp groups come from pg_collection, a missing group raises ValueError, and a missing pg_collection warns under the owner name is_dataset_built_on_rank. - tests/unit_tests/data/test_dataset_provider_process_groups.py: The PR's test targets the shared predicate and main's rule that a sequence-packing scheduler builds on every pipeline stage. - tests/unit_tests/training/test_dataset_providers.py: Main's test now expects the pg_collection parameter and the bound predicate. 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/transformer_layer.py: Main (NVIDIA#8424) moves HyperConnectionTransformerLayer into hyper_connection_transformer_layer.py. The result takes main's side and re-applies the base's edit that gives both hyper-connection modules the layer's TP group in the new file. - megatron/training/training.py: The base threads explicit process-group collections through setup, data loading and train_step, and main adds the tensor-metric observer, the new train-loop and data-loader helpers, and cfg.optimizer. The result keeps both. The RL block in train() is dropped because main (NVIDIA#4264) moves RL setup to megatron/rl/training_setup.py, which still reads the global data-parallel size. The two _get_model_pg_collection helpers are unified into one that takes a model chunk and warns with ProcessGroupFallbackWarning before falling back to the global groups. - tests/unit_tests/test_training.py, tests/unit_tests/training/models/test_gpt_builder.py: Both sides' tests and imports are kept. The setup test no longer patches get_megatron_optimizer_config, which main (NVIDIA#8213) removes. Adapted to main outside the conflicts: - tests/unit_tests/training/test_training_fallback_warnings.py, test_training_loop_pg_collection.py, test_training_pg_collection.py: The tests pass a model chunk to _get_model_pg_collection, use main's keyword-only train() arguments, and set run_config.optimizer. 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#7029, NVIDIA#8730, NVIDIA#8746 and NVIDIA#8745 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: - examples/t5/pretrain_t5.py: This branch passes pg_collection into T5Model, and main moves the script to get_run_config() and get_tokenizer() (NVIDIA#8391). The result keeps both and drops the build_tokenizer import that main no longer uses. - megatron/core/inference/contexts/dynamic_context.py: This branch resolves pg_collection and sizes buffers from self.tp_size, and main adds expert tensor parallelism to inference (NVIDIA#4743). The result applies main's tp_ep sizing of moe_max_rows to the resolved groups. Main's tp_ep lookup takes the group from pg_collection, with the EP group as fallback, instead of reading the global group. A caller that gives no full collection therefore gets the EP group as tp_ep, which mis-sizes the MoE buffers when ETP > 1. - megatron/core/models/common/embeddings/rotary_pos_embedding.py: Both sides add an import. The result keeps both. - megatron/training/training.py: Main moves the RL inference-model build to megatron/rl/training_setup.py (NVIDIA#4264). The result takes main. - pretrain_gpt.py, pretrain_hybrid.py: Main moves the dataset predicate and config builder to megatron/training/datasets (NVIDIA#8341, NVIDIA#8592). The result takes the move and keeps this branch's pp_group in get_batch. Adapted to main outside the conflicts: - megatron/training/datasets/providers.py: The moved is_dataset_built_on_rank passes pp_group to mtp_on_this_rank, as the scripts did before the move. - megatron/rl/training_setup.py: RLSetupCallback passes the trained model's pg_collection to build_rl_inference_model as training_pg_collection, re-applying the PR's edit at the call site NVIDIA#4264 moved. test_setup_callback expects the new keyword. - tests/unit_tests/inference/high_level_api/test_apis.py: The stub global grid in the inference-config fallback test sets tp_ep, which the fallback requires now that inference reads it (NVIDIA#4743). 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 drops build_tokenizer and adds get_run_config; the PR drops the mpu import and adds warn_global_process_group_fallback and get_pg_rank. The result keeps main's tokenizer and config changes with the PR's imports. - megatron/training/datasets/providers.py: The file is new on main and takes the PR's dataset rank check from pretrain_gpt.py and pretrain_hybrid.py. The result keeps the base PRs' pg_collection and vp_size plumbing, and wraps the compatibility read of the virtual pipeline size in global_process_group_fallback. A sequence-packing scheduler still builds datasets on every pipeline stage, as on main. - megatron/training/training.py: Main adds a second _get_model_pg_collection(model_chunk) for its tensor metrics (NVIDIA#7472). The result keeps one helper that takes a model chunk and the run's collection, with a warned fallback. The PR's global_process_group_fallback blocks stay around the remaining global reads. Adapted to main outside the conflicts: - megatron/rl/training_setup.py: Main moves the GRPO microbatch calculator reinitialization into RLSetupCallback, where it reads mpu.get_data_parallel_world_size(). It now uses the size of the model's data-parallel group (dp_gtp_remat, else dp). This matches the global default except when the _MPU_DATA_PARALLEL_WORLD_SIZE override is set. - tests/unit_tests/rl/test_rl_utils.py: test_setup_callback stubs get_attr_wrapped_model to supply that group instead of patching mpu.get_data_parallel_world_size. The process-group allowlist records the reads main added since this PR was written. Also in this merge: - tests/unit_tests/test_parallel_state_deprecation.py: The core-fallback test counts only the fallback warning of resolve_process_groups. The TP helper's own warning comes with NVIDIA#8060, which this PR's base does not have. 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>
Conflicts: - examples/bert/pretrain_bert.py, examples/t5/pretrain_t5.py, tools/run_inference_performance_test.py, train_rl.py, rotary_pos_embedding.py, token_dispatcher.py and the import blocks of test_fine_grained_activation_offloading.py and test_gpt_builder.py: the PR replaced mpu imports with group helpers and main added or dropped imports. The result keeps both and drops build_tokenizer, which main removed. pretrain_t5.py also gains main's get_run_config() call after the PR's pg_collection default. - megatron/core/extensions/transformer_engine.py: keeps the PR's TE autocast teardown checks and main's grouped-tensor marker helpers. - megatron/core/full_cuda_graph.py, megatron/core/transformer/ cuda_graphs.py: the PR added teardown release paths and main added capture constants, captured_runners and graph.reset(). The PR's _reset_cuda_graph_runner now also resets each graph and releases capture constants, and both delete and teardown paths use it. - megatron/core/inference/contexts/dynamic_context.py: keeps the PR's TP-aware worst-case token count, scaled by main's tp_ep_size. - megatron/core/transformer/transformer_layer.py: takes main's move of HyperConnectionTransformerLayer (NVIDIA#8424); the PR's tp_group edit is re-applied in hyper_connection_transformer_layer.py. - pretrain_gpt.py, pretrain_hybrid.py, pretrain_hybrid_flex.py, test_get_batch.py: main moved the dataset providers into megatron/training/datasets/providers.py. The PR's pg_collection plumbing and warned fallbacks are re-applied there. Main's NVIDIA#8592 rule replaces the PR's stage check, so packed datasets build on every pipeline stage. - megatron/training/checkpointing.py: main's layer-wise optimizer condition with the PR's get_pg_rank(dp_gtp_remat_group). - megatron/training/training.py: keeps the PR's single pg_collection build and main's tensor metrics, dataloader and optimizer paths. The two _get_model_pg_collection helpers become one chunk-based function that warns on its global fallback, so main's tensor-metric callers now warn when the model has no collection. - megatron/rl/training_setup.py, tests/unit_tests/rl/test_rl_utils.py: both sides size the GRPO calculator from the model's dp_gtp_remat or dp group. The result reads the model's pg_collection once and also passes it to build_rl_inference_model as training_pg_collection. - tests/unit_tests/test_training.py: keeps the PR's setup test without the optimizer-config monkeypatch main removed in NVIDIA#8213, and main's forward-pre-hook test. Adapted to main outside the conflicts: - megatron/rl/training_setup.py: main moved the RL inference-model build out of training.py. The training_pg_collection argument is re-applied as a keyword-only parameter of build_rl_inference_model. - PR tests for dataset providers, elastification, fallback warnings, the training loop and CUDA graphs follow main's moved providers, run_config fixtures, train() signature and graph reset API. 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/inference/advanced/gpt_dynamic_inference.py, examples/inference/advanced/gpt_static_inference.py, examples/inference/launch_inference_server.py, examples/inference/offline_inference.py, tools/run_dynamic_text_generation_server.py: main replaces build_tokenizer with get_tokenizer(). The result keeps the PR's get_registered_process_groups() model and engine builds and main's tokenizer changes. - tools/run_text_generation_server.py: main builds the model through get_model_builder(args, cfg.tokenizer, ...) with a pg_collection from use_mpu_process_groups(). The result keeps main's builder and takes the PR's registered groups and bound ModelOpt builder. - megatron/inference/utils.py: main adds a tokenizer_config argument to get_model_builder and switches to get_tokenizer(). The result keeps main's calls inside the PR's global_process_group_fallback block and the PR's pg_collection pass-through. - examples/t5/pretrain_t5.py: main drops build_tokenizer. The result keeps the PR's get_pg_rank import for the tp_group passed to get_batch. - megatron/training/training.py: main moves and rewrites _get_model_pg_collection. The PR's change is re-applied to main's version, so the fallback read runs inside global_process_group_fallback. - pretrain_gpt.py, pretrain_hybrid.py: main moves is_dataset_built_on_rank and core_gpt_dataset_config_from_args into shared helpers. The result takes the move and keeps the PR's get_batch fallback block. Adapted to main outside the conflicts: - megatron/training/datasets/providers.py: the PR's edit to is_dataset_built_on_rank is re-applied where main moved it, so the fallback read runs inside global_process_group_fallback. The unused warn_global_process_group_fallback import is removed. - tests/unit_tests/inference/test_inference_entry_point_groups.py: the PR's test stubs get_run_config() and get_tokenizer() and accepts the tokenizer_config argument, matching main's tokenizer refactor. - tests/unit_tests/test_example_process_groups.py: Main's BERT model provider reads the run config before the arguments (NVIDIA#8391). The provider test stubs get_run_config as well as get_args. 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>
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 #8768, which contains #8767, #8766, #8765, #8747, #8761, #8728, #8746, #8037, #8049 and #6293. Please review the diff from the merge of #8768: scoped diff.
_build_pg_collection_from_parallel_state(), and Read the bootstrap process groups from the registry #8768 gives it theowner=keyword and adds the_register_data_parallel_groupstest helper.tests/unit_tests/inference/test_inference_entry_point_groups.pyfrom Deprecate use_mpu_process_groups outside core and close its silent paths #8767. The embedder tests extendtests/unit_tests/tools/test_tool_process_groups.pyfrom Pass process groups explicitly in the standalone examples and tools #8746.This PR does not depend on #8772 or #8773 and can land any time after #8768.
Why.
finetune()intasks/finetune_utils.pyand theBertEmbedderoftools/bert_embedding/embed.pycalledsetup_model_and_optimizer()withoutpg_collection. Every run took its deprecated fallback: aProcessGroupFallbackWarning, and an error under--strict-process-group-fallbacks.get_model()calls the model provider withconfig=andpg_collection=. On main, the providers of the detoxification sampler, the multimodalrun_text_generation.pyandvision_model_tester.pytake neither, soget_model()would fail on them with aTypeError. Deprecate use_mpu_process_groups outside core and close its silent paths #8767 and Use the model's process groups in ModelOpt, multimodal and MIMO examples #8761 fix them, but no test can run them: the first two import the removedmegatron.inference.text_generation, and the third needs the GPU container.setup_model_and_optimizer()passes its groups.What.
finetune()andBertEmbedderbuild the collection thatpretrain()builds for a caller that passes none._build_pg_collection_from_parallel_state(args, owner="setup_model_and_optimizer")reads the groups thatinitialize_megatron()registered and, with--create-all-gather-group, adds the all-gather groups. Those are the groups the fallback built, so the model and optimizer run on the same groups as before.setup_model_and_optimizer(), whose fallback it is.megatron.training'sget_model()outside the tests, the guard finds the provider when the calling script defines it (a function, a nested function, a lambda or afunctools.partial()of one) or imports it from a module next to the script or at the repository root. It resolves names in the scope of the call and follows assignments. The provider must acceptconfig=andpg_collection=, by name or through**kwargs, and read the ones it names. The three scripts above must be among those checked. On main's versions, the check reports both keywords for each.setup_model_and_optimizer()outside the tests passespg_collection. Calls are matched under the names a script imports the function ormegatron.training.trainingas, by the same matcher asget_model()'s calls, so an aliased call is checked and a method of the same name on another class is not. On the tree it finds three calls:pretrain(), the finetuning driver and the BERT embedding tool.Tests.
test_parallel_state_deprecation.py:finetune()builds on the registered collection, and on an unregistered grid it warns once withsetup_model_and_optimizeras the owner.test_tool_process_groups.py: the same two cases forBertEmbedder. They need h5py, transformers and Transformer Engine, and skip otherwise.test_logger_ownership.pyis adapted to the new call.Before the 2026-11-01 sync, the branch ran these files and
test_inference_entry_point_groups.pyon 4 CPU ranks with Gloo: 155 passed, 6 skipped and 2 failed, the same per test as on the stacked version. There, 6 more tests passed than on its base. The 2 embedder tests skip. The 2 failures,test_core_metric_flags_keep_cli_defaults_and_owners[False|True], also failed on the stacked base without this PR.On 4 GPUs against its base:
test_inference_entry_point_groups.py: 18 passed here vs 14 on the base, 4 new tests pass.test_parallel_state_deprecation.py: 112 passed vs 110, 2 new tests pass.test_tool_process_groups.py: 2 passed and 3 skipped vs 2 passed and 1 skipped; the 2 extra skips are the new embedder tests.test_logger_ownership.py: 29 passed on both sides.inference/high_level_api/test_apis.py(29 passed) andtest_example_process_groups.py(11 passed) give the same results on both sides. No test regresses against the base. In the integration run, this PR's test files show no regressions against main. On the earlier stacked version,test_inference_entry_point_groups.pyalso passed under-W error::...ProcessGroupFallbackWarning, and so did the embedder test on the registered grid. Nothing runsfinetune()orBertEmbedderend to end, because no in-tree script calls either.Compatibility.
tasks/finetune_utils.pyandtools/bert_embedding/embed.pynow import the private training helper_build_pg_collection_from_parallel_statefrommegatron.training.training.setup_model_and_optimizer()"was called withoutpg_collection", as on main.finetune()andBertEmbeddertake that fallback on its behalf and have nopg_collectionargument of their own.vlm_dynamic_inference.pyandsimple_t5.OWN_PROVIDER_SCRIPTSis a hard-coded list. A provider that takes**kwargsis only checked to accept the keywords.test_inference_entry_point_groups.py, so a selective PR run skips these static checks. That is left for a follow-up.generate_samples_gpt.py,examples/multimodal/run_text_generation.py,tools/run_vlm_text_generation.pyandtasks/eval_utils.py;finetune()'s training loop, which callstrain_step()andtraining_log()with outdated arguments; andembed.py's top-levelpretrain_bertimport.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.The branch was synced with main 77391e7 on 2026-11-01 by a merge commit that merges the updated #8768 without conflicts, so existing commits and review links stay valid.
Part of #6307.
🤖 Generated with Claude Code