feat: Kimi Delta Attention (KDA) attention variant, and configurable mHC input-norm epsilon - #7427
Closed
erictang000 wants to merge 2 commits into
Closed
erictang000 wants to merge 2 commits into
erictang000 wants to merge 2 commits into
Conversation
HyperConnectionModule normalizes the flattened residual streams as x / (rms(x) + eps) with eps hard-coded to 1e-6. Models trained with a standard RMSNorm in that position -- x * rsqrt(mean(x^2) + eps) -- cannot be loaded into mHC as it stands. GLM-5.3-Flash is one: it uses rms_norm_eps (1e-5) inside the square root. The two forms agree for O(1) activations but not for small residual streams. GLM-5.3-Flash's embeddings have a per-token rms below sqrt(1e-5), where the placement of the epsilon changes the mixing weights materially, so this is not a tolerance that can be absorbed. Adds two TransformerConfig fields: - mhc_norm_eps (default 1e-6) -- the epsilon itself, previously a literal in __init__. - mhc_norm_eps_inside_sqrt (default False) -- selects the standard-RMSNorm form via a new native_proj_rms_eps_inside_sqrt op. Both defaults reproduce today's behavior exactly. The fused mHC kernels implement the paper form only, so use_fused_mhc with mhc_norm_eps_inside_sqrt=True is rejected in __post_init__ rather than silently ignored. tests/unit_tests/transformer/test_hyper_connection_norm_eps.py covers both forms against their closed-form reference, the config guard, and the small-scale regime that motivates the knob. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
KDA (Kimi Linear, arXiv:2510.26692) is a gated delta rule whose forget gate is per channel rather than per head. It is the linear-attention layer of Kimi Linear and of GLM-5.3-Flash, which uses it for 3 of every 4 layers. megatron/core/ssm/kda.py adds KimiDeltaAttention next to the gated delta net family, and the experimental-attention-variant machinery gains a "kda" name alongside "gdn"/"gdn2": is_linear_attention_variant now covers it, so the existing linear_attention_freq pattern and hybrid block builder drive it unchanged. Unlike GDN, KDA keeps its projections separate rather than fusing them into one in_proj -- that is the layout its reference checkpoints ship in, and keeping it means an HF bridge maps 1:1. Consequently the input layernorm is not fused into the first linear (fuse_input_layernorm=False). Tensor parallelism shards heads: q/k/v/f_b/g_b/b are column-parallel, the three depthwise causal convolutions and the fp32 A_log/dt_bias are split along the head dimension, the low-rank f_a/g_a down-projections are duplicated, and o_proj is row-parallel. The replicated o_norm weight is marked sequence_parallel so its gradient is summed across the TP group. Packed sequences (qkv_format="thd") go through cu_seqlens. sharded_state_dict follows GDN. Geometry reuses the shared linear_* config fields (KDA requires the q/k and v head counts and head dimensions to be equal, which __post_init__ enforces), plus a new kda_gate_lower_bound: when set the log-decay is bounded to [lower_bound, 0) via lower_bound * sigmoid(exp(A_log) * (f + dt_bias)) -- GLM-5.3-Flash uses -5.0 -- and the default None keeps the unbounded -exp(A_log) * softplus(f + dt_bias) gate of the original Kimi Linear. Not supported: context parallelism and inference caches, both of which raise. tests/unit_tests/ssm/test_kda.py checks a packed two-sequence forward against the HuggingFace glm5_next reference layer in bf16. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5 tasks
Author
|
close in favor of #7054 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds Kimi Delta Attention (KDA) as
experimental_attention_variant="kda", and makes the mHC input-normalization epsilon placement configurable. Together these are the two megatron-core pieces needed to build GLM-5.3-Flash (HFglm5_next) out of mcore components; the companion NVIDIA-NeMo/Megatron-Bridge#6137 adds the provider/spec/bridge on top and is blocked on this PR.Issue tracking
Linked issue: not yet filed — happy to open a feature request if the team wants one before review.
The two changes
1.
feat(mhc): configurable input-normalization epsilon placementHyperConnectionModulenormalizes the flattened residual streams asx / (rms(x) + eps)withepshard-coded to1e-6. Models trained with a standard RMSNorm in that position —x * rsqrt(mean(x^2) + eps)— cannot be loaded into mHC as it stands.The two forms agree for O(1) activations but not for small residual streams. GLM-5.3-Flash uses
rms_norm_eps(1e-5) inside the square root and its embeddings have a per-token rms belowsqrt(1e-5), where the placement of the epsilon changes the mixing weights materially — not a tolerance that can be absorbed.Two
TransformerConfigfields:mhc_norm_eps1e-6__init__mhc_norm_eps_inside_sqrtFalsenative_proj_rms_eps_inside_sqrtopBoth defaults reproduce today's behavior exactly. The fused mHC kernels implement the paper form only, so
use_fused_mhctogether withmhc_norm_eps_inside_sqrt=Trueis rejected in__post_init__rather than silently ignored.2.
feat(ssm):KimiDeltaAttentionKDA (Kimi Linear, arXiv:2510.26692) is a gated delta rule whose forget gate is per channel rather than per head:
megatron/core/ssm/kda.pyadds the module next to the gated delta net family;is_linear_attention_variantnow covers"kda", so the existinglinear_attention_freqpattern and the hybrid block builder drive it unchanged.in_proj. That is the layout its reference checkpoints ship in, and keeping it means an HF bridge maps 1:1. Consequentlyfuse_input_layernorm=False. Open to folding this onto_GDNBaseinstead if you'd prefer one code path — it would cost the checkpoint-layout correspondence.q/k/v/f_b/g_b/bcolumn-parallel; the three depthwise causal convolutions and the fp32A_log/dt_biassplit along the head dimension; the low-rankf_a/g_adown-projections duplicated;o_projrow-parallel. The replicatedo_normweight is markedsequence_parallelsofinalize_model_gradssums its gradient across the TP group.qkv_format="thd") go throughcu_seqlens.sharded_state_dictfollows GDN.linear_*fields — KDA requires the q/k and v head counts and head dimensions to be equal, enforced in__post_init__— plus a newkda_gate_lower_bound. Setting it bounds the log-decay to[lower_bound, 0)(GLM-5.3-Flash uses-5.0); the defaultNonekeeps the unbounded-exp(A_log) * softplus(f + dt_bias)gate of the original Kimi Linear.Validation
Run against this branch on a single B300, torch 2.13, TE from the same toolchain:
tests/unit_tests/ssm/test_kda.py(new)glm5_nextreference layer in bf16tests/unit_tests/transformer/test_hyper_connection_norm_eps.py(new)tests/unit_tests/transformer/test_hyper_connection_recompute.py+test_mhc_block_manager.py(existing)hyper_connection.pychangeBoth modules were also validated end-to-end in their out-of-tree form (same code, carried against
b3393bbb) as part of a GLM-5.3-Flash bring-up: Megatron vs. HFtransformerslogits on the 4-layer GLM-5.3-Flash slice came out at the bf16 noise floor (KL 0.0082, 91.5% argmax at TP1, against a measured HF-bf16-vs-fp32 floor of 0.0071 / 95.7%), and a vLLM↔Megatron logprob round-trip on 4×H100 at TP2/EP4 matched to 0.064 mean absolute logprob. Details: NovaSky-AI/SkyRL#2179.Contribution process
Pre-checks
jit_fuser/torch.compile, CUDA extension, TE or external-library dispatch, or a scatter/index accumulation), I have added or updated its bit-exact determinism test and registered it intests/unit_tests/determinism/kernels/manifest.py— please advise:native_proj_rms_eps_inside_sqrtis a newtorch.compileop and KDA dispatches tofla'schunk_kda, so this likely applies; I did not want to guess at the manifest entries.kda.py)megatron/corefiles)Known gaps
🤖 Generated with Claude Code