Skip to content

Add config-selectable MLA draft attention - #758

Open
maocheng23 wants to merge 2 commits into
sgl-project:mainfrom
maocheng23:agent/general-mla-draft-attention
Open

Add config-selectable MLA draft attention#758
maocheng23 wants to merge 2 commits into
sgl-project:mainfrom
maocheng23:agent/general-mla-draft-attention

Conversation

@maocheng23

@maocheng23 maocheng23 commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add config-selectable Multi-head Latent Attention to the DFlash-family draft backbone: dflash_config.attention_mode: "mla" keeps the existing DFlashDraftModel, DominoDraftModel, or DSparkDraftModel architecture and swaps only the attention projections; omitting the option preserves the current GQA path
  • support the standard MLA projection fields (optional low-rank Q, shared compressed KV latent), partial interleaved or NeoX RoPE selected by the standard rope_interleave field, and DeepSeek YaRN mscale_all_dim logit scaling
  • preserve the DFlash-family target-context injection, full/sliding masks, objectives, capture contract, and eager/SDPA/FlexAttention backend selection

MLA is wired exactly the way gqa/mha already are — family-local, selected per mode inside the shared decoder layer — and every MLA parameter is a standard top-level HF config field: the mode introduces no new behavioral knobs.

Structure (two commits)

  1. refactor(dflash): extract shared attention scaffold — pure code motion, no behavior change: Qwen3DFlashAttentionBase owns everything the modes must agree on (KV-cache updates, flex/eager/sdpa backend dispatch including the SPECFORGE_FLEX_ATTENTION_BACKEND override, fully-masked-query zeroing, output projection); Qwen3DFlashAttention keeps its name, constructor, and state-dict keys and implements only _init_projections/_compute_qkv. The subclass contract (scaling, num_key_value_groups, o_proj) is documented and asserted at init.
  2. Add config-selectable MLA draft attention — additive: this commit does not touch the scaffold or the GQA class again (its only deletions in dflash.py are the decoder-layer class lookup and the model-level rotary dim).

Details:

  • attention_mode has a single source of truth (resolve_dflash_attention_mode + _DFLASH_ATTENTION_CLASSES); DSpark imports it instead of re-declaring the mode set, and "mha" now enforces equal query/KV head counts for every family (previously only DSpark checked this)
  • the rotary embedding stays model-level: DFlashDraftModel builds it with the mode-appropriate dim (qk_rope_head_dim under MLA) and all modes consume the same position_embeddings pipeline
  • MLA dimension validation runs once at model init, next to the existing resolve_dflash_attention_layout boundary, and CPU-side in apply_dflash_overrides before GPU allocation

Docs note the serving boundary explicitly: MLA is a training-side mode (train, spec_generate, export --to hf); SGLang serving of DFlash-family drafts currently implements the GQA/MHA layout only, so the export gate rejects MLA.

Validation

  • pre-commit: all hooks passed
  • commit 1 alone passes the full pre-existing tests/test_modeling suite unchanged (46 passed, 4 skipped, 15 subtests) — the scaffold extraction is behavior-preserving
  • branch tip: tests/test_modeling 63 passed, 5 skipped, 24 subtests — test_dflash_mla.py covers eager↔SDPA parity with grads, hand-computed RoPE reference values for both conventions, asymmetric-K/V-dim caching, an MLA spec_generate decode smoke test, the DSpark MLA head-count-policy bypass, and MHA head-count enforcement
  • tests/test_runtime/test_model_loading.py + test_disaggregated_model_loading.py + tests/test_scripts/test_gate_orchestration.py: 27 passed, 8 subtests
  • tested with the repository-pinned Transformers 5.8.1 and PyTorch 2.11.0; the CUDA FlexAttention forward/backward case needs a GPU re-run on this revision since the flex path routes through the shared compile_friendly_flex_attention dispatch

🤖 Generated with Claude Code

@maocheng23
maocheng23 force-pushed the agent/general-mla-draft-attention branch from 62e64fa to 4b72534 Compare August 21, 2026 01:02
@maocheng23
maocheng23 marked this pull request as ready for review August 21, 2026 07:11
maocheng23 and others added 2 commits August 24, 2026 20:03
Split Qwen3DFlashAttention into Qwen3DFlashAttentionBase (KV-cache updates,
eager/sdpa/flex backend dispatch, fully-masked-query zeroing, output
projection) and a projection-only subclass. Pure code motion: state-dict
keys, construction signature, and forward behavior are unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dflash_config.attention_mode: "mla" swaps only the attention projections
inside the shared DFlash-family decoder layer; gqa (default) and mha keep
the existing class. The MLA subclass implements the standard DeepSeek
parameterization: optional low-rank Q, shared compressed KV latent, partial
RoPE with the convention taken from the standard rope_interleave field, and
YaRN mscale_all_dim logit scaling. Structural dims use the standard
top-level HF fields; validation runs once at model init and CPU-side in
apply_dflash_overrides. attention_mode 'mha' now requires equal query/KV
head counts everywhere (previously only DSpark enforced it). The export
gate rejects MLA since SGLang serves only the GQA/MHA draft layout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@maocheng23
maocheng23 force-pushed the agent/general-mla-draft-attention branch from c83ee51 to 6b9019f Compare August 25, 2026 03:09
@maocheng23

Copy link
Copy Markdown
Collaborator Author

Force-pushed a rework (also rebased on current main, no conflicts):

  • Scope cut — no custom knobs. Removed the two speculative dflash_config options. mla_use_output_gate is gone: standard DeepSeek MLA has no attention output gate and nothing consumes it; dropping it also removes the only behavioral hook the scaffold inserted into the shared forward. mla_rope_interleaved is gone: the standard HF rope_interleave field on the draft config already selects the rotation convention, so a second surface for the same choice was redundant. Every MLA parameter is now a standard top-level HF field.
  • History split for reviewability. Commit 1 is the pure scaffold extraction (no behavior change — the pre-existing test_modeling suite passes on it unchanged); commit 2 adds MLA and never touches the scaffold or GQA class again.
  • Tightened validation. attention_mode: "mha" now requires equal query/KV head counts for every family (previously only DSpark enforced it), and the scaffold's subclass contract is documented and asserted at init.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant