Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
139b583
Prepare the Gated DeltaNet base for channel-wise variants
fkuner Aug 17, 2026
da9d990
Add Kimi Delta Attention to hybrid models
fkuner Aug 17, 2026
b382bfe
Honor GDN projection metadata in FSDP checkpoints
fkuner Aug 15, 2026
1f34327
Add head-wise output gating to MLA
fkuner Aug 15, 2026
dc1ca15
Include nested MTP modules in QK clipping
fkuner Aug 15, 2026
98d52cf
Add a Ling-V3 Tiny hybrid model spec
fkuner Aug 15, 2026
f4cafaf
Add a Ling-V3 Tiny pretraining example
fkuner Aug 15, 2026
94b5ca0
Account for KDA and MLA in training metrics
fkuner Aug 15, 2026
824ca51
Fix Hybrid MTP z-loss metric indexing
fkuner Aug 17, 2026
e069d17
Add Ling-V3 Tiny functional regression
fkuner Aug 15, 2026
e239b61
Apply suggestions from code review
fkuner Aug 20, 2026
8c73427
Rename Ling-V3 Tiny functional test
fkuner Aug 20, 2026
344b270
Fix MLA output gate compilation and tests
fkuner Aug 20, 2026
40f0423
Validate GDN norm recompute for hybrid models
fkuner Aug 20, 2026
f6eba65
Tighten MLA output gate VJP tolerance
fkuner Aug 20, 2026
8ebbc56
Validate KDA safe-gate bounds
fkuner Aug 21, 2026
f709ee9
refactor: Align KDA structure with GatedDeltaNet
yuzhongw-nvidia Aug 21, 2026
1a07060
feat: Add attention output gate granularity
yuzhongw-nvidia Aug 21, 2026
de28a82
Remove Ling-specific onboarding artifacts
fkuner Aug 22, 2026
ef8e9af
Remove FSDP DTensor support from Ling onboarding
fkuner Aug 22, 2026
a7c70aa
Use the generic Hybrid spec in functional coverage
fkuner Aug 22, 2026
0e06b45
Refine KDA and hybrid FLOPs test contracts
fkuner Aug 22, 2026
c723eba
Correct MLA headwise gate VJP reference
fkuner Aug 22, 2026
7a31ac0
Correct KDA source attribution
fkuner Aug 23, 2026
8ff5307
Update megatron/training/training.py
fkuner Aug 24, 2026
c7f07f7
Update megatron/core/transformer/multi_latent_attention.py
fkuner Aug 24, 2026
de4b538
Fix hybrid layer count doctest examples
fkuner Aug 24, 2026
e51cb51
Fix Ling-V3 Tiny CI assertions
fkuner Aug 24, 2026
2e6d0a6
Remove unused KDA parameter markers
fkuner Aug 24, 2026
daddbfc
chore: preserve current inference context while applying KDA
svcnemo-autobot Aug 27, 2026
18a826f
Merge main into chore/cherrypick-14e28c6e-to-main-v2
svcnemo-autobot Aug 27, 2026
8b36b00
fix(ci): secure mamba recipe credentials
svcnemo-autobot Aug 28, 2026
88a24d5
fix: adapt Ling-V3 imports to main
svcnemo-autobot Aug 28, 2026
bc17ee5
fix: restrict legacy checkpoint deserialization
svcnemo-autobot Aug 28, 2026
f205386
style: format gated delta net CP checks
svcnemo-autobot Aug 29, 2026
91f6f85
Merge commit '21bbbe616db4858d46f348d6224bb56c5ddae1f7' into chore/ch…
svcnemo-autobot Aug 29, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions megatron/core/inference/contexts/dynamic_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,8 @@ def __init__(self, model_config: TransformerConfig, inference_config: InferenceC
attention_layer_map, dsa_layer_map = operator.itemgetter(
Symbols.ATTENTION, Symbols.DS_ATTENTION
)(get_layer_maps_from_layer_type_list(mamba_inference_state_config.layer_type_list))
if Symbols.KDA in mamba_inference_state_config.layer_type_list:
raise NotImplementedError("KDA layers are not supported for inference.")
recurrent_layer_map = {}
for global_layer_idx, layer_type in enumerate(
mamba_inference_state_config.layer_type_list
Expand Down
15 changes: 15 additions & 0 deletions megatron/core/model_parallel_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@
import torch


def _parse_pad_packed_seq_alignment(value):
"""Parse THD packed-sequence padding alignment."""
if value == "max":
return value
try:
alignment = int(value)
except (TypeError, ValueError) as exc:
raise ValueError(
"pad_packed_seq_alignment must be 'max' or a positive integer alignment."
) from exc
if alignment <= 0:
raise ValueError("pad_packed_seq_alignment must be 'max' or a positive integer alignment.")
return alignment


def resolve_tensor_parallel_weight_shards(
tensor_model_parallel_size: int,
tensor_parallel_num_weight_shards: Optional[int],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.

import warnings
from typing import List, Optional

from megatron.core.fusions.fused_bias_dropout import get_bias_dropout_add
from megatron.core.models.backends import BackendSpecProvider
from megatron.core.ssm.gated_delta_net import GatedDeltaNet, GatedDeltaNet2, GatedDeltaNetSubmodules
from megatron.core.ssm.gated_delta_net import (
GatedDeltaNet,
GatedDeltaNetSubmodules,
KimiDeltaAttention,
KimiDeltaAttentionSubmodules,
)
from megatron.core.transformer.enums import AttnMaskType, LayerType
from megatron.core.transformer.experimental_attention_variant.absorbed_mla import (
AbsorbedMLASelfAttention,
Expand All @@ -19,6 +24,7 @@
is_dsa_skip_topk_layer,
source_dsa_compute_layer,
)
from megatron.core.transformer.hyper_connection import HyperConnectionModule
from megatron.core.transformer.identity_op import IdentityOp
from megatron.core.transformer.spec_utils import ModuleSpec
from megatron.core.transformer.transformer_block import (
Expand All @@ -27,6 +33,7 @@
)
from megatron.core.transformer.transformer_config import TransformerConfig
from megatron.core.transformer.transformer_layer import (
HyperConnectionTransformerLayer,
MlpBuilder,
TransformerLayer,
TransformerLayerSubmodules,
Expand Down Expand Up @@ -58,7 +65,7 @@
##########

# Canonical ``experimental_attention_variant`` names served by the gated delta net family.
GDN_ATTENTION_VARIANTS = ("gdn", "gdn2")
GDN_ATTENTION_VARIANTS = ("gdn", "kda")

# Deprecated ``experimental_attention_variant`` spellings mapped to their canonical name.
_DEPRECATED_ATTENTION_VARIANT_ALIASES = {"gated_delta_net": "gdn"}
Expand All @@ -72,25 +79,33 @@
def get_gated_delta_net_module_spec(
config: TransformerConfig, backend: BackendSpecProvider = None
) -> ModuleSpec:
"""Build module spec for GatedDeltaNet attention."""
"""Build a module spec for a GDN-family attention variant."""

if backend is None:
backend = _get_backend_spec_provider(config=config)

rms_norm = config.normalization == "RMSNorm"
# gdn2 reuses the GDN submodules and spec structure with the GatedDeltaNet2 module.
gdn_module = (
GatedDeltaNet2 if config.experimental_attention_variant == "gdn2" else GatedDeltaNet
)
attention = ModuleSpec(
module=gdn_module,
submodules=GatedDeltaNetSubmodules(
in_proj=backend.column_parallel_layer_norm_linear(),
out_norm=backend.layer_norm(rms_norm=rms_norm, for_qk=False),
out_proj=backend.row_parallel_linear(),
),
metainfo={"fuse_input_layernorm": True},
)
if config.experimental_attention_variant == "kda":
attention = ModuleSpec(
module=KimiDeltaAttention,
submodules=KimiDeltaAttentionSubmodules(
in_proj=backend.column_parallel_linear(),
beta_proj=backend.column_parallel_linear(),
out_norm=backend.layer_norm(rms_norm=rms_norm, for_qk=False),
out_proj=backend.row_parallel_linear(),
),
metainfo={"fuse_input_layernorm": False},
)
else:
attention = ModuleSpec(
module=GatedDeltaNet,
submodules=GatedDeltaNetSubmodules(
in_proj=backend.column_parallel_layer_norm_linear(),
out_norm=backend.layer_norm(rms_norm=rms_norm, for_qk=False),
out_proj=backend.row_parallel_linear(),
),
metainfo={"fuse_input_layernorm": True},
)
return attention


Expand Down Expand Up @@ -245,6 +260,10 @@ def get_transformer_layer_with_experimental_attention_variant_spec(

# Get GPT decoder block layer specs
rms_norm = config.normalization == "RMSNorm"
enable_hc = config.enable_hyper_connections
hc_module = HyperConnectionModule if enable_hc else IdentityOp
layer_module = HyperConnectionTransformerLayer if enable_hc else TransformerLayer

layer_specs = []
for layer_number in range(config.num_layers):
attention = (
Expand All @@ -271,14 +290,16 @@ def get_transformer_layer_with_experimental_attention_variant_spec(

layer_specs.append(
ModuleSpec(
module=TransformerLayer,
module=layer_module,
submodules=TransformerLayerSubmodules(
input_layernorm=input_layernorm,
self_attention=attention,
self_attn_bda=get_bias_dropout_add,
self_attention_hyper_connection=hc_module,
pre_mlp_layernorm=pre_mlp_layernorm,
mlp=not_none(mlp),
mlp_bda=get_bias_dropout_add,
mlp_hyper_connection=hc_module,
),
)
)
Expand Down Expand Up @@ -349,19 +370,7 @@ def get_transformer_block_with_experimental_attention_variant_spec(
def normalize_experimental_attention_variant(
experimental_attention_variant: Optional[str],
) -> Optional[str]:
"""Resolve a deprecated ``experimental_attention_variant`` spelling to its canonical name.

``gated_delta_net`` is the deprecated spelling of ``gdn``. Passing it emits a
``DeprecationWarning`` and returns the canonical name so that every downstream
consumer only has to handle ``gdn``.

Args:
experimental_attention_variant: The configured variant name, possibly a
deprecated alias.

Returns:
The canonical variant name, or the argument unchanged when it is not an alias.
"""
"""Resolve a deprecated attention-variant spelling to its canonical name."""
canonical = _DEPRECATED_ATTENTION_VARIANT_ALIASES.get(experimental_attention_variant)
if canonical is None:
return experimental_attention_variant
Expand All @@ -376,11 +385,7 @@ def normalize_experimental_attention_variant(


def is_gated_delta_net_variant(experimental_attention_variant: Optional[str]) -> bool:
"""Check if the experimental attention variant is served by a gated delta net layer.

Accepts the deprecated ``gated_delta_net`` spelling without warning; use
:func:`normalize_experimental_attention_variant` to emit the deprecation notice.
"""
"""Return whether a name selects a GDN-family attention implementation."""
canonical = _DEPRECATED_ATTENTION_VARIANT_ALIASES.get(
experimental_attention_variant, experimental_attention_variant
)
Expand Down Expand Up @@ -501,7 +506,7 @@ def _get_backend_spec_provider(config: TransformerConfig) -> BackendSpecProvider
)
backend: BackendSpecProvider = (
KitchenSpecProvider(
fallback=TESpecProvider(),
fallback=TESpecProvider(fallback_to_eager_attn=config.fallback_to_eager_attn),
use_kitchen_attention=config.use_kitchen_attention,
kitchen_attention_backend=config.kitchen_attention_backend,
)
Expand Down Expand Up @@ -537,6 +542,7 @@ def _get_self_attention_module_spec(
qk_l2_norm=config.qk_l2_norm,
use_kitchen=config.use_kitchen,
use_te_activation_func=config.use_te_activation_func,
fallback_to_eager_attn=config.fallback_to_eager_attn,
use_kitchen_attention=config.use_kitchen_attention,
kitchen_attention_backend=config.kitchen_attention_backend,
mla_down_proj_fusion=getattr(config, "mla_down_proj_fusion", False),
Expand Down
3 changes: 3 additions & 0 deletions megatron/core/models/gpt/gpt_layer_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ def get_gpt_layer_with_inference_submodules(
linear_kv_down_proj=backend.linear(),
linear_kv_up_proj=linear_kv_up_proj,
core_attention=backend.core_attention(),
linear_gate=backend.column_parallel_linear(),
linear_proj=backend.row_parallel_linear(),
q_layernorm=IdentityOp,
kv_layernorm=IdentityOp,
Expand Down Expand Up @@ -304,6 +305,7 @@ def get_gpt_layer_with_transformer_engine_submodules(
linear_kv_down_proj=backend.linear(),
linear_kv_up_proj=linear_kv_up_proj,
core_attention=backend.core_attention(),
linear_gate=backend.column_parallel_linear(),
linear_proj=backend.row_parallel_linear(),
q_layernorm=IdentityOp,
kv_layernorm=IdentityOp,
Expand Down Expand Up @@ -424,6 +426,7 @@ def get_gpt_layer_local_submodules(
linear_kv_down_proj=backend.column_parallel_linear(),
linear_kv_up_proj=backend.column_parallel_linear(),
core_attention=backend.core_attention(),
linear_gate=backend.column_parallel_linear(),
linear_proj=backend.row_parallel_linear(),
q_layernorm=qk_norm if qk_layernorm else IdentityOp,
kv_layernorm=qk_norm if qk_layernorm else IdentityOp,
Expand Down
Loading
Loading