Skip to content

[Attn] Rename CP backends and relocate model attention modules - #5445

Merged
acisseJZhong merged 1 commit into
mainfrom
rename_attention_backends
Oct 16, 2026
Merged

acisseJZhong merged 1 commit into
mainfrom
rename_attention_backends

Conversation

@acisseJZhong

Copy link
Copy Markdown
Contributor

Stack: this PR -> #4760.

Separate naming and file organization from the MLA CP optimization in #4760: rename CP/vLLM backends consistently with InnerAttention, move DeepSeek/Kimi MLA classes into model-specific attention.py files, and update callers, including Muse Spark. Computation, parameter names, and initialization order are unchanged.

Validation: 163 CPU tests passed. DeepSeek V3 and text-only Kimi K3 debug models match main bitwise over 10 BF16/Flex training steps (seed 42, deterministic): initial/final weights, outputs, losses, gradients, and grad norms. Non-Pyrefly lint hooks passed; Pyrefly reports the same 53 diagnostics as main. GraphTrainer validation is blocked by the installed PyTorch missing _is_cacheable_effect.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Meta Open Source bot. label Oct 16, 2026
@acisseJZhong
acisseJZhong changed the base branch from main to unify_moe_ffn October 16, 2026 07:48
@acisseJZhong
acisseJZhong changed the base branch from unify_moe_ffn to main October 16, 2026 07:48
@acisseJZhong
acisseJZhong added this pull request to stack #5446 October 16, 2026 07:49
@acisseJZhong
acisseJZhong force-pushed the rename_attention_backends branch from a88ad32 to cc9f290 Compare October 16, 2026 08:07
@acisseJZhong
acisseJZhong marked this pull request as ready for review October 16, 2026 08:07
@pytorch-bot pytorch-bot Bot added the ciflow/fake-pg Run 1-GPU Fake PG integration tests label Oct 16, 2026
@acisseJZhong
acisseJZhong force-pushed the rename_attention_backends branch from cc9f290 to dd8f415 Compare October 16, 2026 22:21
@acisseJZhong
acisseJZhong merged commit 7b5a04c into main Oct 16, 2026
33 of 34 checks passed
acisseJZhong added a commit that referenced this pull request Oct 19, 2026
…imi K3 and dpskV3 (#4760)

Stack order: #5445 -> #4760.

Naming and file moves are in #5445; this PR focuses on MLA CP
optimization.

**The original optimization idea was inspired by this [MLA Ulysses CP
proposal](https://gist.github.com/fegin/bd9bd9e9147ae1b11375dfb68815f78a).**

Shape suffixes: `T` tokens, `H` heads, `L` KV latent, `N` non-positional
key, `R` shared key, `V` value; `K=N+R`, `P=N+V`, `F=K+P`. Suffixes
describe logical dimensions; collectives change their sharding.

- **K/V all-gather CP**
- Before: all-gather materialized K and V separately. K repeats
`k_shared_TR`
    across attention heads.
  - After: all-gather normalized compressed KV latents and head-shared
`k_shared_TR`, then apply `wkv_b` and materialize K/V locally. This
trades
    repeated projection work for lower communication volume.

  ```python
  # Before: materialize K before communication.
  kv_THP = reshape_per_head(wkv_b(kv_c_normed_TL))
  k_nope_THN, v_THV = unpack(kv_THP)
  k_THK = concat(k_nope_THN, expand_per_head(k_shared_TR))
  k_THK = all_gather(k_THK)
  v_THV = all_gather(v_THV)

  # After: communicate compressed latents before projecting K/V.
  kv_c_normed_TL = all_gather(kv_c_normed_TL)
  k_shared_TR = all_gather(k_shared_TR)
  kv_THP = reshape_per_head(wkv_b(kv_c_normed_TL))
  k_nope_THN, v_THV = unpack(kv_THP)
  k_THK = concat(k_nope_THN, expand_per_head(k_shared_TR))
  ```

- **Ulysses CP**
- Before: use three all-to-alls for materialized Q, K, and V. K repeats
    `k_shared_TR` across attention heads.
  - Current: all-gather headless `k_shared_TR`, then use one all-to-all
    for `q_THK` + packed `kv_THP`.

  ```python
# Before: materialize K, then move Q, K, and V from token to head
sharding.
  kv_THP = reshape_per_head(wkv_b(kv_c_normed_TL))
  k_nope_THN, v_THV = unpack(kv_THP)
  k_THK = concat(k_nope_THN, expand_per_head(k_shared_TR))
  q_THK = all_to_all_token_to_head(q_THK)
  k_THK = all_to_all_token_to_head(k_THK)
  v_THV = all_to_all_token_to_head(v_THV)
  out_THV = attention(q_THK, k_THK, v_THV)
  out_THV = all_to_all_head_to_token(out_THV)

  # Current: combine q_THK and kv_THP in one all-to-all.
  kv_THP = reshape_per_head(wkv_b(kv_c_normed_TL))
  k_shared_TR = all_gather(k_shared_TR)
  packed_q_kv_THF = all_to_all_token_to_head(
      concat(q_THK, kv_THP)
  )
  q_THK, kv_THP = split(packed_q_kv_THF)
  k_nope_THN, v_THV = unpack(kv_THP)
  k_THK = concat(
      k_nope_THN,
      expand_per_head(k_shared_TR),
  )
  out_THV = attention(q_THK, k_THK, v_THV)
  out_THV = all_to_all_head_to_token(out_THV)

  ```

- **Shared MLA backend and checkpoints**
  - DeepSeek V3, Kimi K2.7, and Kimi K3 share the compact MLA backend.
`MLAAttention` owns `wkv_b` and delegates to a Q/K/V attention kernel;
common all-gather communication lives in
`distributed/context_parallel.py`.
- HF adapters map directly to `attention.inner_attention.wkv_b.weight`,
replacing state-dict renaming hooks. HF keys remain compatible. Native
checkpoints use the nested key; old `attention.wkv_b.weight` keys are no
    longer automatically remapped.

- **Sharding and backend compatibility**
- The KV projection explicitly asserts its CP layout: replicated after
latent
all-gather, token-sharded before Ulysses all-to-all. The CP transform
copies
the nested projection config when selecting the backend; the local head
    reshape preserves that layout.
- `fused_mla` rejects CP backends at model construction because its
fused
forward bypasses the compact MLA communication wrapper. Fused MLA with
CP
is not supported; remove the override to use the configured CP backend.
- GraphTrainer precompile delegates metadata construction to the
Decoder;
batch-invariant settings traverse Flex configs directly, including those
    nested inside MLA.
- The TorchTitan vLLM wrapper currently rejects MLA. Kimi K3 MLA
inference
parity and RL integration tests are disabled until support is restored.

## Tests

After rebase/split at
[`4d5064c40c`](4d5064c):
197 CPU tests and the four-GPU MLA sharding test passed. Non-Pyrefly
lint passed; Pyrefly has the same 53 diagnostics as main. GraphTrainer
validation remains blocked by the installed PyTorch missing
`_is_cacheable_effect`.

### Numerical comparison


[`3e6c5c2b1a`](3e6c5c2):
DeepSeek V3 and text-only Kimi K3 debug models, 2 H100s, CP=2,
BF16/Flex, seed 42, deterministic, 256 tokens, 100 steps. Identical
initial weights and a fixed synthetic batch; AdamW LR `1e-3`, gradient
clipping `1.0`.

Relative differences between the materialized-K/V reference and compact
MLA on the same revision. Loss is global mean cross-entropy; grad norm
is FP32 L2 before clipping.

| Model | CP backend | Loss Δ, step 10 | Grad norm Δ, step 10 | Loss Δ,
step 100 | Grad norm Δ, step 100 |
| --- | --- | ---: | ---: | ---: | ---: |
| DeepSeek V3 | K/V all-gather | 0.067% | 0.371% | 0.541% | 0.116% |
| DeepSeek V3 | Ulysses | 0.103% | 0.218% | 0.056% | 0.128% |
| Kimi K3 | K/V all-gather | 2.321% | 11.125% | 0.462% | 0.628% |
| Kimi K3 | Ulysses | 0.262% | 2.466% | 0.363% | 0.322% |

All runs completed 100 steps with finite loss and gradients. First-step
logits and loss are **bitwise identical** in all four comparisons, but
gradients are not: first-step relative L2 gradient differences range
from **0.1475% to 0.2716%**. Changed BF16 gradient accumulation leads to
different subsequent optimizer updates. This fixed-batch comparison does
not establish convergence on a training dataset.

### Performance

Retested at
[`3e6c5c2b1a`](3e6c5c2)
on MAST: DeepSeek-V3 16B, **32 H100 GPUs**, CP=8/FSDP=4/EP=8, BF16 mixed
precision, Flex attention, C4 test data, CUDA graphs disabled, 100
steps. PyTorch `2.15.0a0+git8646abd`.

The baseline materializes K/V before communication on the same revision
and runtime. TPS/GPU is the **rank-0 mean +/- step SD over steps
21-99**, from logged throughput. One run per case.

#### K/V all-gather CP

32,768 tokens per DP rank; HeadTail load balancing.

| Path | Input collectives | TPS/GPU (mean +/- SD) | vs. baseline |
| --- | --- | ---: | ---: |
| [Before: materialized
K/V](https://www.internalfb.com/msl/studio/runs/mast/tt-pr4760-3e6c5c2-all-gather-before-32-jessicazhong-r2)
| 2 all-gathers | 3817.5 +/- 1021.8 | - |
| [Current: compressed KV latent + shared
key](https://www.internalfb.com/msl/studio/runs/mast/tt-pr4760-3e6c5c2-all-gather-current-32-jessicazhong-r2)
| 2 all-gathers | 3970.8 +/- 1009.7 | +4.02% |

#### Ulysses CP

8,192 tokens per DP rank; no CP load balancing.

| Path | Input collectives | TPS/GPU (mean +/- SD) | vs. baseline |
| --- | --- | ---: | ---: |
| [Before: separate Q, K,
V](https://www.internalfb.com/msl/studio/runs/mast/tt-pr4760-3e6c5c2-ulysses-before-32-jessicazhong-r2)
| 3 all-to-alls | 1000.6 +/- 289.5 | - |
| [Current: combined Q + packed KV, shared
key](https://www.internalfb.com/msl/studio/runs/mast/tt-pr4760-3e6c5c2-ulysses-current-32-jessicazhong-r2)
| 1 all-to-all + 1 all-gather | 1098.7 +/- 303.9 | +9.80% |

[Archived
notes.](https://www.internalfb.com/phabricator/paste/view/P2549350949 )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ciflow/fake-pg Run 1-GPU Fake PG integration tests ciflow/rl CLA Signed This label is managed by the Meta Open Source bot.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants