Skip to content

[Dev] feat(multimodal): migrate Qwen3.5-VL to HybridModel - #6315

Merged
FDecaYed merged 7 commits into
NVIDIA:devfrom
BestJuly:lit/multimodal_hybrid
Sep 9, 2026
Merged

FDecaYed merged 7 commits into
NVIDIA:devfrom
BestJuly:lit/multimodal_hybrid

Conversation

@BestJuly

@BestJuly BestJuly commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

What

Migrate the examples/multimodal_dev Qwen3.5-VL language decoder from
GPTModel to HybridModel, 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_net plus
--linear-attention-freq 4, with the attention/MLP ordering baked into
TransformerLayer. HybridModel expresses it explicitly through
--hybrid-layer-pattern, which is where this model family belongs long term.

Changes

Model wiring (examples/multimodal_dev)

  • MultimodalModel / Qwen35VLModel now take hybrid_stack_spec and
    hybrid_layer_pattern instead of a transformer_layer_spec and an
    mtp_block_spec. get_qwen35_vl_language_spec is removed.
  • Each historical Qwen block becomes two hybrid layers: a GatedDeltaNet (G)
    or full-attention (*) layer followed by a dense (-) or MoE (E) MLP
    layer. Three GDN blocks then one attention block reproduces the
    --linear-attention-freq 4 cadence exactly.
  • MTP depths replicate the last block, matching get_gpt_mtp_block_spec, which
    derived the MTP spec from the final decoder layer.
  • Variant configs are converted from block counts to hybrid layer counts,
    because HybridModel counts one layer per pattern symbol.

mRoPE support in HybridModel (megatron/core/models/hybrid/hybrid_model.py)

  • Build a MultimodalRotaryEmbedding when position_embedding_type == 'mrope'
    and compute sectioned (optionally raw, fused-kernel) freqs in forward,
    mirroring GPTModel line for line, including the
    apply_rope_fusion / rotary_interleaved / fused_single_qkv_rope /
    inference conditions and the flash-decode NotImplementedError.
  • Widen the HybridModelConfig.position_embedding_type literal accordingly.

GatedDeltaNet (megatron/core/ssm/gated_delta_net.py)

  • Import fla.ops.cp.build_cp_context separately from the rest of FLA so an FLA
    build 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)

  • Derive the pattern from NUM_LAYERS, NUM_EXPERTS and the new
    MTP_NUM_LAYERS knob; pass the MTP arguments only when MTP is enabled.
  • NUM_LAYERS need not be a multiple of 4: trailing blocks stay GatedDeltaNet,
    which is what --linear-attention-freq 4 produced, so shallow proxy runs keep
    working.

Tests

  • examples/multimodal_dev/tests/test_hybrid_migration.py — factory wiring plus
    structural equivalence between the hybrid pattern and the former GPT layout.
    The key check cross-validates validate_segment_layers (hybrid) against
    get_linear_attention_pattern (GPT) so a semantic drift on either side fails.
  • tests/unit_tests/models/test_hybrid_model.py — HybridModel constructor with
    position_embedding_type='mrope'.
  • examples/multimodal_dev/tests/test_cp_thd_correctness.py — ported to the
    hybrid 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 not
directly loadable. tools/checkpoint/gpt_hybrid_conversion.py does not cover
this case either — it explicitly rejects GDN (G) and MTP checkpoints. This is
documented in examples/multimodal_dev/README.md.

Scope of risk

The megatron/core changes are additive: the mRoPE branches only run when
position_embedding_type == 'mrope', which no existing HybridModel
configuration uses, and the FLA import change only alters behavior on builds
that lack fla.ops.cp. Everything else is confined to examples/multimodal_dev.

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>
@copy-pr-bot

copy-pr-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

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.

@BestJuly BestJuly changed the title feat(multimodal): migrate Qwen3.5-VL to HybridModel [Dev] feat(multimodal): migrate Qwen3.5-VL to HybridModel Aug 7, 2026
@QiZhangNV

