Skip to content

[Kimi-K3] DCP support - #50484

Merged
WoosukKwon merged 9 commits into
vllm-project:mainfrom
GirasoleY:k3-dcp
Aug 10, 2026
Merged

WoosukKwon merged 9 commits into
vllm-project:mainfrom
GirasoleY:k3-dcp

Conversation

@GirasoleY

@GirasoleY GirasoleY commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Co-authored-by: @foraxe

Summary

Follow-up to #50000 adding decode context parallelism for Kimi-K3:

  • direct symmetric-memory DCP A2A output/LSE reduction, including empty-KV-shard masking
  • DCP support for the fused Kimi-K3 MLA layer
  • NVLS-multicast direct query gather and multimem chunked-context KV gather
  • direct publication of query shards into the consumer-final buffer, removing the staging-to-final materialization by @foraxe

This replaces #50055.

Query-buffer lifetime

The direct query gather returns a view of its persistent symmetric buffer. Reuse is ordered by the mandatory post-attention DCP combine:

  1. query gather publishes the current epoch and waits for every rank
  2. attention consumes the gathered query on the same CUDA stream
  3. every combine implementation introduces a cross-rank dependency after attention
  4. the next gather cannot execute until all ranks have passed the preceding attention read

DBO microbatches use independent workspace slots.

Accuracy

.buildkite/kimi-k3/rack5/gsm8k.yaml:

Arm exact_match Correct/N Request errors
TP8 96.21% 1269/1319 0
DCP8 96.97% 1279/1319 0

Performance

120k regression workload: 114k shared prefix + 6k suffix, 400 output tokens, Mooncake disabled.

Arm Conc TPOT p50/p90/p99 HBM use mean/peak
TP8 c1 13.806/13.831/13.857ms 4.93%/7.17%
DCP8 c1 10.544/10.574/10.597ms 0.64%/1.10%
TP8 c2 16.192/23.591/34.101ms 9.18%/14.11%
DCP8 c2 11.828/19.437/27.562ms 1.30%/2.37%

HBM KV capacity per GPU:

  • TP8: 1.933M tokens / 25.12 GiB
  • DCP8: 19.752M tokens / 34.28 GiB

On 4x GB200 at matched Kimi-K3 geometry, the direct-to-final query path improved query-exchange latency by 10.4%-29.9%. Correctness and changing-input CUDA-graph replay passed.

Scope and overlap

This PR subsumes the direct symmetric-memory MLA A2A work in #48897 and extends it with Kimi-K3 fused MLA DCP, direct query gather, chunked-context KV gather, and the direct-to-final query optimization.

CUDA-graph padding follow-up

Commit 76b2e9d45e makes empty-shard LSE masking tolerate CUDA-graph padding rows.

Validation:

  • tests/distributed/test_dcp_a2a.py::TestLSEWeightedCombine::test_ag_rs_masks_empty_shard_and_padded_lse: 1 passed on GB300.
  • DCP2 partial-prefix reuse versus TP2 on 2x GB300, with direct A2A, query gather, and KV gather selected: 1 passed; 256 cached tokens, exact generated-token match, finite logprobs, and drift <= 1e-2.
  • Pre-commit hooks on both changed files: passed.
  • An exploratory full-file GB300 run had 25 passes and 7 return-LSE dtype assertion failures (float32 actual versus fp16/bf16 expected); those cases pass no masking metadata and do not execute this change.

AI assistance was used to diagnose, implement, and validate this follow-up fix.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This pull request is from a fork — automated review is disabled. A repository maintainer can comment @claude review to run a one-time review.

@mergify

mergify Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

This pull request has merge conflicts that must be resolved before it can be
merged. Please rebase the PR, @GirasoleY.

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

Comment thread vllm/v1/attention/ops/common.py Outdated
Comment on lines +25 to +31
query_lens = query_start_loc[1:] - query_start_loc[:-1]
empty_rows = torch.repeat_interleave(
seq_lens == 0,
query_lens,
output_size=lse.shape[0],
)
lse.masked_fill_(empty_rows[:, None], float("-inf"))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this will never be called if we use custom cuda kernel?

Comment thread vllm/envs.py
),
# Direct DCP ops default on when applicable; set to 1 to enforce or 0 to disable.
"VLLM_USE_DIRECT_DCP_A2A": lambda: maybe_convert_bool(
os.getenv("VLLM_USE_DIRECT_DCP_A2A")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we set default value? Or I think we can make it an engine args.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we already have --dcp-comm-backend cuda-a2a (or a better name?)

@GirasoleY GirasoleY Aug 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I considered these, but the kernel version has some limitation. The intent here is

  • None = auto (default on when multicast is available)
  • 1 = force use
  • 0 = disable.

Which I feel it's actually cleaner this way... but happy to change.

@prakhar-prakash-juspay

Copy link
Copy Markdown

@GirasoleY do you plan to get this PR merged if it's working fine?

@GirasoleY
GirasoleY force-pushed the k3-dcp branch 2 times, most recently from a526d4b to 5dfad64 Compare August 4, 2026 21:17
@ywang96 ywang96 added the ready ONLY add when PR is ready to merge/full CI is needed label Aug 4, 2026
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

@GirasoleY, CI is now available for this PR. Comment /ci run to run full CI or /ci retry to retry failed jobs.

@WoosukKwon WoosukKwon added ready ONLY add when PR is ready to merge/full CI is needed and removed ready ONLY add when PR is ready to merge/full CI is needed labels Aug 7, 2026
@WoosukKwon

Copy link
Copy Markdown
Collaborator

/ci run

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

✅ Triggered Buildkite CI #82945 for commit 65328d0ee326.

@WoosukKwon

Copy link
Copy Markdown
Collaborator

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #83171 for commit 4b4c1d0214d9.

@WoosukKwon
WoosukKwon merged commit 63ac04a into vllm-project:main Aug 10, 2026
242 of 248 checks passed
@github-project-automation github-project-automation Bot moved this from Ready to Done in NVIDIA Aug 10, 2026
vrdn-23 added a commit to vrdn-23/vllm that referenced this pull request Aug 14, 2026
Resolves the recurring vllm/envs.py structural conflict per
docs/superpowers/specs/2026-05-14-envs-merge-conflict-resolution-design.md:
main's legacy `if TYPE_CHECKING:` block and `environment_variables` dict are
dropped wholesale (superseded by the pydantic BaseSettings tree on this
branch), then main's semantic delta is ported field-by-field.

6 main-side commits touched vllm/envs.py since base e644c8c (+55 -0).
All 10 new vars have already-merged callers, so every port is mandatory:

- vllm-project#51447 VLLM_MAX_STOP_STRINGS (int=4), VLLM_MAX_NUM_BAD_WORDS (int=128),
  VLLM_MAX_BAD_WORDS_TOTAL_TOKENS (int=1024) -> ServerSettings
- vllm-project#49948 VLLM_MAX_AUDIO_DECODE_BYTES (int=268_435_456) -> MediaSettings,
  carrying compile_factor=False to mirror main's ignore-set addition
- vllm-project#50484 VLLM_USE_DIRECT_DCP_A2A / _Q_GATHER / _KV_GATHER (bool|None=None)
  -> QuantSettings, with one shared `_parse_direct_dcp` before-validator
  reproducing main's maybe_convert_bool exactly
- vllm-project#52079 VLLM_KIMI_K3_GEMM_RS (bool=False) -> QuantSettings
- vllm-project#49458 VLLM_USE_HW_AGNOSTIC (bool=False) -> UsageSettings
- vllm-project#47808 VLLM_ADAPTIVE_VERIFICATION_PROFILE_CONTEXT_LEN (int=8192)
  -> QuantSettings

No deletions, modifications, or renames this window. Nothing was dropped
silently: all 6 commits' envs.py deltas are covered above.

Env var set parity after resolution: 292 branch fields vs 293 main runtime
entries, sole difference VLLM_TRITON_ATTN_USE_TD -- the known deprecation
shim divergence, re-confirmed untouched by this merge window.

Verified: 54 tests pass across tests/test_envs.py, tests/test_envs_pydantic.py
and tests/docs/test_env_vars_gen.py; `pre-commit run --files vllm/envs.py`
clean; tests/test_request_input_bounds.py passes (22 tests). The audio, DCP
and end-to-end hw-agnostic consumer suites need a CUDA box plus soundfile /
multiprocess and were not run here.

AI assistance was used to enumerate the port list and apply the resolution;
see Appendix G of the playbook for the full audit trail.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Vinay Damodaran <vrdn@hey.com>
Leoyzen added a commit to Leoyzen/vllm that referenced this pull request Aug 16, 2026
… refactor (vllm-project#52377)

GLM-5.2 + DCP4 + MTP spec decode produced garbled output (repetition,
acceptance collapsing to ~100%) after the vllm-project#50484 DCP Manager refactor,
which only handled dense MLA. Per vllm-project#46514, per-token seq_lens must be
localized AFTER the MTP expansion; the old path under-counted local KV on
(W-1)/W ranks, the indexer picked a wrong sparse top-k, and decode
degenerated into repetition.

Squashed from the production bugfix chain:
- 9a63d1e6: restore main MLADCPManager in mla_attention.decode (sparse-MLA
  DCP startup crash)
- d5f5ca13: guard mask_dcp_empty_shards_ against empty local decode shard
  (num_decodes=0 -> index out of bounds)
- 1e008a8a: expose FP8 sparse decode metadata via FlashMLASparseMetadata.decode
- 3492ca7a: skip LSE empty-shard mask on sparse DCP decode (superseded by the
  official vllm-project#52377 fix below)
- a05834a6 (vllm-project#52377 upstream): getattr(attn_metadata, "decode", None) guard,
  _direct_workspace_query_gather fallback for forced-MQA, use_forced_mqa flag
  (full seq_lens/query_start_loc for sparse)
- c912d820: drop VLLM_DEBUG_DCP instrumentation

Verified in production: 8+2 -> 10, 3+4 x3 identical, counting 1-174
consecutive, acceptance 0.90/0.78/0.63/0.56/0.47 (healthy reject curve).

Co-authored-by: Sisyphus <sisyphus@openci.dev>
foraxe added a commit to foraxe/vllm that referenced this pull request Aug 25, 2026
… memory

Port the direct-final PCP KV idea from vllm-project#49517 onto the merged vllm-project#50484
symmetric-memory substrate. Producers write final Main-KV and Indexer-K
rows into every replica through peer pointers and skip the vllm-project#52046
AllGather + insert path.

Signed-off-by: 云挚 <ningyunxiao.nyx@antgroup.com>
LopezCastroRoberto pushed a commit to LopezCastroRoberto/vllm that referenced this pull request Aug 27, 2026
… memory

Port the direct-final PCP KV idea from vllm-project#49517 onto the merged vllm-project#50484
symmetric-memory substrate. Producers write final Main-KV and Indexer-K
rows into every replica through peer pointers and skip the vllm-project#52046
AllGather + insert path.

Signed-off-by: 云挚 <ningyunxiao.nyx@antgroup.com>
foraxe added a commit to foraxe/vllm that referenced this pull request Aug 28, 2026
… memory

Port the direct-final PCP KV idea from vllm-project#49517 onto the merged vllm-project#50484
symmetric-memory substrate. Producers write final Main-KV and Indexer-K
rows into every replica through peer pointers and skip the vllm-project#52046
AllGather + insert path.

Signed-off-by: 云挚 <ningyunxiao.nyx@antgroup.com>
LopezCastroRoberto pushed a commit to LopezCastroRoberto/vllm that referenced this pull request Aug 31, 2026
…hrough PyTorch symmetric memory

Port the direct-final PCP KV idea from vllm-project#49517 onto the merged vllm-project#50484
symmetric-memory substrate. Producers write final Main-KV and Indexer-K
rows into every replica through peer pointers and skip the vllm-project#52046
AllGather + insert path.

Signed-off-by: 云挚 <ningyunxiao.nyx@antgroup.com>
(cherry picked from commit 748d7d4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/build k3 kimi nvidia ready ONLY add when PR is ready to merge/full CI is needed v1

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants