chore: nightly sync main into dev (13_08_2026) - #6522
Closed
svcnvidia-nemo-ci wants to merge 276 commits into
Closed
chore: nightly sync main into dev (13_08_2026)#6522svcnvidia-nemo-ci wants to merge 276 commits into
svcnvidia-nemo-ci wants to merge 276 commits into
Conversation
Signed-off-by: Philip Petrakian <ppetrakian@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
Signed-off-by: oliver könig <okoenig@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: oliver könig <okoenig@nvidia.com>
Signed-off-by: Siddharth Singh <sidsingh@nvidia.com>
Signed-off-by: Keshav Santhanam <ksanthanam@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
Signed-off-by: Markus Schnös <markus.schnoes@deepl.com> Co-authored-by: Markus Schnös <markus.schnoes@deepl.com>
…ky (#5848) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
…idden at checkpoint load time (#4705) Signed-off-by: John St John <jstjohn@nvidia.com> Signed-off-by: John St. John <jstjohn@nvidia.com>
…l" (#5324) Signed-off-by: Yury Parfenov <4665475+warpuv@users.noreply.github.com> Co-authored-by: Guihong Li <guihongl@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
…w pointer (#5639) Signed-off-by: Yan Bai <bayan@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com>
Signed-off-by: Gautham Kollu <gkollu@nvidia.com>
Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ckpointing (#5742) Signed-off-by: Deepak Narayanan <dnarayanan@nvidia.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…est (#5759) Signed-off-by: Rui Zhu <rui.zhu.rz399@yale.edu> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Dmytro Pykhtar <37850217+dimapihtar@users.noreply.github.com>
Signed-off-by: Philip Petrakian <ppetrakian@nvidia.com>
Signed-off-by: Lawrence McAfee <lmcafee@nvidia.com>
… failures (#5881) Signed-off-by: Ajay Balasa <abalasa@nvidia.com>
Signed-off-by: Evgenii Zheltonozhskii <zheltonozhskiy@gmail.com> Co-authored-by: Maanu Grover <maanug@nvidia.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Contributor
Author
|
/ok to test 579e0ea |
Contributor
Author
|
/ok to test e128caa |
1. Rename get_hybrid_data_context_parallel_groups to
get_dynamic_data_context_parallel_groups in training.py.
main's training.py imports and passes the hybrid_* spelling, but dev's
parallel_state.py defines the function as get_dynamic_* (dev renamed both
the function and the _DYNAMIC_DP_CP_GROUPS global). Taking main's version
of training.py per the nightly-sync override list therefore left a
dangling import, which the Installation Test caught:
ImportError: cannot import name
'get_hybrid_data_context_parallel_groups'
from 'megatron.core.parallel_state'
This is the function-level counterpart of the
args.hybrid_context_parallel -> args.dynamic_context_parallel rename the
skill already mandates for this file. Both call sites match dev's
pre-merge version verbatim.
2. Drop two declarations the merge duplicated.
The merge kept both dev's and main's copy of the same declaration:
PackedSeqParams.pad_between_seqs (packed_seq_params.py) and
HYBRIDEP_TOKEN_ALIGNMENT (fused_a2a.py). Each appeared once on dev and
once on main, twice in the merged tree; Sphinx reported both as
autodoc2.dup_item warnings.
For pad_between_seqs the duplicate was not inert: main's trailing
'pad_between_seqs: bool = None' shadowed dev's
'Optional[bool]' annotation, and the codebase relies on the tri-state
(transformer_engine.py:2264 tests 'is False', param_and_grad paths test
'is None'). Kept dev's annotation and dropped main's duplicate; the
dataclass still carries all 14 of dev's fields and all 13 of main's.
Signed-off-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
svcnvidia-nemo-ci
force-pushed
the
main2dev/13_08_2026
branch
from
August 13, 2026 21:22
e128caa to
6d20ae6
Compare
Contributor
Author
|
/ok to test 6d20ae6 |
Contributor
Author
|
Superseded by today's nightly sync. |
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.
Summary
Nightly sync of
mainintodev.main(merge-base48a887fec).Python lines: +69055 / -11351 across 474 filesorigin/dev(29 golden-value JSONs,uv.lock, recipe YAMLs, etc.).git merge origin/main --no-editfromorigin/dev. No global-X theirs; every conflict was resolved individually.Files where main's version was taken
Per the nightly-sync skill's "Files to Override from Main" list:
megatron/training/training.pymegatron/training/utils/common_utils.pyutils.pypath is now this module)megatron/training/datasets/data_samplers.pymegatron/core/optimizer/layer_wise_optimizer.pymegatron/training/initialize.pytraining.py— 4 intentional deviations from main1–2.
args.hybrid_context_parallel→args.dynamic_context_parallel(2 sites::2407,:3593).The skill requires this rename after taking main's version. It is a correctness fix, not cosmetic:
model_parallel_config.__post_init__(megatron/core/model_parallel_config.py:573-584) mapshybrid_context_parallel → dynamic_context_parallel = Truebut never the reverse, so main'sreference reads
Falsefor every user who passes--dynamic-context-parallel, silently skipping theHybridCPDataLoaderWrapperwrap and mis-settingis_hybrid_cp.3–4. Restored
_get_thd_sequence_length_upper_bound+ its call-site kwarg. This was a genuinemerge accident — details in the advisory-findings section below.
Files explicitly kept at dev's version
.github/CODEOWNERS,pyproject.toml,uv.lock,docker/Dockerfile.ci.dev— all four verifybyte-identical to
origin/dev. They appear in the remerge diff only because a conflict wasresolved back to dev's version.
uv.lockwas never hand-edited and needed no regeneration.Git source reconciliation:
mainhas two[tool.uv.sources]entries dev lacks (deep_gemm,mamba-ssm). Neither needs adding: every import of both istry/except ImportError-guarded(
batch_invariant_kernels.py:33,:1740;core/utils.py:398), andmamba-ssm~=2.2is already a devdependency from PyPI (
pyproject.toml:95,:119,:179). Three sources differ in revision(
emerging_optimizers,nemo-run,transformer-engine); dev is newer onemerging_optimizers, andthe skill mandates keeping dev's coupled triple, so dev's revisions were kept.
Files deleted in dev but restored
None restored — and that is the correct outcome. Comparing
origin/mainagainst the merged treesurfaced 3 candidates:
tests/test_utils/recipes/gpt-nemo.yaml40d30942d"fix: remove files that dev intentionally deleted" removes exactly these 3 files — a prior sync had restored them by mistaketests/functional_tests/test_cases/gpt/gpt3_nemo_te_tp1_pp1_1node_50steps/model_config.yamltests/functional_tests/test_cases/gpt/gpt3_nemo_te_tp1_pp1_1node_50steps/golden_values_dev_dgx_h100.jsonRestoring a recipe file is not inert:
recipe_parser.py:389discovers recipes viarecipes_dir.glob("**/*.yaml"), so putting one back silently re-adds whole functional-test suites tothe CI matrix.
Disposition of every pre-push advisory finding
The audit reported 6,486 potential dev-only line removals, plus no CODEOWNERS finding and
no dependency-triple finding.
That 6,486 count is not meaningful as stated:
blackreformatted 15 files andisortreorderedimports in 3, and the audit's predicate is
comm -23over sorted raw lines, so every rewrappedline reads as a missing dev line. I re-ran the identical predicate at two granularities that
reformatting cannot perturb:
Name/Attribute/keyword/arg/alias)def/class)Classifying all 140 by whether the name exists anywhere in the merged tree:
e.g. 13 schedule-node symbols from
models/gpt/fine_grained_callables.py→models/common/utils.pyand 4 →
models/common/fine_grained_callables.py(main'sffbe018c8); 12 pipeline symbols frommegatron/rl/agent/api.py→megatron/rl/agent/rollout_pipeline.py(main's87bf52075).after the merge-base. Representative:
c922805a4(Add support for non-Gym multi-turn environments #5312) rewrotetests/unit_tests/rl/test_rl_utils.py(554 lines changed) and renamedtest_get_grouped_rollouts.py→test_rollout_generation.py, dropping 11 dev test names.c922805a4is an ancestor ofmainbut not ofdev, and dev never touched those tests afterthe merge-base — dev's copies were simply the older pre-rewrite versions. Others:
87bf52075(RL: unify rollout generation into one pipeline #6495),
541d5eef0,f41ec5495,bcf4c8fb5(inference async-sched/coordinator),59b72fa57,d981f66be,714c24a7e,d207685b4(MFSDP v2),648bc011f,4464d1c19,2a75ac12c.In every case the merged file is byte-identical to main's and main's version is the larger,
newer one (
test_rl_utils.py1183 → 1393 lines;test_fully_shard.py593 → 1083), i.e. main isahead on those paths.
_dsv4_hybrid_self_attention_flops,mla_attn_layer_flops,finalize_model_grads_with_state_reloadare internal to dev'straining.py(definition +callers all inside the file), which is on the override list. Confirmed no dangling external
caller: the only surviving mentions of the first two are inside docstrings of
tests/unit_tests/test_num_floating_point_operations.py(:292,:300,:1019) with noexecutable reference, and that test imports only
num_floating_point_operations,update_seqlen_stats_from_cu_seqlens,consume_seqlen_stats_in_iteration— all present.finalize_model_grads_with_state_reloadhas zero references tree-wide.DelayedRelease,Headers,DecodeForwardPrimer,TransformerLayerState,_RolloutPipelineare classes infiles where main's version won, with no surviving callers.
The one real merge accident:
_get_thd_sequence_length_upper_boundExactly the pattern the skill warns about — main's caller version dropped a dev-only feature whose
callee still supports it.
TECudaGraphHelper(..., thd_sequence_length_upper_bound=_get_thd_sequence_length_upper_bound(args)).megatron/core/transformer/cuda_graphs.py:2150(
thd_sequence_length_upper_bound=None), stored at:2166, consumed at:2679-2682.Impact if left dropped — two distinct failures:
tests/unit_tests/training/test_train_step_schedule_plumbing.py:347assertstraining_mod._get_thd_sequence_length_upper_bound(args) == 1024. The merged tree keeps dev'scopy of that file (347 lines; main's is 69 and never references the helper), so it would raise
AttributeError. This is sync-caused, not pre-existing — the test passes ondev.cuda_graphs.py:2679falls back toself.seq_length, undersizing THD CUDA graphs. Per the comment there,seq_lengthis wrong underCP because
max_seqlen_per_dp_cp_rankis only the per-rank token budget, not the max length of onesample before packing.
Fixed by restoring dev's 35-line helper verbatim (
mathalready imported) and re-adding the kwarg.I then wrote an AST checker for every from-import and module-alias attribute reference against all
override-list modules plus
data_schedule.py: 0 unresolved.Golden-value JSONs: a new CI gate arriving from main
tools/check_golden_values.pyand its workflow step do not exist ondevat all — both arrivevia main's
bb5647a9b(#5989), inside the non-exemptlintingjob. Because the step only validatesgolden files that differ from the base branch, this sync is what causes 9 dev files to be checked
for the first time. That makes the failure sync-caused, not pre-existing.
All 9 failed on non-finite
iteration-timevalues. Thosenans are placeholders for unlogged steps,not data:
model_config.yamlsets--log-interval: 2, so odd steps are never logged and step 1 hasno preceding step to time. The fix drops the
nan-valued steps and re-derives the header(
start_step/end_step/step_interval), asserting the surviving keys form a single arithmeticrun. Net diff: 5 insertions / 38 deletions.
This strengthens the test rather than loosening it.
common.py:239-260comparesiteration-timeby median over a steady window, mapping any non-numeric to
np.inf; withnans in-window the goldenmedian was itself
inf, so the assertion degenerated toinf == inf— a vacuous pass. Removing themmakes the comparison real over finite medians.
python3 tools/check_golden_values.pynow reports"Checked 27 golden-value file(s); all values are finite."
Verification performed locally
Reproduced CI's exact lint gate (
tools/autoformat.shwithCHECK_ONLY=true, which selectsmegatron/core+tests/— 415 files) using CI's pinned versions (black==24.4.2,isort==5.13.2,pylint==3.2.6,ruff~=0.9.0):black --skip-magic-trailing-comma --skip-string-normalization --checkisort --checkpylintpylintexits 4 on warnings andautoformat.shruns underset -e, so these would have failed the job)ruff check --no-fixtools/check_golden_values.pyNote on
pylint:param_and_grad_buffer.py'scopy_tensor_to_quantized_paramimport was correctlydropped — main's
8e57bb642(#6094) deliberately replaced the per-param call with the batchedcopy_tensors_to_quantized_params.fine_grained_callables.py'sPreProcessNode/PostProcessNodewere kept (suppressed instead) because they are load-bearing re-exports:
tests/unit_tests/pipeline_parallel/test_pp_mhc_compatibility.py:27imports them from that path.API mismatch audit
Ran an AST caller/callee signature audit over all 471 changed Python files (35 findings), then the
identical audit against pristine
origin/dev(31), leaving 5 merged-only candidates. All 5reproduce on pristine
origin/mainat byte-identical call sites, so they are inherited from main,not created by the merge. Two were checked further:
moe/router.py:964is a resolver false positive — the real callee istopk_routing_with_score_function(moe_utils.py:777), whose signature accepts all 10 "rejected"kwargs; my resolver had matched the unrelated
Router.routingmethods by bare name.models/common/utils.pyis main-only yet differs from main in the merged tree because gitrename-matched it to dev's
model_chunk_schedule_plan.pyand preserved dev's mHC hooks(
preprocess_for_layer_schedule/postprocess_for_layer_schedule) plus dev'sdeepepv2backendtuple — the desired combine-both-sides outcome.
The one real mismatch this audit caught was self-inflicted: an earlier import consolidation had
moved
get_batch_on_this_tp_rankinpretrain_gpt.pyinto themegatron.core.utilsblock, assumingboth paths re-export one object. They don't — two distinct same-named functions exist with
incompatible signatures (
megatron/core/utils.py:2177takes 12+ positional params;megatron/training/utils/common_utils.py:580takes(data_iterator, mtp_on_this_rank=False, needs_padding_mask=False)). The call site atpretrain_gpt.py:171uses the training one; the importwas moved back. (
get_batch_on_this_cp_rankis a genuine re-export, so its differing path is safe.)Conflict resolutions (
--remerge-diff)git 2.54.0 is installed, so
--remerge-diffworks.git show --remerge-diff 579e0eac7produces 18,309 lines across 102 files — far past GitHub's PR-body limit, so the
per-file conflict census is below and reviewers can reproduce the full diff with:
git fetch origin main2dev/13_08_2026 && git show --remerge-diff 579e0eac7Conflict resolutions by file — 40 files with the most remerge hunks (of 102)
uv.lockmegatron/training/training.pymegatron/training/checkpointing.pymegatron/core/ssm/gated_delta_net/common.pymegatron/rl/rl_utils.pytests/unit_tests/ssm/test_gated_delta_net.pymegatron/training/arguments.pymegatron/core/transformer/transformer_config.pymegatron/core/inference/engines/dynamic_engine.pymegatron/training/models/dist_utils.pymegatron/core/inference/contexts/dynamic_context.pytests/functional_tests/test_cases/moe/gpt3_mcore_te_tp2_pp1_te_8experts2parallel_ddp_average_in_collective_1node/golden_values_dev_dgx_gb200.jsontests/functional_tests/test_cases/moe/gpt3_mcore_te_tp2_pp1_te_8experts2parallel_overlap_grad_reduce_param_gather_groupedGEMM_1node/golden_values_dev_dgx_gb200.jsontests/unit_tests/dist_checkpointing/test_optimizer.pymegatron/core/distributed/param_and_grad_buffer.pymegatron/core/transformer/moe/experts.pytests/functional_tests/test_cases/moe/gpt3_moe_mcore_te_tp4_ep2_etp2_pp2_resume_torch_dist_dist_optimizer_1node/golden_values_dev_dgx_gb200.jsontests/unit_tests/fusions/test_swiglu_fusion.pytests/unit_tests/ssm/test_hybrid_layer_allocation.pytests/unit_tests/transformer/moe/test_grouped_mlp.pymegatron/core/models/hybrid/hybrid_block.pymegatron/core/optimizer/optimizer.pymegatron/core/transformer/transformer_layer.pymegatron/training/argument_utils.pypyproject.tomltests/unit_tests/transformer/moe/test_token_dispatcher.pymegatron/core/fusions/fused_bias_swiglu.pymegatron/core/models/common/model_chunk_schedule_plan.pymegatron/core/transformer/multi_token_prediction.pytests/functional_tests/test_cases/moe/gpt3_moe_mcore_te_tp4_ep2_etp2_pp2_scoped_cudagraph/golden_values_dev_dgx_h100.jsontests/unit_tests/transformer/moe/test_shared_experts.pymegatron/core/fp8_utils.pymegatron/core/models/common/utils.pymegatron/core/transformer/moe/token_dispatcher.pytests/unit_tests/inference/contexts/test_dynamic_prefix_caching.pytests/unit_tests/transformer/test_full_cuda_graph.pydocker/Dockerfile.ci.devmegatron/core/models/gpt/fine_grained_callables.pymegatron/core/models/hybrid/hybrid_layer_allocation.pymegatron/core/ssm/gated_delta_net/gdn2.pyFull remerge diff is 18,309 lines across 102 files; the 40 files with the most conflict hunks are listed above.
uv.lock(122) anddocker/Dockerfile.ci.dev(4) appear here only because their conflictswere resolved back to dev's version; both verify byte-identical to
origin/dev.training.py(112) is the largest code entry, as expected for an override-list file.Phase 3: CI fixes
get_hybrid_data_context_parallel_groups→get_dynamic_data_context_parallel_groupsThe
Installation Test / Pip - Python3.12job failed with:This is the function-level counterpart of the
args.hybrid_context_parallelrename the skillalready mandates for
training.py. Dev renamed both the accessor and its backing global(
_HYBRID_DP_CP_GROUPS→_DYNAMIC_DP_CP_GROUPS); main kept thehybrid_*spelling. Taking main'straining.pyper the override list therefore left a dangling import.Fixed at both sites, matching dev's pre-merge version verbatim (
origin/dev:training.py:95and:2720): the import at:99and thehybrid_cp_group_func=argument at:2445. Alphabetical importorder is preserved, so
isortstays clean.Worth noting how this surfaced: the failure is in
megatron.training.__init__→training.py, whichtests/unit_tests/conftest.pyalso imports — so this single dangling name would have cascaded intoevery unit-test suite, not just the install check.
I then wrote a static resolver for the whole class of bug (AST, no torch needed, since the
Installation Test imports every module under
megatron.*):from megatron.core.parallel_state import Xacross 1,601 files, plusmpu.X/parallel_state.Xattribute reads, resolved against the 167 namesparallel_state.pyactuallydefines → 0 missing after the fix.
from megatron/tests/tools... import Xresolved against its target module'stop-level namespace (following re-exports) → 4 findings, all static-analysis false positives,
identical on
origin/devandorigin/main:bert_layer_with_transformer_engine_specis served by amodule-level
__getattr__deprecation shim (bert_layer_specs.py:95), andtools/bert_embedding/external_libs.pypopulatesh5py/transformersviaglobals()[lib] = importlib.import_module(lib).Two declarations the merge duplicated
build-docs(exempt from the ship gate, but a real merge artifact) reported twoautodoc2.dup_itemwarnings, and Sphinx runs with warnings-as-errors:Both are the merge keeping dev's and main's copy of the same declaration — one occurrence on each
parent, two in the merged tree.
HYBRIDEP_TOKEN_ALIGNMENTwas a harmless duplicate (identical value and comment).pad_between_seqswas not inert: main's trailing
pad_between_seqs: bool = Nonecame after dev'spad_between_seqs: Optional[bool] = None, so main's annotation won. The tri-state matters — thecodebase distinguishes
None(infer) fromFalse(explicitly no padding) fromTrue:extensions/transformer_engine.py:2264testspacked_seq_kwargs.get("pad_between_seqs") is False,transformer_layer.py:580-581testsis Trueandis None, andtest_thd_cuda_graph.pyassertsis False/is Trueat 10 sites.Kept dev's
Optional[bool]and dropped main's duplicate. Verified the dataclass still carries all 14of dev's fields and all 13 of main's — nothing lost, only the duplicate removed.
To confirm this was the whole extent of the pattern, I wrote a duplicate-declaration audit (AST;
module- and class-level
def/class/Assign/AnnAssign) that reports a name only when itsoccurrence count in the merged tree exceeds both parents' — so pre-existing duplicates don't
create noise. Across all 474 changed Python files: exactly these 2, now 0.
Re-verification after the Phase 3 fixes
Replayed CI's real gate —
tools/autoformat.sh's own file selection(
git diff --diff-filter=d --merge-base origin/main megatron/core tests/, 222 files) with CI's argv:black --skip-magic-trailing-comma --skip-string-normalization --checkisort --check-onlypylint(.pylintrc:disable=all+ C0115/C0116/W0611/C0301/E0606/W0141)ruff check --no-fixtools/check_golden_values.pyparallel_statename resolutionDCO
The DCO check reports
failure, but its own summary says the verdict is unknown rather thannegative:
This is a pagination limit, not a missing sign-off: the PR carries 275 commits. I re-requested the
check 4 times (identical result each time) and have now pushed a new commit, which is the other remedy
the app suggests. The Phase 3 fix commit carries a
Signed-off-bytrailer.For the record, the sign-off state of the commit list itself: 19 of the 274 commits inherited from
mainlack aSigned-off-bytrailer (e.g.15c83d2fc"chore: rotate oncall schedule", theUpdate copy-pr-bot.yaml [skip ci]commits,648bc011f,411a5d8b2). Those are already onmainand are not something a sync PR can alter. Prior sync PRs show the app tolerates this: #5314 passed
DCO while carrying unsigned commits from 15 different authors and two unsigned merge commits — so
merge commits and NVIDIA-member commits are not what it objects to.
-S(GPG) signing is unavailable on this runner (gpg: signing failed: No secret key), so the fixcommit is signed off with
-sonly — which is what DCO verifies.