Copy link
Copy Markdown
Contributor

While reviewing this migration, I noticed that the configured position embedding type does not match the model that is actually constructed.

run_qwen35_vl.sh sets --position-embedding-type rope, while Qwen35VLModel ignores that configuration and unconditionally constructs the decoder with position_embedding_type="mrope". The runtime model therefore uses MRoPE, but the parsed arguments and checkpoint metadata describe ordinary RoPE. Configuration-driven tooling such as checkpoint converters, exporters, or generic model builders could consequently reconstruct the wrong decoder architecture.

This cannot be fixed by changing the recipe to --position-embedding-type mrope alone. The earlier MTP validation in arguments.py only accepts rope and none, so it rejects mrope, while the later validation explicitly lists mrope as supported. Please consolidate these two validation paths and make the recipe, model construction, and checkpoint metadata consistently describe the decoder as using mrope.

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(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we pass cp_group to mrope like other PEs?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think is_hybrid_model also need to be set.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed and have set this, and also deleted linear_attention_freq to match the logic.

@hxbai

hxbai commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

/claude strict-review

Comment on lines +339 to +346
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,
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

  1. Correctness under a custom pg_collection. HybridModel accepts pg_collection precisely so a caller can supply process groups that are not the parallel_state globals. Here the CP group is silently taken from the global MPU state instead. MultimodalRotaryEmbedding.forward uses self.cp_group for get_pos_emb_on_this_cp_rank(...) whenever the per-call cp_group is None — and this model's forward passes cp_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 on self.cp_group. If the injected pg_collection.cp differs from the global CP group, the mRoPE frequencies get zigzag-sliced for the wrong rank — silently wrong positions, not a crash. check_initialized=False also means an uninitialized MPU yields None, which turns CP slicing off entirely rather than erroring.

  2. Repo guidance. Per CLAUDE.md, new megatron/core production code should not introduce reads of global parallel_state process 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 as self.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.

Suggested change
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,
)

Comment on lines +918 to +921
# 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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Comment on lines +65 to +71
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."
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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-section must match MROPE_SECTION in ..."
  • README.md:61 — "also match MROPE_SECTION in models/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.

Comment on lines +316 to +318
# Architecture. HybridModel counts one layer per pattern symbol, so each
# Qwen block ('G'/'*' plus '-'/'E') contributes two layers.
num_layers=2 * v["num_layers"],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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's get_linear_attention_pattern consumer is not reached — HybridModel builds a HybridStack from hybrid_layer_pattern.
  • transformer_config.py:1768 explicitly skips the linear_attention_freq is not None assertion when is_hybrid_model.
  • The FLOPs path takes the hybrid branch (training.py:1281, via get_hybrid_layer_counts), not the linear_attention_freq branch.

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.

Comment on lines +468 to +476
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SUGGESTION Simplification]

What: two small clarity issues in the expansion loop.

  1. 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 when NUM_LAYERS=0, in which case the MTP loop would emit MTP blocks for a zero-layer decoder anyway.

  2. The MTP loop consumes ATTN_LAYER_SYMBOL as leaked from the decoder loop's last iteration. That happens to be correct — GPT's get_gpt_mtp_block_spec does copy.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}"
done

Pass 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 FDecaYed left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@FDecaYed
FDecaYed added this pull request to the merge queue Sep 9, 2026
Merged via the queue into NVIDIA:dev with commit b001dac Sep 9, 2026
93 of 94 checks passed
BestJuly added a commit to BestJuly/Megatron-LM that referenced this pull request Sep 23, 2026
* 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>
BestJuly added a commit to BestJuly/Megatron-LM that referenced this pull request Oct 30, 2026
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>

This branch was previously deployed

2 inactive deployments
public — e9927943 Deployed Sep 7, 2026 by copy-pr-bot[bot] via finalize / publish-docs #8335
test — e9927943 Deployed Sep 7, 2026 by copy-pr-bot[bot] via cicd-wait-in-queue #20995
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants