[dev] feat(moe): Add KDA Low-Rank Projections and Extend MLA Support - #6877
yuzhongw-nvidia wants to merge 12 commits into
Conversation
397665d to
cd063dc
Compare
|
/claude review |
|
Light review. One likely bug (posted inline) plus two smaller notes; the rest looks solid — the legacy-fused path is preserved bit-for-bit and the FLOPs formula reduces to the old one when both ranks are 1. 2. FP8 alignment is only asserted for the fused projection. if self.fp8:
fp8_align_size = get_fp8_align_size(self.fp8_recipe)
for field_name in ("kda_f_lora_rank", "kda_gate_lora_rank"):
rank = getattr(self, field_name)
if rank is not None and rank % fp8_align_size != 0:
raise ValueError(
f"KDA requires {field_name} to be a multiple of {fp8_align_size} "
f"under FP8, got {rank}."
)3. No Nit: |
76ef545 to
6f9e6bd
Compare
|
/claude review |
|
/ok to test 6f9e6bd |
6f9e6bd to
1112f08
Compare
There was a problem hiding this comment.
Light review. The KDA low-rank work is well-structured — the _get_in_proj_dim hook, the legacy-fused checkpoint preservation, and the parametrized test coverage across all four rank combinations are all solid. Three things flagged inline, plus notes below.
Blocking
Circular import (transformer_config.py:14). fp8_utils already imports transformer_config at module level, so the new top-level from megatron.core.fp8_utils import get_fp8_align_size closes the cycle. Installation Test and both build-and-test-wheels jobs are currently red, which is consistent with this. Deferring the import into __post_init__ matches how the rest of the tree handles it.
Worth a look
tp_comm_buffer_name collision (kda.py:118, kda.py:182) — f_proj and g_proj reuse "fc1", already claimed by in_proj.
Unconditional LayerNorm in hybrid MLA specs (hybrid_layer_specs.py) — the TEColumnParallelLinear → TELayerNormColumnParallelLinear swap isn't gated on qk_layernorm, and q_layernorm/kv_layernorm stay IdentityOp, so this adds a norm rather than fusing an existing one. Details inline.
Test coverage
no_rope for MLA has a forward-shape test, but it doesn't assert the no-RoPE path is numerically distinct. The use_rope=False branch at multi_latent_attention.py:1002-1021 concatenates q_pos_emb / k_pos_emb unrotated, so a cheap regression guard would be to build a second layer with no_rope_freq=[0, 0], copy weights across, and assert the outputs differ. As written, the test would still pass if the branch accidentally applied RoPE.
Also, the low-rank projections are only exercised by unit tests. hybrid_mr_mcore_te_tp1_pp1_ep8_cp2_kda_gated_mla_1N8G still runs with the legacy fused layout, so the new path gets no functional/ckpt-resume coverage. Given the two distinct checkpoint layouts this PR introduces, a --kda-f-lora-rank variant of that recipe would be valuable.
Minor
Two unrelated parenthesis-stripping edits in training.py (lines ~4945, ~5243) are outside the PR's stated scope — docs/developer/contribute.md asks contributors not to touch formatting in code unrelated to the change.
1112f08 to
66c6205
Compare
|
/ok to test 66c6205 |
|
Light review — the KDA low-rank plumbing and MLA NoPE changes look sound overall, and unit coverage for the new rank combinations is thorough. No new direct 1. Contradictory NoPE handling for cached MLA latents — flagged inline at 2. Spec wiring for the 6 new submodules is untested. Relatedly, |
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
c1ee20d to
1c658da
Compare
|
/claude review |
There was a problem hiding this comment.
Light review. The three features are cleanly separated and the parametrized test matrices are good — test_parallel_kda_correctness covering all four low-rank combinations across TP/SP/CP with a dist-ckpt round trip is exactly the right coverage for the new projections, and the FLOPs formula is legacy-equivalent (the refactored projection_flops expands to the old hidden_size * (in_proj_dim + num_qk_heads) + hidden_size * v_dim when both ranks are None).
Two comments left inline:
common.py— hard-codingact_fn = siluin the shared base also changesGatedDeltaNet, and only KDA gets an assertion for it.kda.py— the new FP8 rank-alignment guard (and therank <= 0guards inkda_layer_flops) are untested.
Both are minor; no blocking issues found.
One thing I checked and it's fine: f_a_proj/g_a_proj use parallel_mode="duplicated" without passing tp_group, which satisfies TELinear's assert tp_group is None and routes their dist-ckpt through the replicated TELinear.sharded_state_dict path.
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com> (cherry picked from commit 2794e4b)
|
/claude review |
There was a problem hiding this comment.
Light review — the production changes look correct to me. te_checkpoint usage in gdn.py/kda.py matches the established FP8/FP4 selective-recompute pattern in transformer_layer.py/moe_layer.py (signature and active_pg_collection.tp are right), the legacy vs. low-rank in_proj split names/sections stay consistent with common.py's sharded_state_dict width assertion, the FLOPs plumbing into kda_layer_flops/hybrid_flops is correct, and no new global parallel_state.get_*_group() reads are introduced.
Two test-coverage nits:
1. test_gdn_recompute_mxfp8_backward_has_main_grad asserts nothing (tests/unit_tests/test_muon_decouple_fp8_param_gather.py)
The name and docstring promise a main_grad check, but the body ends at self._run_steps(args, model, optimizer, 1). Since _run_steps only collects grads where p.main_grad is not None, a regression that drops main_grad on recomputed GDN/KDA params would pass silently. Something like:
self._run_steps(args, model, optimizer, 1)
gdn_params = [
(name, param)
for module in model
for name, param in module.named_parameters()
if "mixer" in name and param.requires_grad
]
assert gdn_params, "no GDN/KDA parameters found in the model"
missing = [name for name, param in gdn_params if getattr(param, "main_grad", None) is None]
assert not missing, f"GDN/KDA parameters missing main_grad after backward: {missing}"(adjust the name filter to whatever actually matches the GDN/KDA submodule for this hybrid pattern).
2. The six new KDA submodule wirings have no spec-level assertion
TestGetGatedDeltaNetModuleSpec::test_kda_uses_direct_projection_submodules in tests/unit_tests/models/test_experimental_attention_variant_module_specs.py still only checks in_proj/beta_proj, so a regression in the new f_proj/f_a_proj/f_b_proj/g_proj/g_a_proj/g_b_proj wiring (or the linear() vs column_parallel_linear() choice for the duplicated *_a_proj path) would not be caught there. Worth extending that assertion, and mirroring it for hybrid_layer_specs.py.
…VIDIA#6877 Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
…VIDIA#6877 Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
Remove the ineffective MXFP8 recompute regression and its dedicated hybrid-model plumbing. Extend the existing KDA spec test to assert all low-rank and full-rank projection modules in both GPT and hybrid specs. Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
0ac2f30 to
ee65046
Compare
|
/claude review |
1 similar comment
|
/claude review |
Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
ee65046 to
e122279
Compare
…VIDIA#6877 Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
…VIDIA#6877 Signed-off-by: Yuzhong Wang <yuzhongw@nvidia.com>
What does this PR do?
Issue tracking
For PRs from open-source community contributors:
Linked issue:
Contribution process
Pre-checks
Code review
Feel free to message or comment @NVIDIA/mcore-oncall to help accelerate your merge into main. The less complex your PR is, the faster it will be approved and merged!
All PRs start as draft. If you open a non-draft PR, it will be automatically converted to draft.
Step 1: Mark PR as "Ready for Review"
.github/CODEOWNERS.Final Review might get declined if these requirements are not fulfilled.
Step 2: Final Review
For PRs that change
megatron/core, once all expert reviewers have approved, theFinal Reviewlabel is applied automatically and final reviewers are assigned.For PRs outside
megatron/core, this step is skipped.Step 3: Approved
Once all required reviewers have approved, the
Approvedlabel is applied automatically.Merge
Any member of mcore-engineers will be able to merge your PR.