Repository navigation
[Dev] feat(multimodal): migrate Qwen3.5-VL to HybridModel - #6315
Conversation
The GPTModel code path is being deprecated, so move the examples/multimodal_dev
Qwen3.5-VL language decoder from GPTModel to HybridModel.
- MultimodalModel / Qwen35VLModel now take a hybrid stack spec plus a unified
--hybrid-layer-pattern instead of a transformer layer spec and an MTP block
spec. Each historical Qwen block becomes two hybrid layers: a GatedDeltaNet
('G') or full-attention ('*') layer followed by a dense ('-') or MoE ('E')
MLP layer, reproducing the --linear-attention-freq 4 cadence of the GPT path.
MTP depths replicate the last block, as get_gpt_mtp_block_spec derived the
MTP spec from the final decoder layer.
- Add mrope support to HybridModel, mirroring GPTModel: build a
MultimodalRotaryEmbedding when position_embedding_type is 'mrope', and
compute the sectioned (optionally raw, fused-kernel) freqs in forward.
Widen the HybridModelConfig position_embedding_type literal accordingly.
- Because HybridModel counts one layer per pattern symbol, the Qwen variant
configs are converted from block counts to hybrid layer counts.
- Import fla.ops.cp.build_cp_context separately from the rest of FLA so that a
build without the CP extension still enables GatedDeltaNet, and raise a
descriptive error only when chunkwise CP is actually requested.
- run_qwen35_vl.sh derives the pattern from NUM_LAYERS, NUM_EXPERTS and the new
MTP_NUM_LAYERS knob, and only passes the MTP arguments when MTP is enabled.
The decoder checkpoint layout changes with this migration; see the README for
details on why existing GPTModel-format Qwen3.5-VL checkpoints are not directly
loadable.
Signed-off-by: Li Tao <lit@nvidia.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
While reviewing this migration, I noticed that the configured position embedding type does not match the model that is actually constructed.
This cannot be fixed by changing the recipe to |
Three places where the launcher and the constructed model disagreed.
1. Position embeddings. The recipe declared --position-embedding-type rope
while Qwen35VLModel constructed the decoder with "mrope". The forward pass
was unaffected -- mRoPE dispatch keys off config.mrope_section and the
frequency shape, not position_embedding_type -- but the parsed args and the
checkpoint metadata described a plain-RoPE decoder, so checkpoint
converters, exporters and generic model builders would reconstruct the
wrong architecture.
Declaring mrope was rejected before this change: validate_args carried two
MTP position-embedding checks, and the earlier one accepted only rope and
none, so it fired before the authoritative check further down (which
already lists mrope) ever ran. Drop the narrower duplicate.
The recipe now passes --position-embedding-type mrope --mrope-section
11 11 10 (--mrope-section is generated from the TransformerConfig field),
post_language_config no longer overrides mrope_section behind the CLI's
back, and Qwen35VLModel takes the type from the parsed args and rejects
anything but mrope.
2. --linear-attention-freq 4 is no longer passed. TransformerConfig skips its
assertion for hybrid models, and its only consumers are the GPTModel spec
builder, TransformerBlock and the non-hybrid FLOPs branch -- none of which
the HybridModel path reaches. It was a second, unenforced source of truth
for a layout that --hybrid-layer-pattern already owns.
--experimental-attention-variant gated_delta_net stays: that is what drives
the GDN dimension validation.
3. The decoder attention layout is now declared per variant as ATTN_CADENCE,
one period of the layout with one symbol per Qwen block ("GGG*"), instead
of being implied by a `block_idx % 4` branch. The cadence repeats and is
truncated to NUM_LAYERS, so the architecture is readable at the point where
every other per-variant dimension is set, and a variant that ever deviates
changes one string. Generated patterns are unchanged for all ten variants
at every MTP depth, and NUM_LAYERS / NUM_EXPERTS / MTP_NUM_LAYERS keep
working as proxy overrides.
Signed-off-by: Li Tao <lit@nvidia.com>
Conflict: dev split megatron/core/ssm/gated_delta_net.py into a package (common.py / gdn.py / kda.py) and, in doing so, put the fla.ops.cp import back inside the HAVE_FLA try block. Reapply this branch's FLA change on top of the new layout: fla.ops.cp is imported separately so an FLA build without the CP extension no longer disables GatedDeltaNet entirely, and both chunkwise-CP entry points (GDN and the new KDA) raise an actionable ImportError instead of calling None. Signed-off-by: Li Tao <lit@nvidia.com>
| cp_group=self.pg_collection.cp, | ||
| ) | ||
| elif self.position_embedding_type == 'mrope' and not self.config.multi_latent_attention: | ||
| self.rotary_pos_emb = MultimodalRotaryEmbedding( |
There was a problem hiding this comment.
Should we pass cp_group to mrope like other PEs?
There was a problem hiding this comment.
Good catch. This was a bug and have fixed and is covered by new tests.
| @@ -302,8 +313,9 @@ def get_qwen35_vl_language_config( | |||
| v = _VARIANT_CONFIGS[variant] | |||
|
|
|||
| kwargs = dict( | |||
There was a problem hiding this comment.
I think is_hybrid_model also need to be set.
There was a problem hiding this comment.
Agreed and have set this, and also deleted linear_attention_freq to match the logic.
|
/claude strict-review |
| self.rotary_pos_emb = MultimodalRotaryEmbedding( | ||
| kv_channels=self.config.kv_channels, | ||
| rotary_percent=rotary_percent, | ||
| rotary_interleaved=self.config.rotary_interleaved, | ||
| seq_len_interpolation_factor=seq_len_interpolation_factor, | ||
| rotary_base=rotary_base, | ||
| interleaved_mrope=self.config.mrope_interleaved, | ||
| ) |
There was a problem hiding this comment.
[CRITICAL Correctness]
What: MultimodalRotaryEmbedding is constructed without cp_group, unlike the two sibling branches immediately above — the rope branch (RotaryEmbedding(..., cp_group=self.pg_collection.cp)) and the yarn branch (YarnRotaryEmbedding(..., cp_group=self.pg_collection.cp)) both pass it. MultimodalRotaryEmbedding.__init__ therefore takes its fallback:
self.cp_group = (
cp_group
if cp_group is not None
else parallel_state.get_context_parallel_group(check_initialized=False)
)Why it matters: two separate problems.
-
Correctness under a custom
pg_collection.HybridModelacceptspg_collectionprecisely so a caller can supply process groups that are not theparallel_stateglobals. Here the CP group is silently taken from the global MPU state instead.MultimodalRotaryEmbedding.forwardusesself.cp_groupforget_pos_emb_on_this_cp_rank(...)whenever the per-callcp_groupisNone— and this model'sforwardpassescp_group=packed_seq_params.cp_group if packed_seq_params is not None else None, so the non-packed path (the common BSHD training path) always relies onself.cp_group. If the injectedpg_collection.cpdiffers from the global CP group, the mRoPE frequencies get zigzag-sliced for the wrong rank — silently wrong positions, not a crash.check_initialized=Falsealso means an uninitialized MPU yieldsNone, which turns CP slicing off entirely rather than erroring. -
Repo guidance. Per
CLAUDE.md, newmegatron/coreproduction code should not introduce reads of globalparallel_stateprocess groups; it should thread the group through from the caller. This branch introduces one indirectly, and the correct group is already available two lines away asself.pg_collection.cp.
Note this is not theoretical for this PR: examples/multimodal_dev/models/base.py::_thd_mrope_no_cp_override mutates self.language_model.rotary_pos_emb.cp_group at runtime, so whatever this attribute is initialized to is load-bearing on the very path the PR is enabling.
(The GPT copy this was ported from has the same omission, but that is a pre-existing bug in a different file — copying it into hybrid_model.py, where the adjacent branches already do the right thing, makes the inconsistency worse.)
Fix: pass the group explicitly.
| self.rotary_pos_emb = MultimodalRotaryEmbedding( | |
| kv_channels=self.config.kv_channels, | |
| rotary_percent=rotary_percent, | |
| rotary_interleaved=self.config.rotary_interleaved, | |
| seq_len_interpolation_factor=seq_len_interpolation_factor, | |
| rotary_base=rotary_base, | |
| interleaved_mrope=self.config.mrope_interleaved, | |
| ) | |
| self.rotary_pos_emb = MultimodalRotaryEmbedding( | |
| kv_channels=self.config.kv_channels, | |
| rotary_percent=rotary_percent, | |
| rotary_interleaved=self.config.rotary_interleaved, | |
| seq_len_interpolation_factor=seq_len_interpolation_factor, | |
| rotary_base=rotary_base, | |
| interleaved_mrope=self.config.mrope_interleaved, | |
| cp_group=self.pg_collection.cp, | |
| ) |
| # NOTE: the MTP position-embedding-type check lives with the other MTP | ||
| # validation further down (search for `supported_position_types`). Keeping a | ||
| # second, narrower copy here caused 'mrope' to be rejected before the | ||
| # authoritative check ever ran. |
There was a problem hiding this comment.
[IMPORTANT Compatibility]
What: deleting the early assertion does more than un-block mrope. The removed check allowed only {rope, none}; the authoritative downstream check (line 2141) allows {learned_absolute, rope, mrope, none}. So this diff simultaneously legalizes two previously-rejected combinations:
--mtp-num-layers N --position-embedding-type mrope— intended, and the point of the PR.--mtp-num-layers N --position-embedding-type learned_absolute— a silent side effect nowhere mentioned in the PR description or the new comment.
Why it matters: learned_absolute + MTP was hard-rejected on every prior release of this file, so no user has ever run it and it has no functional-test coverage. MTP rolls the sequence forward per prediction depth (prepare_mtp_sequence_roll_context); with RoPE that is a pure position_ids shift, but with learned_absolute the position embedding is added inside LanguageModelEmbedding from the unshifted embedding-side positions, so whether the MTP depth-k branch sees correctly-offset absolute positions is an untested question. Turning it from "asserts immediately" into "trains and produces a number" converts a loud failure into a possible silent one. It is also strictly outside the PR's stated scope ("make the Qwen3.5-VL recipe describe the model it builds").
Fix: keep the scope of this PR to mrope. Either narrow the downstream list to the union that is actually intended/tested, or gate it explicitly. Concretely, at line 2141:
if args.mtp_num_layers:
# MTP is compatible with position embedding types that use position_ids.
# 'learned_absolute' is excluded: MTP's sequence roll shifts position_ids,
# but learned_absolute adds embeddings from the unshifted embedding-side
# positions, and that combination has no test coverage.
supported_position_types = ["rope", "mrope", "none"]
assert args.position_embedding_type in supported_position_types, (...)If learned_absolute + MTP is meant to be enabled here, say so in the commit message and add a test — but that belongs in its own PR.
| hybrid_layer_pattern = getattr(args, "hybrid_layer_pattern", None) | ||
| if hybrid_layer_pattern is None: | ||
| raise ValueError( | ||
| "Qwen3.5-VL uses HybridModel and requires --hybrid-layer-pattern. " | ||
| "Use GEGEGE*E per four MoE blocks (or G-G-G-*- for dense blocks), " | ||
| "and append /*E or /*- for each MTP depth." | ||
| ) |
There was a problem hiding this comment.
[IMPORTANT Correctness]
What: the PR hard-enforces one recipe/model invariant but leaves the neighbouring one on the honour system. --position-embedding-type now raises here (and again in Qwen35VLModel.__init__) if it disagrees with the model, but --mrope-section — which the PR newly makes mandatory on the CLI — is only documented as needing to match:
run_qwen35_vl.sh:374— "--mrope-sectionmust matchMROPE_SECTIONin ..."README.md:61— "also matchMROPE_SECTIONinmodels/qwen35_vl/configuration.py."
and post_language_config deliberately declines to set it ("overriding it would let the recipe and the constructed model disagree"). Nothing checks it. The only assertion in the stack is validate_args:1702, which merely requires it to be non-None.
Why it matters: MROPE_SECTION = [11, 11, 10] is tied to ROTARY_PERCENT = 0.25 and kv_channels: sum(MROPE_SECTION) must equal int(kv_channels * ROTARY_PERCENT) // 2. The new test_mrope_section_matches_rotary_dimension asserts exactly that — for the constant, not for the CLI value that actually reaches the model. A user who writes --mrope-section 12 10 10 (right sum, wrong split) gets a model that trains to a plausible-looking loss with the T/H/W channel boundaries in the wrong place — a silent accuracy bug, not a crash. A wrong sum is worse still: _apply_interleaved_mrope indexes freqs[..., slice(offset, mrope_section[dim_idx] * 3, 3)], which silently under- or over-fills channels rather than raising.
This is exactly the class of recipe/model disagreement the PR was written to eliminate, so leaving it unenforced is inconsistent with the change's own stated goal.
Fix: validate it next to the pattern check, mirroring the hybrid_layer_pattern guard:
from examples.multimodal_dev.models.qwen35_vl.configuration import MROPE_SECTION, VISION_KWARGS
...
if list(language_config.mrope_section or []) != list(MROPE_SECTION):
raise ValueError(
f"Qwen3.5-VL requires --mrope-section {' '.join(map(str, MROPE_SECTION))}, "
f"but got {language_config.mrope_section}. The section split is tied to "
f"kv_channels and ROTARY_PERCENT; a mismatch silently misplaces the "
f"T/H/W channel boundaries."
)That turns a documented convention into a checked one, and lets the docs stop carrying the burden.
| # Architecture. HybridModel counts one layer per pattern symbol, so each | ||
| # Qwen block ('G'/'*' plus '-'/'E') contributes two layers. | ||
| num_layers=2 * v["num_layers"], |
There was a problem hiding this comment.
[SUGGESTION Simplification]
What: now that num_layers is the hybrid layer count, the linear_attention_freq=4 still sitting in this same dict (line 343) is both dead and internally inconsistent with it. Under the HybridModel path that field is never consumed:
TransformerBlock'sget_linear_attention_patternconsumer is not reached —HybridModelbuilds aHybridStackfromhybrid_layer_pattern.transformer_config.py:1768explicitly skips thelinear_attention_freq is not Noneassertion whenis_hybrid_model.- The FLOPs path takes the hybrid branch (
training.py:1281, viaget_hybrid_layer_counts), not thelinear_attention_freqbranch.
So the value is inert — but a reader who trusts it computes the wrong layout, because interpreted against the now-doubled num_layers it reads as "every 4th layer", i.e. half the intended full-attention count.
Why it matters: the point of this PR is that the config should describe the model that gets built. Leaving a stale sibling field next to the one whose units you just changed re-creates, inside a single dict, the recipe/model disagreement the PR removes elsewhere. The next person adding a variant has no way to tell which of the two fields is authoritative.
Fix: drop it and note where the layout now comes from:
# Hybrid attention (GatedDeltaNet). The GDN/full-attention layout comes
# from --hybrid-layer-pattern, not linear_attention_freq: HybridModel
# builds its stack from the pattern and never reads that field.
experimental_attention_variant="gated_delta_net",
linear_conv_kernel_dim=4,If it has to stay for a non-hybrid consumer, keep it but comment that it is ignored on the hybrid path and is in block units while num_layers here is in layer units.
| ATTN_LAYER_SYMBOL="${ATTN_CADENCE:0:1}" | ||
| HYBRID_LAYER_PATTERN="" | ||
| for ((block_idx = 0; block_idx < NUM_LAYERS; block_idx++)); do | ||
| ATTN_LAYER_SYMBOL="${ATTN_CADENCE:block_idx % ${#ATTN_CADENCE}:1}" | ||
| HYBRID_LAYER_PATTERN+="${ATTN_LAYER_SYMBOL}${MLP_LAYER_SYMBOL}" | ||
| done | ||
| for ((mtp_depth = 0; mtp_depth < MTP_NUM_LAYERS; mtp_depth++)); do | ||
| HYBRID_LAYER_PATTERN+="/${ATTN_LAYER_SYMBOL}${MLP_LAYER_SYMBOL}" | ||
| done |
There was a problem hiding this comment.
[SUGGESTION Simplification]
What: two small clarity issues in the expansion loop.
-
ATTN_LAYER_SYMBOL="${ATTN_CADENCE:0:1}"at line 468 is dead in every real configuration — the loop unconditionally reassigns it on its first iteration. It only survives whenNUM_LAYERS=0, in which case the MTP loop would emit MTP blocks for a zero-layer decoder anyway. -
The MTP loop consumes
ATTN_LAYER_SYMBOLas leaked from the decoder loop's last iteration. That happens to be correct — GPT'sget_gpt_mtp_block_specdoescopy.copy(spec.layer_specs[-1]), so MTP replicating the final block is the right parity — but the code expresses it as an implicit side effect of loop-variable scoping rather than as the intent. If someone later reorders the loops, adds a trailing symbol, or wraps the decoder loop in a conditional, the MTP symbol changes silently and the pattern still parses.
Why it matters: the pattern string is the sole source of truth for the built architecture now that --num-layers and --linear-attention-freq are gone. A silently-wrong MTP symbol produces a model that trains fine but has a GDN MTP head where a full-attention one was intended — no error, just a different architecture from the one the comment above claims.
Fix: drop the dead pre-assignment and name the invariant explicitly.
HYBRID_LAYER_PATTERN=""
for ((block_idx = 0; block_idx < NUM_LAYERS; block_idx++)); do
ATTN_LAYER_SYMBOL="${ATTN_CADENCE:block_idx % ${#ATTN_CADENCE}:1}"
HYBRID_LAYER_PATTERN+="${ATTN_LAYER_SYMBOL}${MLP_LAYER_SYMBOL}"
done
# Each MTP depth replicates the final decoder block, matching the GPT path's
# copy.copy(spec.layer_specs[-1]).
LAST_BLOCK_ATTN_SYMBOL="${ATTN_CADENCE:(NUM_LAYERS - 1) % ${#ATTN_CADENCE}:1}"
for ((mtp_depth = 0; mtp_depth < MTP_NUM_LAYERS; mtp_depth++)); do
HYBRID_LAYER_PATTERN+="/${LAST_BLOCK_ATTN_SYMBOL}${MLP_LAYER_SYMBOL}"
donePass the injected CP group to MultimodalRotaryEmbedding. The mrope branch in HybridModel was the only rotary branch not forwarding pg_collection.cp, so it fell back to the parallel_state global. HybridModel.forward passes cp_group=None on the unpacked path, which makes the stored group the one that slices the frequencies, and examples/multimodal_dev overrides that attribute at runtime. Validate the effective mrope_section in the Qwen3.5-VL factory. The T/H/W split is tied to kv_channels and ROTARY_PERCENT, so a section with the right total width but the wrong partition silently misplaces the channel boundaries. The recipe value stays authoritative; the model-specific factory now checks it. Declare is_hybrid_model on the Qwen3.5-VL language config and drop the now-dead linear_attention_freq. num_layers counts hybrid layers, so without the flag the output-layer init std would be scaled by the doubled count; the GDN layout comes from --hybrid-layer-pattern and that field is never read on the hybrid path. Keep learned_absolute out of the MTP position-embedding allow-list. The duplicate early assertion this branch removed rejected it on every prior release, and MTP's sequence roll shifts position_ids while learned_absolute adds embeddings from the unshifted embedding-side positions. Also reuse the cached inference-mode flag in the mrope forward branch, and derive the MTP layer symbol in run_qwen35_vl.sh explicitly instead of relying on a leaked loop variable. Signed-off-by: Li Tao <lit@nvidia.com>
Signed-off-by: Li Tao <lit@nvidia.com> # Conflicts: # examples/multimodal_dev/tests/test_mrope_parity.py
tools/autoformat.sh runs black with --skip-magic-trailing-comma, which collapses the MultimodalRotaryEmbedding construction in test_mrope_stored_cp_group_drives_unpacked_slicing onto one line at the configured 100-column width. No behavioral change. Signed-off-by: Li Tao <lit@nvidia.com>
FDecaYed
left a comment
There was a problem hiding this comment.
Re-reviewed the current head e992794. The CP-group injection and architecture-specific mrope_section validation are correctly implemented with focused coverage, and the exact-head required CI checks pass. The failing codecov/patch status is advisory rather than a required dev check; its misses are concentrated in optional fused/inference and missing-extension defensive branches, so I do not consider it a merge blocker.
* Short-circuit condition to avoid copying from GPU memory in `ChainedOptimizer` (NVIDIA#5623) Signed-off-by: Hristo Filaretov <hfilaretov@nvidia.com> Co-authored-by: Michał Marcinkiewicz <43240942+mmarcinkiewicz@users.noreply.github.com> * Increase Megatron-FSDP overlap test dim to 8192 for reliable overlap (NVIDIA#5770) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Inference: Add profile endpoints to chat completions. (NVIDIA#5611) Signed-off-by: Siddharth Singh <sidsingh@nvidia.com> * Inference: Do not route pad/dummy tokens to any expert (NVIDIA#4922) Signed-off-by: Siddharth Singh <sidsingh@nvidia.com> * Inference: Add load aware routing to prefix caching. (NVIDIA#5607) Signed-off-by: Siddharth Singh <sidsingh@nvidia.com> * fix(clip_grads): handle empty grads_for_norm in inf-norm and p-norm paths (NVIDIA#5530) Signed-off-by: Min Htet Myet <mattralminn@email.com> Signed-off-by: Mattral <mattralminn@gmail.com> * test(gpt): AUT-830 mark tp1_pp4_vp1_resume_torch_decoupled_lr flaky on h100 (NVIDIA#5801) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * Delegate reasoning token retention to the chat template in multi-turn conversations (NVIDIA#5276) * Various ModelOpt fixes: QAD test for CICD, use model builder config instead of model provider, allow loading teacher ckpt independently of student (NVIDIA#4520) Signed-off-by: Asha Anoosheh <aanoosheh@nvidia.com> * build: Update Transformer Engine to 2.17 (NVIDIA#5680) Signed-off-by: Ajay <abalasa@nvidia.com> Signed-off-by: Ajay Balasa <abalasa@nvidia.com> Signed-off-by: [Your Name] <your.email@example.com> * Mamba prefix caching fixes (NVIDIA#5502) Signed-off-by: Keshav Santhanam <ksanthanam@nvidia.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Exercise nested MFSDP CUDA graph capture (NVIDIA#5796) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Implement Quantile Balancing in MoE (NVIDIA#5349) Signed-off-by: Haoran Zhang <haoranz@nvidia.com> * Unset NCCL overrides for MFSDP v2 tests (NVIDIA#5794) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Fix MegatronFSDP root module hook dispatch (NVIDIA#5808) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Pin cudnn-fe and cuTeDSL version (NVIDIA#5812) Signed-off-by: Ajay Balasa <abalasa@nvidia.com> * chore: rotate oncall schedule * Inference: Add the nemotron_v3 reasoning parser (NVIDIA#5634) Signed-off-by: Siddharth Singh <sidsingh@nvidia.com> * Missing moe_router_dtype causes unexpected downcast in ModelOpt example (NVIDIA#5810) Signed-off-by: Jinhang Choi <jinhangc@nvidia.com> Co-authored-by: Cory Ye <44509866+cspades@users.noreply.github.com> * Avoid FSDP unit terminology in MFSDP v2 (NVIDIA#5793) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> Signed-off-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com> Co-authored-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com> * Fix configured norm epsilon in MambaLayer (NVIDIA#5750) Signed-off-by: Shanhao <5197744+shanhaoli@users.noreply.github.com> * [refactor] Common combined-1F1B schedule-plan base (1/4 of NVIDIA#4798) (NVIDIA#4941) Signed-off-by: Yan Xu <yxu1@nvidia.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * chore(tests): AUT-851 move NCCL defaults from run_ci_test.sh to conftest (NVIDIA#5826) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * Set num_splits to 0 for FA4 inference (NVIDIA#5804) Signed-off-by: Keshav Santhanam <ksanthanam@nvidia.com> * ci: Enhance nightly/mr/weekly error reporting (NVIDIA#5831) Signed-off-by: Ajay Balasa <abalasa@nvidia.com> * feat(docker): Add NCCL installation script and install NCCL 2.30.4 (NVIDIA#5815) Signed-off-by: Ajay Balasa <abalasa@nvidia.com> * IMA fix by making the copy of book keeping buffer to GPU blocking (NVIDIA#5715) Signed-off-by: Shanmugam Ramasamy <111910568+shanmugamr1992@users.noreply.github.com> * Add GPTModel to HybridModel migration guide (NVIDIA#5698) Signed-off-by: Philip Petrakian <ppetrakian@nvidia.com> * Pair frozen FSDP backward hooks (NVIDIA#5710) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Clarify NVIDIA email signing guidance (NVIDIA#5699) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Overlap FSDP communication with compute (NVIDIA#5719) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * chore(skills): add Regent Open Plugin manifest (NVIDIA#5840) Signed-off-by: oliver könig <okoenig@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * chore(skills): remove Open Plugin manifest (superseded) (NVIDIA#5842) Signed-off-by: oliver könig <okoenig@nvidia.com> * return prefix cache hits data from the chat completions api (NVIDIA#5609) Signed-off-by: Siddharth Singh <sidsingh@nvidia.com> * Refactor data parallel coordinator to enable modular handlers (NVIDIA#5550) Signed-off-by: Keshav Santhanam <ksanthanam@nvidia.com> * Pass device IDs to cleanup barrier (NVIDIA#5702) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Fix averaging for MoE z-loss metric tracking (NVIDIA#3199) Signed-off-by: Markus Schnös <markus.schnoes@deepl.com> Co-authored-by: Markus Schnös <markus.schnoes@deepl.com> * test(mfsdp): AUT-881 mark test_overlaps_communication_and_compute flaky (NVIDIA#5848) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * Inference: Extend default cuda-graph coverage to 512 tokens (NVIDIA#5797) * Fix for sequence-level aux MoE loss being dependent on batch size (NVIDIA#5798) Signed-off-by: Oleg Sudakov <osudakov@nvidia.com> Signed-off-by: Oleg Sudakov <oleg.sudakov@outlook.com> Co-authored-by: Fei Wu <33940270+YangFei1990@users.noreply.github.com> * Allow parameterless FSDP root modules (NVIDIA#5711) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Fix issue where parameter groups with different min/max LRs get overridden at checkpoint load time (NVIDIA#4705) Signed-off-by: John St John <jstjohn@nvidia.com> Signed-off-by: John St. John <jstjohn@nvidia.com> * fix bug where Gemma4 is not working with recompute_granularity = "full" (NVIDIA#5324) Signed-off-by: Yury Parfenov <4665475+warpuv@users.noreply.github.com> Co-authored-by: Guihong Li <guihongl@nvidia.com> * Avoid extra MFSDP v2 model-weight sync memcpy (NVIDIA#5834) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * [experimental] Add experimental/agent_compose placeholder with preview pointer (NVIDIA#5639) Signed-off-by: Yan Bai <bayan@nvidia.com> * Stabilize mfsdp_v2 overlap test by enlarging the model (NVIDIA#5846) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> * Print important dependencies (NVIDIA#5814) Signed-off-by: Gautham Kollu <gkollu@nvidia.com> * Test zero-CTA copy-engine all-gather (NVIDIA#5858) Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Route Lion through DistributedOptimizer and support single-moment checkpointing (NVIDIA#5742) Signed-off-by: Deepak Narayanan <dnarayanan@nvidia.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> * Fix broken remove_sharded_tensors public API and re-enable its unit test (NVIDIA#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> * Make the model larger and higher mb size to make reduce flakiness (NVIDIA#5816) Signed-off-by: Gautham Kollu <gkollu@nvidia.com> * chore(beep boop 🤖): Bump (main) (2026-07-20) * Update active oncall to Phlip79 this week (NVIDIA#5896) Signed-off-by: Philip Petrakian <ppetrakian@nvidia.com> * Overlap async scheduling phases (NVIDIA#5549) Signed-off-by: Lawrence McAfee <lmcafee@nvidia.com> * fix(deps): AUT-1323 use released dev dependency sources (NVIDIA#6273) Signed-off-by: NVIDIA NeMo Bot <nemo-bot@nvidia.com> Co-authored-by: NVIDIA NeMo Bot <nemo-bot@nvidia.com> * build: AUT-1363 verify downloaded yq binaries (NVIDIA#6344) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * cp: chore(ci): bump community workflow to v1.8.8 (NVIDIA#6345) Signed-off-by: oliver könig <okoenig@nvidia.com> Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> Co-authored-by: oliver könig <okoenig@nvidia.com> * fix(ci): AUT-1396 stabilize docker cache and external test queue (NVIDIA#6348) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * fix(optimizer): AUT-1363 avoid grad threshold check during capture (NVIDIA#6355) Signed-off-by: Hristo Filaretov <hfilaretov@nvidia.com> Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> Co-authored-by: Hristo Filaretov <hello@hgf.sh> Co-authored-by: Michał Marcinkiewicz <43240942+mmarcinkiewicz@users.noreply.github.com> * [dev] Refactor CSA structure: Move CSA implementation helpers into csa_utils dir (NVIDIA#6372) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * [dev] Optimize MTP contiguous packed-CP rolls (NVIDIA#6246) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * [Dev] Update moe recipes (NVIDIA#6335) Signed-off-by: Xin Yao <xiny@nvidia.com> * fix(ci): redact sensitive environment values from test output (NVIDIA#6408) Signed-off-by: oliver könig <okoenig@nvidia.com> * [dev] [Deepseek-V4] Fix fused CSA indexer loss normalization and compact attention indices (NVIDIA#6349) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * ci(auth): treat svcnemo-autobot as internal (NVIDIA#6437) Signed-off-by: oliver könig <okoenig@nvidia.com> * [DEV] fix(multimodal_dev): make --record-memory-history work on the model_provider entry (NVIDIA#6277) Signed-off-by: xuwenc <xuwenc@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: Li Tao <lit@nvidia.com> * fix(ci): AUT-1427 skip Claude labeling for external authors (NVIDIA#6395) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * fix: AUT-1504 abort when SSO list download fails on dev (NVIDIA#6517) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * ci: AUT-1408 backport GitHub App authentication to dev (NVIDIA#6435) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * fix(transformer): AUT-1497 support dual RoPE full recompute (NVIDIA#6519) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * ci: Do not upload docker oci artifact attestations (NVIDIA#6543) Signed-off-by: Charlie Truong <chtruong@nvidia.com> * Fix non-fused mHC projection for empty sequences (NVIDIA#6371) Signed-off-by: bvolpato <brunocvcunha@gmail.com> * [dev] Refactor: extract and split common logic between GDN & GDN2 (cherry-pick NVIDIA#5843) (NVIDIA#6088) Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> * [Dev] Allow FP8/FP4 with AbsorbedMLA up-projection recompute (NVIDIA#6178) Signed-off-by: Yunsheng Ni <yunshengn@nvidia.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * [dev] Add chunked optimizer-state and master-weight offload (NVIDIA#6244) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * [Dev] Support mHC selective recompute with CUDA graphs under EP a2a overlap (NVIDIA#5841) Signed-off-by: Jingqi Yang <jingqiny@nvidia.com> Signed-off-by: jingqiny-99 <jingqiny@nvidia.com> * [Dev] Recompute EP A2A overlap activations per layer instead of per model chunk (NVIDIA#6311) Signed-off-by: Pingtian Li <pingtianl@nvidia.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * [dev] moe(perf): Refactor CP layout organization for Qwen3.5-style hybrid attention model (NVIDIA#6387) Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com> Co-authored-by: Haoran Zhang <haoranz@nvidia.com> * [lite] Add MagiAttention as an optional core-attention backend for qwen3_moe (NVIDIA#6478) Signed-off-by: Tailai Ma <58548582+xiaoyao0115@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * [dev] Overlap CP communication for indexer and compressed KV (NVIDIA#5691) Signed-off-by: xiaoyao0115 <1804647152@qq.com> * [dev] Replace DP balance all-to-all rerouting with all-gather (NVIDIA#6378) Signed-off-by: xiaoyao0115 <1804647152@qq.com> * [dev] moe(perf): Minor improvements of pre-GDR fused path. (NVIDIA#6658) Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com> Co-authored-by: CarlosGomes98 <cgomes@nvidia.com> * [Dev] Generalize FSDP persistent communication buffers (NVIDIA#6316) Signed-off-by: hongbinl <hongbinl@nvidia.com> * [Dev] Add Ling-V3 Tiny hybrid model training support (NVIDIA#6556) Signed-off-by: fkuner <784819644@qq.com> Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com> Signed-off-by: Fan Kun <784819644@qq.com> Co-authored-by: Yuzhong Wang <yuzhongw@nvidia.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> * ci: centralize container builds and add cache population workflow (NVIDIA#6646) Signed-off-by: Ajay Balasa <abalasa@nvidia.com> Signed-off-by: Charlie Truong <chtruong@nvidia.com> * ci: prioritize baseline cache for merge groups (NVIDIA#6721) Signed-off-by: Charlie Truong <chtruong@nvidia.com> * ci: use base PR cache as fallback (NVIDIA#6774) Signed-off-by: Charlie Truong <chtruong@nvidia.com> * Set provenance: false during docker build Signed-off-by: Charlie Truong <chtruong@nvidia.com> * [dev](Fix): Make the mHC attention CUDA-graph split opt-in (NVIDIA#6661) Signed-off-by: Jingqi Yang <jingqiny@nvidia.com> Signed-off-by: jingqiny-99 <jingqiny@nvidia.com> * feat: support unified model bagel with generation and understanding (NVIDIA#3635) Signed-off-by: sophiayyya <yangjingyi0730@163.com> Signed-off-by: root <root@eos0294.eos.clusters.nvidia.com> Signed-off-by: Sophia Yang <sopyang@cw-dfw-cs-001-dc-02.cm.cluster> Signed-off-by: Deyu Fu <deyuf@nvidia.com> Signed-off-by: Sophia Yang <sopyang@cw-dfw-cs-001-vscode-01.cm.cluster> Co-authored-by: root <root@eos0294.eos.clusters.nvidia.com> Co-authored-by: Sophia Yang <sopyang@cw-dfw-cs-001-dc-02.cm.cluster> Co-authored-by: Deyu Fu <deyuf@nvidia.com> Co-authored-by: Sophia Yang <sopyang@cw-dfw-cs-001-vscode-01.cm.cluster> * [Dev] Fuse standard RoPE packing for MLA and DSA (NVIDIA#6343) Signed-off-by: Robin Zhang <robinz@nvidia.com> * [dev] add DSv4 Flash THD 4K and 64K recipe (NVIDIA#6911) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * [Dev] Add configurable attention latent normalization epsilon (NVIDIA#6204) Signed-off-by: janEbert <janpabloe@nvidia.com> Signed-off-by: Robin Zhang <robinz@nvidia.com> Co-authored-by: janEbert <janpabloe@nvidia.com> * [Dev] Add TileLang DSA and indexer weights projection precision controls (NVIDIA#6279) Signed-off-by: ℍ𝕠𝕝𝕝𝕠𝕨 𝕄𝕒𝕟 <hollowman@opensuse.org> Signed-off-by: Robin Zhang <robinz@nvidia.com> Co-authored-by: ℍ𝕠𝕝𝕝𝕠𝕨 𝕄𝕒𝕟 <hollowman@opensuse.org> * fix(deps): AUT-2172 pin compatible TileLang runtime (NVIDIA#6946) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * Fix hybrid MTP partial CUDA graph capture (NVIDIA#6583) Signed-off-by: guihong-nv <guihongl@nvidia.com> * [dev] Fix mock data, hybrid recompute, CUDA graph reuse, and Hash MoE selection (NVIDIA#6704) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> Signed-off-by: Deyu Fu <deyuf@nvidia.com> Co-authored-by: Deyu Fu <deyuf@nvidia.com> * [Dev] Support paged stash with TE whole-MoE CUDA graphs (NVIDIA#6022) Signed-off-by: Robin Zhang <robinz@nvidia.com> Co-authored-by: Charlie Truong <chtruong@nvidia.com> * [Dev] Support device-initiated grouped linear without TE op fuser (NVIDIA#6847) Signed-off-by: Zhongbo Zhu <42691305+zhongbozhu@users.noreply.github.com> Signed-off-by: hongbinl <hongbinl@nvidia.com> Co-authored-by: Zhongbo Zhu <42691305+zhongbozhu@users.noreply.github.com> * [dev] lite: Sync Megatron Lite experimental updates for deepseek v4 (NVIDIA#6397) Signed-off-by: Yan Bai <bayan@nvidia.com> * [Dev] fix: account for DSA top-k sparsity and indexer cost in FLOPs (NVIDIA#6753) Signed-off-by: Yunsheng Ni <yunshengn@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * build: define ssm and te extras consumed by Dockerfile.ci.lts (NVIDIA#7004) Signed-off-by: oliver könig <okoenig@nvidia.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * [Dev] Add global-batch quantile balancing (NVIDIA#6637) Signed-off-by: Harry Zhou <hhanyu@nvidia.com> Signed-off-by: Deyu Fu <deyuf@nvidia.com> * chore: AUT-2153 sync main through 3005e9c into dev (NVIDIA#6907) Signed-off-by: Hristo Filaretov <hfilaretov@nvidia.com> Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> Co-authored-by: Hristo Filaretov <hello@hgf.sh> Co-authored-by: Michał Marcinkiewicz <43240942+mmarcinkiewicz@users.noreply.github.com> Co-authored-by: Jingyue Wu <jingyuew@nvidia.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * [dev] fix: avoid duplicate offload of recomputed activations (NVIDIA#7044) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * [Dev] ci: guard examples/multimodal_dev with a unit-test bucket (NVIDIA#6083) Signed-off-by: Li Tao <lit@nvidia.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> * [Dev] Add RMSNorm latent up-projection (NVIDIA#6804) Signed-off-by: Harry Zhou <hhanyu@nvidia.com> * cp: AUT-2161 route external jobs through ephemeral v2 (NVIDIA#6909) (NVIDIA#7065) Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> Signed-off-by: Charlie Truong <chtruong@nvidia.com> Co-authored-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * fix(sync): preserve reviewable argument history Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 562bada) * fix(sync): defer unauditable triage integration Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 796e9a2) * fix(sync): defer coupled triage consumers Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 69084d2) * style(sync): format inherited Python changes Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit cdf6af0) * fix: restore omitted sync dependencies Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 4d9b765) * fix: close remaining sync test failures Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 9f3a66c) * fix: repair remaining sync unit failures Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit e07e13b) * style: format dynamic engine assignment Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit b25258e) * fix: restore async scheduling token commit Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 56834c1) * fix(inference): restore synchronized async and cache contracts Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit ed1a2db) * fix(modelopt): avoid unsupported recipe API Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit e884bf3) * fix(modelopt): normalize legacy quantization configs Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit a659231) * fix(modelopt): support legacy quantization configs Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit e4ba000) * fix(modelopt): support legacy prefill signatures Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 3192094) * fix(modelopt): restore migrated model builders Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 316a437) * fix(config): resolve model config defaults at call time Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit ab30e83) * fix(gpt): repair hyperconnection and MTP specs Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit 95da38c) * test(hybrid): refresh QAD total-loss golden values Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> (cherry picked from commit d8f1e40) * test: align quantile balancing coverage with dev Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * fix(moe): preserve sequence aux loss batch scaling Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> * [Dev] Add SiTU-GLU through Transformer Engine (NVIDIA#6673) Signed-off-by: Harry Zhou <hhanyu@nvidia.com> Signed-off-by: Deyu Fu <deyuf@nvidia.com> Co-authored-by: Deyu Fu <deyuf@nvidia.com> * [dev] Fix premature handler advancement in fine-grained activation offloading (NVIDIA#6783) Signed-off-by: HaochenYuan <haocheny@nvidia.com> Signed-off-by: hongbinl <hongbinl@nvidia.com> Co-authored-by: hongbinl <hongbinl@nvidia.com> * [DEV] fix(multimodal_dev): derive mock samples from the sample index (NVIDIA#6287) Signed-off-by: xuwenc <xuwenc@nvidia.com> Co-authored-by: Xin Yao <xiny@nvidia.com> * [DEV] fix(multimodal_dev): align the Qwen3.5-VL fp32 RoPE wrappers with apply_rotary_pos_emb (NVIDIA#6611) Signed-off-by: xuwenc <xuwenc@nvidia.com> Co-authored-by: Xin Yao <xiny@nvidia.com> * [dev] [fix] Skip auxiliary loss for hash MoE layers (NVIDIA#7079) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> Co-authored-by: Xin Yao <xiny@nvidia.com> * [dev] [DeepSeek-V4] Add compact BF16 and MXFP8 DSA indexer support (NVIDIA#5992) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * feat(moe): add a megakernel backend with MOK integration (NVIDIA#6572) Signed-off-by: qizhang <qizhang@nvidia.com> Signed-off-by: Xin Yao <xiny@nvidia.com> Co-authored-by: Xin Yao <xiny@nvidia.com> * [MoE] Preserve HybridEP capacity across CUDA graph replay (NVIDIA#6999) Signed-off-by: Gao <gdeng@nvidia.com> * [dev] DeepSeek-V4 CSA optimization: fuse some THD-related ops (NVIDIA#7064) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * [Dev] Enable dense routing maps for Flex dispatch (NVIDIA#6614) Signed-off-by: Harry Zhou <hhanyu@nvidia.com> Signed-off-by: Deyu Fu <deyuf@nvidia.com> Co-authored-by: Deyu Fu <deyuf@nvidia.com> Co-authored-by: Xin Yao <xiny@nvidia.com> * [Dev] feat(multimodal): migrate Qwen3.5-VL to HybridModel (NVIDIA#6315) Signed-off-by: Li Tao <lit@nvidia.com> * [Dev] fix: Preserve offload events in Hybrid mHC CUDA graphs (NVIDIA#7014) Signed-off-by: jingqiny-99 <jingqiny@nvidia.com> * [dev] agent_compose: adopt Core fusions and main_grad accumulation on the DSv4 path (NVIDIA#7127) Signed-off-by: Yan Bai <bayan@nvidia.com> Signed-off-by: leikaixiang.shyoshyo <leikaixiang.shyoshyo@bytedance.com> Co-authored-by: leikaixiang.shyoshyo <leikaixiang.shyoshyo@bytedance.com> * [Dev] Remove unused legacy hybrid CP implementation (NVIDIA#7203) Signed-off-by: Tailai Ma <tailaim@nvidia.com> * chore: AUT-2153 sync exact 100 main commits into dev (NVIDIA#7094) Signed-off-by: Ajay Balasa <abalasa@nvidia.com> Signed-off-by: Evgenii Zheltonozhskii <zheltonozhskiy@gmail.com> Signed-off-by: Yongqiang Wang <yongqiang.seagull@gmail.com> Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com> Signed-off-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com> Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> Signed-off-by: Philip Petrakian <ppetrakian@nvidia.com> Signed-off-by: Teodor-Dumitru Ene <teodord.ene@gmail.com> Signed-off-by: Ali Arda Eker <aeker@nvidia.com> Signed-off-by: Charlie Truong <chtruong@nvidia.com> Signed-off-by: ykarnati <ykarnati@nvidia.com> Signed-off-by: William Dykas <wdykas@oci-hsg-cs-001-vscode-03.cm.cluster> Signed-off-by: William Dykas <wdykas@oci-nrt-cs-001-vscode-01.cm.cluster> Signed-off-by: zhongboz <zhongboz@nvidia.com> Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com> Signed-off-by: Siddharth Singh <sidsingh@nvidia.com> Signed-off-by: shanmugamr1992 <shanmugamr@nvidia.com> Signed-off-by: Keshav Santhanam <ksanthanam@nvidia.com> Signed-off-by: Shijie Wang <jaywan@nvidia.com> Signed-off-by: [Your Name] <your.email@example.com> Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> Signed-off-by: Jon Barker <jbarker@aws-dfw-cs-001-login-01.cm.cluster> Signed-off-by: wdykas <wdykas@nvidia.com> Signed-off-by: Chen Cui <chcui@nvidia.com> Signed-off-by: janEbert <janpabloe@nvidia.com> Signed-off-by: oliver könig <okoenig@nvidia.com> Signed-off-by: HaochenYuan <haocheny@nvidia.com> Signed-off-by: Hollow Man <hollowman@opensuse.org> Signed-off-by: William Dykas <wdykas@nvidia.com> Signed-off-by: Cory Ye <cye@nvidia.com> Signed-off-by: Laura Dang <laurad@nvidia.com> Signed-off-by: Shiqing Fan <shiqingf@nvidia.com> Signed-off-by: Deepak Narayanan <deepakn94@gmail.com> Signed-off-by: Jiangfei Duan <jiangfeid@nvidia.com> Signed-off-by: Philip Monk <pmonk@nvidia.com> Signed-off-by: Jimmy Zhang <jiemingz@nvidia.com> Signed-off-by: Xuanteng Huang <xuantengh@nvidia.com> Signed-off-by: guihong-nv <guihongl@nvidia.com> Signed-off-by: asolergi-nv <asolergibert@nvidia.com> Signed-off-by: Antoni-Joan Solergibert <asolergibert@nvidia.com> Signed-off-by: ilml <tolong@nvidia.com> Signed-off-by: Tom Long <tolong@nvidia.com> Signed-off-by: Deepak Narayanan <dnarayanan@nvidia.com> Signed-off-by: YangFei1990 <feiw@nvidia.com> Signed-off-by: Siddhartha Raman Sundara Raman <sraman@nvidia.com> Signed-off-by: kunlunl <kunlunl@nvidia.com> Signed-off-by: Lawrence McAfee <lmcafee@nvidia.com> Signed-off-by: Björn Buschkämper <bjoern.buschkaemper@gmail.com> Signed-off-by: Chaitra Sathe <csathe@nvidia.com> Signed-off-by: Will Dykas <wdykas@nvidia.com> Signed-off-by: shanmugamr1992 <shanmugamr1992@gmail.com> Signed-off-by: Asha Anoosheh <aanoosheh@nvidia.com> Signed-off-by: Yan Bai <bayan@nvidia.com> Co-authored-by: Ajay <abalasa@nvidia.com> Co-authored-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> Co-authored-by: Yongqiang Wang <yongqiang.seagull@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: achyuthan.s <113010327+Achyuthan-S@users.noreply.github.com> Co-authored-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com> Co-authored-by: Jingyue Wu <jingyuew@nvidia.com> Co-authored-by: Philip Petrakian <ppetrakian@nvidia.com> Co-authored-by: Teodor-Dumitru Ene <34819528+tdene@users.noreply.github.com> Co-authored-by: Ali Arda Eker <aeker1@binghamton.edu> Co-authored-by: Charlie Truong <chtruong@nvidia.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Yashaswi Karnati <144376261+yashaswikarnati@users.noreply.github.com> Co-authored-by: wdykas <73254672+wdykas@users.noreply.github.com> Co-authored-by: William Dykas <wdykas@oci-hsg-cs-001-vscode-03.cm.cluster> Co-authored-by: William Dykas <wdykas@oci-nrt-cs-001-vscode-01.cm.cluster> Co-authored-by: Zhongbo Zhu <42691305+zhongbozhu@users.noreply.github.com> Co-authored-by: Siddharth Singh <sidsingh@nvidia.com> Co-authored-by: Shanmugam Ramasamy <111910568+shanmugamr1992@users.noreply.github.com> Co-authored-by: Keshav Santhanam <ksanthanam@nvidia.com> Co-authored-by: Shijie <jaywan@nvidia.com> Co-authored-by: [Co-author Name] <coauthor.email@example.com> Co-authored-by: Jon Barker <jbarker@nvidia.com> Co-authored-by: Jon Barker <jbarker@aws-dfw-cs-001-login-01.cm.cluster> Co-authored-by: Chen Cui <chcui@nvidia.com> Co-authored-by: janEbert <janpabloe@nvidia.com> Co-authored-by: oliver könig <okoenig@nvidia.com> Co-authored-by: HaochenYuan <106647990+HaochenYuan@users.noreply.github.com> Co-authored-by: ℍ𝕠𝕝𝕝𝕠𝕨 𝕄𝕒𝕟 <hollowman@opensuse.org> Co-authored-by: Cory Ye <44509866+cspades@users.noreply.github.com> Co-authored-by: Laura Dang <laurad@nvidia.com> Co-authored-by: Shiqing Fan <shiqingf@nvidia.com> Co-authored-by: Jieming Zhang <jiemingz@nvidia.com> Co-authored-by: Deepak Narayanan <deepakn94@gmail.com> Co-authored-by: Jiangfei Duan <jiangfeid@nvidia.com> Co-authored-by: Philip Monk <phil@pcmonk.me> Co-authored-by: Jimmy Zhang <133159885+jiemingz@users.noreply.github.com> Co-authored-by: Xuanteng Huang <44627253+xuantengh@users.noreply.github.com> Co-authored-by: Guihong Li <guihongl@nvidia.com> Co-authored-by: Antoni-Joan Solergibert <asolergibert@nvidia.com> Co-authored-by: Tom Long <tolong@nvidia.com> Co-authored-by: Deepak Narayanan <dnarayanan@nvidia.com> Co-authored-by: Fei Wu <33940270+YangFei1990@users.noreply.github.com> Co-authored-by: Xin Yao <xiny@nvidia.com> Co-authored-by: Siddhartha Raman Sundara Raman <sraman@nvidia.com> Co-authored-by: kunlunl <kunlunl@nvidia.com> Co-authored-by: Lawrence McAfee <85179052+lmcafee-nvidia@users.noreply.github.com> Co-authored-by: Jorge Albericio <jalbericiola@nvidia.com> Co-authored-by: Teodor-Dumitru Ene <teodord.ene@gmail.com> Co-authored-by: Björn Buschkämper <bjoern.buschkaemper@gmail.com> Co-authored-by: Dmytro Pykhtar <37850217+dimapihtar@users.noreply.github.com> Co-authored-by: nvcsathe <csathe@nvidia.com> Co-authored-by: Will Dykas <wdykas@nvidia.com> Co-authored-by: Philip Monk <pmonk@nvidia.com> Co-authored-by: shanmugamr1992 <shanmugamr1992@gmail.com> Co-authored-by: Asha Anoosheh <aanoosheh@nvidia.com> Co-authored-by: Yan Bai <bayan@nvidia.com> * revert(sync): revert AUT-2153 sync exact 100 main commits into dev (NVIDIA#7094) (NVIDIA#7283) Signed-off-by: oliver könig <okoenig@nvidia.com> * [dev] preserve mcore/TE parameter attributes on MOK-aliased expert weights across Module._apply (NVIDIA#7289) Signed-off-by: HaochenYuan <haocheny@nvidia.com> * [dev] Load-balanced context-parallel DSA indexer (NVIDIA#6058) Signed-off-by: jingqiny-99 <jingqiny@nvidia.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> * Recompute RoPE during bwd pass for DSv4 (NVIDIA#7036) Signed-off-by: Ravi Ghadia <rghadia@nvidia.com> * [dev] Make fused CSA Top-K deterministic across no-grad and grad forwards (NVIDIA#7169) Signed-off-by: Bo Li <22713281+bobboli@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> * [dev](perf): DSA pre-attention: plan-driven scorer dispatch, host-built CP layout metadata (NVIDIA#6206) Signed-off-by: jingqiny-99 <jingqiny@nvidia.com> * [dev] Enable mHC attention CUDA graph split for HybridStack and packed THD (NVIDIA#7385) Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> * [PP] Skip shape exchange for fixed packed sequences (NVIDIA#7000) Signed-off-by: Gao <gdeng@nvidia.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> * [Dev] Add pipeline-parallel support to multimodal training in multimodal_dev code path (NVIDIA#6081) Signed-off-by: Li Tao <lit@nvidia.com> * [Dev] Skip attention-mask static inputs for mask-less attention modules (NVIDIA#6797) Signed-off-by: Li Tao <lit@nvidia.com> * revert: drop the early multimodal_dev test/CI cherry-picks superseded upstream Upstream NVIDIA#6083 (a1fa3e5, "ci: guard examples/multimodal_dev with a unit-test bucket") is the final, reviewed version of four early commits carried on dev_mdp by the same author. Keeping both would leave an early and a final version of the same work in one tree. Reverted: 816ccf3 Fix mRoPE parity test stub missing new config fields 62e10ca test(examples/multimodal_dev): repair stale rope_utils config stub 0194190 test(examples/multimodal_dev): make the standalone harnesses pytest tests e0df736 ci: run the examples/multimodal_dev suite as a unit-test bucket Evidence that upstream fully absorbed them: test_thd_correctness.py is byte-identical between dev_mdp and origin/dev, and the upstream conftest.py is a strict superset (+57 lines) of ours, additionally carrying a cleanup hook for the NCCL process group and restricting the exit-code-5 remap to the --experimental pass. The upstream versions arrive with the subsequent merge of origin/dev. Signed-off-by: Li Tao <lit@nvidia.com> * revert: drop the early multimodal_dev PP support superseded by upstream NVIDIA#6081 Upstream c82b949 ("[Dev] Add pipeline-parallel support to multimodal training in multimodal_dev code path (NVIDIA#6081)", 2026-09-18) is the final, reviewed version of dev_mdp's 3f29946, by the same author. It landed upstream after the sync research was written, which is why PR_MAPPING.md still records 3f29946 as having no upstream counterpart. Upstream's version is both larger and already expressed on top of the NVIDIA#6315 HybridModel refactor: test_pp_support.py 553 lines vs our 401, plus a new test_run_script_fsdp_pp.py, conftest hooks and a data/mock.py fix. Carrying ours as well would leave two PP implementations in one tree. Two hunks could not be reverted mechanically, because later MDP commits build on them; both are resolved to keep the MDP work and drop only the PP-specific parts: - models/base.py: the MDP stack refactored the reverted region into _prepare_decoder_inputs(). Ours is kept as-is here and reconciled against upstream in the merge commit instead. - models/qwen35_vl/model.py: build_vision_encoder (MDP's replicated encoder domain) is kept; pre_process/post_process/vp_stage are dropped. The PP>1 rejection in pretrain_multimodal.py is restored by this revert and removed again by the merge, where upstream's PP support arrives. Signed-off-by: Li Tao <lit@nvidia.com> * fix(multimodal_dev): bind emit_pixels ahead of the THD/BSHD split The merge unified the two independent reasons to skip pixel materialization -- upstream's non-first pipeline stage (include_pixel_values) and MDP's owner-sharded capture window (suppress_pixels) -- into a single emit_pixels predicate, but computed it inside the packed/THD branch of pack_or_pad_batch() while also consulting it from the BSHD branch. Any BSHD collation therefore raised UnboundLocalError: cannot access local variable 'emit_pixels' where it is not associated with a value caught by examples/multimodal_dev/tests/test_thd_e2e.py:: TestPackOrPadBatchPadded::test_equal_lengths. Hoist both bindings above the layout split; both layouts consult them and neither depends on packing. Signed-off-by: Li Tao <lit@nvidia.com> * fix(mdp): give MockSFTLowLevelDataset a vocab_size for length-only draws Upstream now rejects MockSFTLowLevelDataset in "file"/"distribution" mode unless vocab_size >= 2, because that class can also synthesize token ids: ValueError: Generated mock data requires vocab_size >= 2. If tokenizer.vocab_size is unavailable, set vocab_size in the mock dataset config JSON; got None. MDP builds it for one purpose only -- to read `.sequence_lengths` and draw per-sample total token lengths -- and never materializes a token, so it had no reason to supply a vocabulary and did not. Supply a nominal vocab_size when the caller's --mdp-mock-dataset-config-json payload does not already carry one. vocab_size is not an input to generate_lognormal_samples(), so the drawn lengths, and therefore the scenario pool and every rank's view of it, are bit-identical to before. Without this the whole mdp_mock data path -- not just the tests -- fails at startup after the merge. Caught by examples/multimodal_dev/tests/test_thd_static_packing.py:: TestMockLengthDistribution (5 tests). Signed-off-by: Li Tao <lit@nvidia.com> * fix(mdp): drive the MDP proxy runner from --hybrid-layer-pattern Since the Qwen3.5-VL HybridModel migration, the model factory rejects a run that does not pass --hybrid-layer-pattern: ValueError: Qwen3.5-VL uses HybridModel and requires --hybrid-layer-pattern. Use GEGEGE*E per four MoE blocks (or G-G-G-*- for dense blocks), and append /*E or /*- for each MTP depth. run_mdp_experiments.sh is fork-only, so upstream could not update it; it still described the GDN placement with --linear-attention-freq 4, which HybridModel ignores. Every MDP proxy run therefore failed at startup after the merge. Port the expansion upstream added to run_qwen35_vl.sh: ATTN_CADENCE is one period of the attention layout ('G' GatedDeltaNet, '*' full attention), repeated and truncated to NUM_LAYERS, each block followed by its MLP symbol ('E' MoE / '-' dense), then one "/<last-attn><mlp>" per MTP depth. The default cadence "GGG*" is exactly what --linear-attention-freq 4 expressed, so the model is unchanged: the study shape (NUM_LAYERS=8, NUM_EXPERTS=8, MTP_NUM_LAYERS=1) yields GEGEGE*EGEGEGE*E/*E. GDN=0 degenerates to all-full-attention. --linear-attention-freq is dropped rather than kept alongside, since TransformerConfig skips its assertion for hybrid models and keeping it would create a second source of truth. Signed-off-by: Li Tao <lit@nvidia.com> * fix(mdp): pass --position-embedding-type mrope and --mrope-section in the proxy runner The Qwen3.5-VL factory now validates both explicitly: ValueError: Qwen3.5-VL requires --mrope-section 11 11 10, but got None. The section split is tied to kv_channels and ROTARY_PERCENT; a mismatch silently misplaces the T/H/W channel boundaries. Before the HybridModel migration, MultimodalModel hard-coded position_embedding_type="mrope" when constructing the decoder, so the proxy runner could pass --position-embedding-type rope and still get an MRoPE model. The migrated model threads the CLI value through and rejects anything but mrope, and takes the section split from --mrope-section rather than an internal constant. Pass both. 11 11 10 matches MROPE_SECTION in models/qwen35_vl/configuration.py and sums to half the rotary dimension (kv_channels * rotary_percent / 2 = 256 * 0.25 / 2 = 32), i.e. the same split the model used implicitly before, so the trained model is unchanged. Signed-off-by: Li Tao <lit@nvidia.com> * fix(mdp): let the capture window, not pipeline rank, decide who keeps pixels Upstream NVIDIA#6081 drops pixel_values off every non-first pipeline stage, on the premise that only the first stage holds the vision encoder. That premise does not hold under MDP: the encoder is a separate replicated domain, and which rank must materialize a microbatch's pixels is decided by the capture window, so a rank that is not PP stage 0 can still be the owner. The merge applied both rules at once, which broke every MDP run with PP > 1: the collate still emits image_grid_thw on every stage, so a stage that dropped the pixels but kept the grids tripped MDP's payload check MdpConfigurationError: MDP: microbatch 1 violates: pixel data and grid metadata either both exist or both are absent (items without pixels). Keep the pipeline rule for the native path and defer to MDP's own pixel_capture_suppressed() when MDP is enabled. Signed-off-by: Li Tao <lit@nvidia.com> * fix(mdp): express VPP through the hybrid layer pattern, not a CLI flag Since the Qwen3.5-VL HybridModel migration, virtual pipeline stages are derived from the '|' segments of --hybrid-layer-pattern, and passing the old flag is rejected outright: AssertionError: --num-virtual-stages-per-pipeline-rank should not be used with --hybrid-layer-pattern. Virtual pipeline stages are derived from the number of | segments in the pattern. run_mdp_experiments.sh still emitted --num-virtual-stages-per-pipeline-rank, so every VPP>1 configuration failed at argument validation -- in the proxy matrix that is the ep-overlap cell, which needs VPP>1 because EP overlap requires it when PP>1. Drop the flag and split the pattern into PP x VPP segments instead. The study shape (NUM_LAYERS=8, PP=2, VPP=2) now yields GEGE|GE*E|GEGE|GE*E/*E. VPP=1 deliberately emits no '|' at all, leaving the segmentation implicit: Megatron splits evenly, which is the same layout, so the pattern for every other cell is byte-identical to before and their results stay comparable. Signed-off-by: Li Tao <lit@nvidia.com> --------- Signed-off-by: Hristo Filaretov <hfilaretov@nvidia.com> Signed-off-by: Jingyue Wu <jingyuew@nvidia.com> Signed-off-by: Siddharth Singh <sidsingh@nvidia.com> Signed-off-by: Min Htet Myet <mattralminn@email.com> Signed-off-by: Mattral <mattralminn@gmail.com> Signed-off-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> Signed-off-by: Asha Anoosheh <aanoosheh@nvidia.com> Signed-off-by: Ajay <abalasa@nvidia.com> Signed-off-by: Ajay Balasa <abalasa@nvidia.com> Signed-off-by: [Your Name] <your.email@example.com> Signed-off-by: Keshav Santhanam <ksanthanam@nvidia.com> Signed-off-by: Haoran Zhang <haoranz@nvidia.com> Signed-off-by: Jinhang Choi <jinhangc@nvidia.com> Signed-off-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com> Signed-off-by: Shanhao <5197744+shanhaoli@users.noreply.github.com> Signed-off-by: Yan Xu <yxu1@nvidia.com> Signed-off-by: Shanmugam Ramasamy <111910568+shanmugamr1992@users.noreply.github.com> Signed-off-by: Philip Petrakian <ppetrakian@nvidia.com> Signed-off-by: oliver könig <okoenig@nvidia.com> Signed-off-by: Markus Schnös <markus.schnoes@deepl.com> Signed-off-by: Oleg Sudakov <osudakov@nvidia.com> Signed-off-by: Oleg Sudakov <oleg.sudakov@outlook.com> Signed-off-by: John St John <jstjohn@nvidia.com> Signed-off-by: John St. John <jstjohn@nvidia.com> Signed-off-by: Yury Parfenov <4665475+warpuv@users.noreply.github.com> Signed-off-by: Yan Bai <bayan@nvidia.com> Signed-off-by: Gautham Kollu <gkollu@nvidia.com> Signed-off-by: Deepak Narayanan <dnarayanan@nvidia.com> Signed-off-by: Rui Zhu <rui.zhu.rz399@yale.edu> Signed-off-by: Lawrence McAfee <lmcafee@nvidia.com> Signed-off-by: NVIDIA NeMo Bot <nemo-bot@nvidia.com> Signed-off-by: Hongxiao Bai <hongxiaob@nvidia.com> Signed-off-by: Xin Yao <xiny@nvidia.com> Signed-off-by: xuwenc <xuwenc@nvidia.com> Signed-off-by: Charlie Truong <chtruong@nvidia.com> Signed-off-by: bvolpato <brunocvcunha@gmail.com> Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com> Signed-off-by: Yunsheng Ni <yunshengn@nvidia.com> Signed-off-by: Jingqi Yang <jingqiny@nvidia.com> Signed-off-by: jingqiny-99 <jingqiny@nvidia.com> Signed-off-by: Pingtian Li <pingtianl@nvidia.com> Signed-off-by: Tailai Ma <58548582+xiaoyao0115@users.noreply.github.com> Signed-off-by: xiaoyao0115 <1804647152@qq.com> Signed-off-by: hongbinl <hongbinl@nvidia.com> Signed-off-by: fkuner <784819644@qq.com> Signed-off-by: Fan Kun <784819644@qq.com> Signed-off-by: sophiayyya <yangjingyi0730@163.com> Signed-off-by: root <root@eos0294.eos.clusters.nvidia.com> Signed-off-by: Sophia Yang <sopyang@cw-dfw-cs-001-dc-02.cm.cluster> Signed-off-by: Deyu Fu <deyuf@nvidia.com> Signed-off-by: Sophia Yang <sopyang@cw-dfw-cs-001-vscode-01.cm.cluster> Signed-off-by: Robin Zhang <robinz@nvidia.com> Signed-off-by: janEbert <janpabloe@nvidia.com> Signed-off-by: ℍ𝕠𝕝𝕝𝕠𝕨 𝕄𝕒𝕟 <hollowman@opensuse.org> Signed-off-by: guihong-nv <guihongl@nvidia.com> Signed-off-by: Zhongbo Zhu <42691305+zhongbozhu@users.noreply.github.com> Signed-off-by: Harry Zhou <hhanyu@nvidia.com> Signed-off-by: Li Tao <lit@nvidia.com> Signed-off-by: HaochenYuan <haocheny@nvidia.com> Signed-off-by: qizhang <qizhang@nvidia.com> Signed-off-by: Gao <gdeng@nvidia.com> Signed-off-by: leikaixiang.shyoshyo <leikaixiang.shyoshyo@bytedance.com> Signed-off-by: Tailai Ma <tailaim@nvidia.com> Signed-off-by: Evgenii Zheltonozhskii <zheltonozhskiy@gmail.com> Signed-off-by: Yongqiang Wang <yongqiang.seagull@gmail.com> Signed-off-by: Achyuthan Sivasankar <achyuthan.sivasankar@gmail.com> Signed-off-by: Teodor-Dumitru Ene <teodord.ene@gmail.com> Signed-off-by: Ali Arda Eker <aeker@nvidia.com> Signed-off-by: ykarnati <ykarnati@nvidia.com> Signed-off-by: William Dykas <wdykas@oci-hsg-cs-001-vscode-03.cm.cluster> Signed-off-by: William Dykas <wdykas@oci-nrt-cs-001-vscode-01.cm.cluster> Signed-off-by: zhongboz <zhongboz@nvidia.com> Signed-off-by: Zhongbo Zhu <zhongboz@nvidia.com> Signed-off-by: shanmugamr1992 <shanmugamr@nvidia.com> Signed-off-by: Shijie Wang <jaywan@nvidia.com> Signed-off-by: Jon Barker <jbarker@aws-dfw-cs-001-login-01.cm.cluster> Signed-off-by: wdykas <wdykas@nvidia.com> Signed-off-by: Chen Cui <chcui@nvidia.com> Signed-off-by: Hollow Man <hollowman@opensuse.org> Signed-off-by: William Dykas <wdykas@nvidia.com> Signed-off-by: Cory Ye <cye@nvidia.com> Signed-off-by: Laura Dang <laurad@nvidia.com> Signed-off-by: Shiqing Fan <shiqingf@nvidia.com> Signed-off-by: Deepak Narayanan <deepakn94@gmail.com> Signed-off-by: Jiangfei Duan <jiangfeid@nvidia.com> Signed-off-by: Philip Monk <pmonk@nvidia.com> Signed-off-by: Jimmy Zhang <jiemingz@nvidia.com> Signed-off-by: Xuanteng Huang <xuantengh@nvidia.com> Signed-off-by: asolergi-nv <asolergibert@nvidia.com> Signed-off-by: Antoni-Joan Solergibert <asolergibert@nvidia.com> Signed-off-by: ilml <tolong@nvidia.com> Signed-off-by: Tom Long <tolong@nvidia.com> Signed-off-by: YangFei1990 <feiw@nvidia.com> Signed-off-by: Siddhartha Raman Sundara Raman <sraman@nvidia.com> Signed-off-by: kunlunl <kunlunl@nvidia.com> Signed-off-by: Björn Buschkämper <bjoern.buschkaemper@gmail.com> Signed-off-by: Chaitra Sathe <csathe@nvidia.com> Signed-off-by: Will Dykas <wdykas@nvidia.com> Signed-off-by: shanmugamr1992 <shanmugamr1992@gmail.com> Signed-off-by: Ravi Ghadia <rghadia@nvidia.com> Signed-off-by: Bo Li <22713281+bobboli@users.noreply.github.com> Co-authored-by: Hristo Filaretov <hello@hgf.sh> Co-authored-by: Michał Marcinkiewicz <43240942+mmarcinkiewicz@users.noreply.github.com> Co-authored-by: Jingyue Wu <jingyuew@nvidia.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Siddharth Singh <sidsingh@nvidia.com> Co-authored-by: Min Htet Myet <88831350+Mattral@users.noreply.github.com> Co-authored-by: svcnemo-autobot <svcnemo-autobot@nvidia.com> Co-authored-by: Asha Anoosheh <aanoosheh@nvidia.com> Co-authored-by: Ajay <abalasa@nvidia.com> Co-authored-by: Keshav Santhanam <ksanthanam@nvidia.com> Co-authored-by: Haoran Zhang <haoranz@nvidia.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Jinhang Choi <cepiross@gmail.com> Co-authored-by: Cory Ye <44509866+cspades@users.noreply.github.com> Co-authored-by: svcnvidia-nemo-ci <svcnvidia-nemo-ci@nvidia.com> Co-authored-by: Shanhao <suith27@gmail.com> Co-authored-by: Yan Xu <45385219+Connor-XY@users.noreply.github.com> Co-authored-by: Shanmugam Ramasamy <111910568+shanmugamr1992@users.noreply.github.com> Co-authored-by: Philip Petrakian <ppetrakian@nvidia.com> Co-authored-by: oliver könig <okoenig@nvidia.com> Co-authored-by: Marks101 <46690260+Marks101@users.noreply.github.com> Co-authored-by: Markus Schnös <markus.schnoes@deepl.com> Co-authored-by: OlegSudakov <oleg.sudakov@outlook.com> Co-authored-by: Fei Wu <33940270+YangFei1990@users.noreply.github.com> Co-authored-by: John St. John <jstjohn@users.noreply.github.com> Co-authored-by: Yury Parfenov <4665475+warpuv@users.noreply.github.com> Co-authored-by: Guihong Li <guihongl@nvidia.com> Co-authored-by: Yan Bai <bayan@nvidia.com> Co-authored-by: gautham-kollu <gkollu@nvidia.com> Co-authored-by: Deepak Narayanan <dnarayanan@nvidia.com> Co-authored-by: Rui Zhu <huthvincent@gmail.com> Co-authored-by: Dmytro Pykhtar <37850217+dimapihtar@users.noreply.github.com> Co-authored-by: Lawrence McAfee <85179052+lmcafee-nvidia@users.noreply.github.com> Co-authored-by: NVIDIA NeMo Bot <nemo-bot@nvidia.com> Co-authored-by: Hongxiao Bai <hongxiaob@nvidia.com> Co-authored-by: Xin Yao <xiny@nvidia.com> Co-authored-by: xuwchen <xuwenc@nvidia.com> Co-authored-by: Charlie Truong <chtruong@nvidia.com> Co-authored-by: Bruno Volpato <gh@brunovolpato.com> Co-authored-by: Yuzhong Wang <yuzhongw@nvidia.com> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: Yunsheng Ni <ni-ys13@tsinghua.org.cn> Co-authored-by: Jingqin Yang <jingqiny@nvidia.com> Co-authored-by: Pingtian Li <158665726+Wohox@users.noreply.github.com> Co-authored-by: Tailai Ma <58548582+xiaoyao0115@users.noreply.github.com> Co-authored-by: CarlosGomes98 <cgomes@nvidia.com> Co-authored-by: Hongbin Liu <lhb8125@users.noreply.github.com> Co-authored-by: Fan Kun <784819644@qq.com> Co-authored-by: sophiayyya <yangjingyi0730@163.com> Co-authored-by: root <root@eos0294.eos.clusters.nvidia.com> Co-authored-by: Sophia Yang <sopyang@cw-dfw-cs-001-dc-02.cm.cluster> Co-authored-by: Deyu Fu <deyuf@nvidia.com> Co-authored-by: Sophia Yang <sopyang@cw-dfw-cs-001-vscode-01.cm.cluster> Co-authored-by: Robin Zhang <robinz@nvidia.com> Co-authored-by: janEbert <janpabloe@nvidia.com> Co-authored-by: ℍ𝕠𝕝𝕝𝕠𝕨 𝕄𝕒𝕟 <hollowman@opensuse.org> Co-authored-by: Zhongbo Zhu <42691305+zhongbozhu@users.noreply.github.com> Co-authored-by: Yunsheng Ni <yunshengn@gmail.com> Co-authored-by: Harry Zhou <67385896+harryzhou2000@users.noreply.github.com> Co-authored-by: HaochenYuan <106647990+HaochenYuan@users.noreply.github.com> Co-authored-by: hongbinl <hongbinl@nvidia.com> Co-authored-by: QiZhangNV <163500791+QiZhangNV@users.noreply.github.com> Co-authored-by: Gao Deng <160076886+gdengk@users.noreply.github.com> Co-authored-by: leikaixiang.shyoshyo <leikaixiang.shyoshyo@bytedance.com> Co-authored-by: Evgenii Zheltonozhskii <zheltonozhskiy@gmail.com> Co-authored-by: Maanu Grover <maanug@nvidia.com> Co-authored-by: Yongqiang Wang <yongqiang.seagull@gmail.com> Co-authored-by: achyuthan.s <113010327+Achyuthan-S@users.noreply.github.com> Co-authored-by: Teodor-Dumitru Ene <34819528+tdene@users.noreply.github.com> Co-authored-by: Ali Arda Eker <aeker1@binghamton.edu> Co-authored-by: Yashaswi Karnati <144376261+yashaswikarnati@users.noreply.github.com> Co-authored-by: wdykas <73254672+wdykas@users.noreply.github.com> Co-authored-by: William Dykas <wdykas@oci-hsg-cs-001-vscode-03.cm.cluster> Co-authored-by: William Dykas <wdykas@oci-nrt-cs-001-vscode-01.cm.cluster> Co-authored-by: Shijie <jaywan@nvidia.com> Co-authored-by: [Co-author Name] <coauthor.email@example.com> Co-authored-by: Jon Barker <jbarker@nvidia.com> Co-authored-by: Jon Barker <jbarker@aws-dfw-cs-001-login-01.cm.cluster> Co-authored-by: Chen Cui <chcui@nvidia.com> Co-authored-by: Laura Dang <laurad@nvidia.com> Co-authored-by: Shiqing Fan <shiqingf@nvidia.com> Co-authored-by: Jieming Zhang <jiemingz@nvidia.com> Co-authored-by: Deepak Narayanan <deepakn94@gmail.com> Co-authored-by: Jiangfei Duan <jiangfeid@nvidia.com> Co-authored-by: Philip Monk <phil@pcmonk.me> Co-authored-by: Jimmy Zhang <133159885+jiemingz@users.noreply.github.com> Co-authored-by: Xuanteng Huang <44627253+xuantengh@users.noreply.github.com> Co-authored-by: Antoni-Joan Solergibert <asolergibert@nvidia.com> Co-authored-by: Tom Long <tolong@nvidia.com> Co-authored-by: Siddhartha Raman Sundara Raman <sraman@nvidia.com> Co-authored-by: kunlunl <kunlunl@nvidia.com> Co-authored-by: Jorge Albericio <jalbericiola@nvidia.com> Co-authored-by: Teodor-Dumitru Ene <teodord.ene@gmail.com> Co-authored-by: Björn Buschkämper <bjoern.buschkaemper@gmail.com> Co-authored-by: nvcsathe <csathe@nvidia.com> Co-authored-by: Will Dykas <wdykas@nvidia.com> Co-authored-by: Philip Monk <pmonk@nvidia.com> Co-authored-by: shanmugamr1992 <shanmugamr1992@gmail.com> Co-authored-by: Ravi Ghadia <40660742+ghadiaravi13@users.noreply.github.com> Co-authored-by: Bo Li <22713281+bobboli@users.noreply.github.com>
main has no multimodal training example. MDP and the Qwen3.8-VL package build on examples/multimodal_dev, so bring it over as it stands at dev db05fc4, the tree the MDP branch (dev_mdp) was last synced to. Taking that exact state lets the MDP delta apply to the example without a second round of reconciliation. Carried from dev (examples hunks plus their tests): NVIDIA#4751 (Qwen3.5-VL training example), NVIDIA#4776 (MoE aux loss padding_mask), NVIDIA#5890, NVIDIA#5964, NVIDIA#5962 (vision RoPE fusion), NVIDIA#6277, NVIDIA#6083 (unit-test bucket for the example), NVIDIA#6611, NVIDIA#6287 (mock samples by index, tests/unit_tests/data/test_mock_qwen35vl_dataset.py), NVIDIA#6315 (HybridModel decoder), NVIDIA#6081 (pipeline parallelism), plus tests/unit_tests/models/test_qwen35_vl_specs.py. The core halves of NVIDIA#4750, NVIDIA#5962 and NVIDIA#6315 are the preceding commits. Not carried: dev changes to the example after db05fc4 (the vision-encoder FLOPs accounting of NVIDIA#6173 and later sync fixes); MDP brings its own vision FLOPs accounting. Signed-off-by: Li Tao <lit@nvidia.com>
What
Migrate the
examples/multimodal_devQwen3.5-VL language decoder fromGPTModeltoHybridModel, ahead of the deprecation of the GPTModel code path.Why
The Qwen3.5-VL decoder is a hybrid GatedDeltaNet / full-attention stack. On the
GPT path that structure was expressed implicitly through
--experimental-attention-variant gated_delta_netplus--linear-attention-freq 4, with the attention/MLP ordering baked intoTransformerLayer.HybridModelexpresses it explicitly through--hybrid-layer-pattern, which is where this model family belongs long term.Changes
Model wiring (
examples/multimodal_dev)MultimodalModel/Qwen35VLModelnow takehybrid_stack_specandhybrid_layer_patterninstead of atransformer_layer_specand anmtp_block_spec.get_qwen35_vl_language_specis removed.G)or full-attention (
*) layer followed by a dense (-) or MoE (E) MLPlayer. Three GDN blocks then one attention block reproduces the
--linear-attention-freq 4cadence exactly.get_gpt_mtp_block_spec, whichderived the MTP spec from the final decoder layer.
because
HybridModelcounts one layer per pattern symbol.mRoPE support in
HybridModel(megatron/core/models/hybrid/hybrid_model.py)MultimodalRotaryEmbeddingwhenposition_embedding_type == 'mrope'and compute sectioned (optionally raw, fused-kernel) freqs in
forward,mirroring
GPTModelline for line, including theapply_rope_fusion/rotary_interleaved/fused_single_qkv_rope/inference conditions and the flash-decode
NotImplementedError.HybridModelConfig.position_embedding_typeliteral accordingly.GatedDeltaNet (
megatron/core/ssm/gated_delta_net.py)fla.ops.cp.build_cp_contextseparately from the rest of FLA so an FLAbuild without the CP extension still enables GatedDeltaNet, and raise a
descriptive error only when chunkwise CP is actually requested.
Launcher (
scripts/run_qwen35_vl.sh)NUM_LAYERS,NUM_EXPERTSand the newMTP_NUM_LAYERSknob; pass the MTP arguments only when MTP is enabled.NUM_LAYERSneed not be a multiple of 4: trailing blocks stay GatedDeltaNet,which is what
--linear-attention-freq 4produced, so shallow proxy runs keepworking.
Tests
examples/multimodal_dev/tests/test_hybrid_migration.py— factory wiring plusstructural equivalence between the hybrid pattern and the former GPT layout.
The key check cross-validates
validate_segment_layers(hybrid) againstget_linear_attention_pattern(GPT) so a semantic drift on either side fails.tests/unit_tests/models/test_hybrid_model.py—HybridModelconstructor withposition_embedding_type='mrope'.examples/multimodal_dev/tests/test_cp_thd_correctness.py— ported to thehybrid stack spec.
Checkpoint compatibility
The decoder checkpoint layout changes: one GPT decoder layer is split across two
hybrid layer indices, the final-norm key changes, and hybrid MTP uses a nested
HybridStack. An existing GPTModel-format Qwen3.5-VL checkpoint is therefore notdirectly loadable.
tools/checkpoint/gpt_hybrid_conversion.pydoes not coverthis case either — it explicitly rejects GDN (
G) and MTP checkpoints. This isdocumented in
examples/multimodal_dev/README.md.Scope of risk
The
megatron/corechanges are additive: the mRoPE branches only run whenposition_embedding_type == 'mrope', which no existingHybridModelconfiguration uses, and the FLA import change only alters behavior on builds
that lack
fla.ops.cp. Everything else is confined toexamples/multimodal_dev.