Add fused dsa - #3044
Conversation
There was a problem hiding this comment.
What is the rational for this change? The base Attention's forward class depends on there being a self.core_attention. This also leads to code duplication. Perhaps something that doesn't have a core attention block followed by linear_proj should just be a different thing all together?
There was a problem hiding this comment.
I just noticed that the MLA and base attention are both creating core attention and out_proj, so I made a quick fix. It has nothing to do with this PR, I will revert this change.
There was a problem hiding this comment.
Not in this PR yet. I revert this change in the standalone absorbed_mla PR. We will merge that PR first right? Once that PR merged, I'll rebase this one.
There was a problem hiding this comment.
Rebased. To avoid any potential concerns.
9953d15 to
382e36b
Compare
382e36b to
2e4a5d4
Compare
|
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. |
0466477 to
3730f09
Compare
|
/ok to test ac68a51 |
|
/ok to test 14e9792 |
|
/ok to test fdaa74c |
|
/ok to test 73ea27c |
ff51b49 to
bf76770
Compare
|
/ok to test bf76770 |
|
/ok to test 1d37420 |
|
/ok to test 46c2e3c |
|
/ok to test 3ead04d |
What does this PR do ?
Separate PR for adding absorbed-mla #3193 (merged)
main PR: #3747
1. TL;DR
AbsorbedMLASelfAttention, a variant of MLA that absorbs K's up projection into Q and applies V's up projection after core attention, enabling MQA-style computation.Attentionclass to move module init to subclasses.2. Big Picture
2.1 Before vs After Architecture
graph TB subgraph "Standard MLA (Before)" H1[hidden_states] --> Q1[Q projection] H1 --> KV1[KV projection] KV1 --> KVup1["KV up proj<br/>[K,V] = W_up @ kv_compressed"] Q1 --> Qup1[Q up proj] Qup1 --> CA1[Core Attention<br/>MHA: n heads for Q,K,V] KVup1 --> CA1 CA1 --> OUT1[Output proj] end subgraph "Absorbed MLA (After)" H2[hidden_states] --> Q2[Q projection] H2 --> KV2[KV projection] Q2 --> Qup2[Q up proj] Qup2 --> ABS["Absorb K_up into Q<br/>Q' = Q @ K_up^T"] ABS --> CA2[Core Attention<br/>MQA: n heads Q, 1 head KV] KV2 --> CA2 CA2 --> Vup["Apply V_up after attn<br/>out = attn_out @ V_up"] Vup --> OUT2[Output proj] endKey insight: By absorbing K's up-projection into Q, the attention operates in MQA form (Q has n heads, K/V have 1 head). This is mathematically equivalent but enables more efficient sparse attention patterns.
2.2 Change Scope Summary
experimental_attention_variant/absorbed_mla.pyexperimental_attention_variant/dsa_fused_kernels.pytests/.../test_absorbed_mla.pyattention.pycore_attention/linear_projinit from base to subclassesdsa.pymulti_latent_attention.pyposition_idsparameterexperimental_attention_variant_module_specs.py3. Design Rationale
3.1 Problem Background
Standard MLA applies KV up-projection before attention:
This produces multi-head K/V tensors, which don't work well with DSA's sparse attention pattern that benefits from MQA-style computation.
3.2 Solution: Matrix Absorption
The mathematical trick:
V up-projection is moved after attention:
3.3 Key Design Points
linear_kv_up_projsplit intolinear_k_up_proj+linear_v_up_proj[s,b,n,d], K/V shape[s,b,1,d]_load_from_state_dicthandles splitting combined KV weights4. Execution Path Deep Dive
4.1 Call Chain
sequenceDiagram participant F as forward() participant GQKV as get_query_key_value_tensors() participant UP as qkv_up_proj_and_rope_apply() participant CA as core_attention() participant VP as V up proj F->>GQKV: hidden_states GQKV->>GQKV: Q down proj → q_compressed GQKV->>GQKV: KV down proj → kv_compressed, k_pos_emb GQKV->>GQKV: Apply layernorms GQKV->>UP: q_compressed, kv_compressed UP->>UP: Q up proj → q [s,b,n,qk+rope_dim] UP->>UP: Absorb K_up into Q: q' = einsum("...nd,ndk->...nk", q_nope, K_up_weight) UP->>UP: Apply RoPE to q_rope and k_pos_emb UP->>UP: Concat: q_absorbed = [q', q_rope], kv = [kv_compressed, k_rope] UP-->>GQKV: q_absorbed, kv_compressed GQKV-->>F: q_absorbed, kv_compressed F->>CA: q_absorbed [s,b,n,kv_rank+rope], kv [s,b,1,kv_rank+rope] CA-->>F: attn_out [s,b,n,kv_rank] F->>VP: einsum("...nc,ndc->...nd", attn_out, V_up_weight) VP-->>F: out [s,b,n,v_dim] F->>F: linear_proj → output4.2 Core Code: K Absorption
4.3 Core Code: V Up-Projection After Attention
5. Module Relationships
classDiagram class Attention { +config +layer_number +attn_mask_type -checkpoint_core_attention -offload_core_attention } class MultiLatentAttention { +rotary_pos_emb +core_attention +linear_proj +softmax_scale } class MLASelfAttention { +linear_q_down_proj +linear_q_up_proj +linear_kv_down_proj +linear_kv_up_proj +get_query_key_value_tensors() } class AbsorbedMLASelfAttention { +linear_k_up_proj [NEW] +linear_v_up_proj [NEW] +get_query_key_value_tensors() +_split_kv_weights() +_combine_kv_weights() } class DSAttention { +k_channels +v_channels +forward() supports MQA } Attention <|-- MultiLatentAttention MultiLatentAttention <|-- MLASelfAttention Attention <|-- AbsorbedMLASelfAttention : extends directly AbsorbedMLASelfAttention ..> DSAttention : uses for MQA modeNote:
AbsorbedMLASelfAttentionextendsAttentiondirectly (notMultiLatentAttention) because it builds its owncore_attentionandlinear_projwith MQA-specific parameters.6. Risks & Edge Cases
cache_mla_latentsnot supportedrecompute_up_projincompatible_load_from_state_dict7. Quick Reference
7.1 File Change Summary
7.2 Key Functions
AbsorbedMLASelfAttention.__init__absorbed_mla.py:350get_query_key_value_tensorsabsorbed_mla.py:596qkv_up_proj_and_rope_applyabsorbed_mla.py:740forwardabsorbed_mla.py:953_split_kv_weightsabsorbed_mla.py:1157unfused_dsa_fn_mqadsa.py:699FusedDSAMQAdsa_fused_kernels.py:19157.3 Related Code
megatron/core/transformer/multi_latent_attention.py- Standard MLA for comparisonmegatron/core/transformer/attention.py- Base attention classContribution process
flowchart LR A[Pre-checks] --> B[PR Tests] subgraph Code Review/Approval C1[Expert Review] --> C2[Final Review] end B --> C1 C2 --> D[Merge]Pre-checks
Core 0.8)Code review
The following process is enforced via the CODEOWNERS file for changes into
megatron/core. For changes outside ofmegatron/core, it is up to the PR author whether or not to tag the Final Reviewer team.For MRs into `main` branch
Feel free to message or comment the @mcore-oncall to help accelerate your merge into main. The less complex your PR is, the faster it will be approved and merged!
(Step 1): Add PR label
Expert Review(Step 2): Collect the expert reviewers reviews
Expert Reviewlabel when your PR is ready for review.Final Review might get declined if these requirements are not fulfilled.
(Step 3): Final Review
Final Reviewlabel(Optional Step 4): Cherry-pick into release branch
If this PR also needs to be merged into
core_r*release branches, after this PR has been merged, selectCherry-pickto open a new PR into the release branch.For MRs into `dev` branch
The proposed review process for `dev` branch is under active discussion.MRs are mergable after one approval by either
eharper@nvidia.comorzijiey@nvidia.com.Merging your PR
Any member of core-adlr and
core-nemowill be able to merge your PR.