Skip to content

[Perf][Kernel] Integrate Mega-mHC from DeepGEMM for DeepSeek V4.1 (reopen of #56255) - #56962

Merged
ywang96 merged 8 commits into
vllm-project:mainfrom
Juntian777:integrate/pr56255-mega-mhc
Sep 15, 2026
Merged

ywang96 merged 8 commits into
vllm-project:mainfrom
Juntian777:integrate/pr56255-mega-mhc

Conversation

@Juntian777

@Juntian777 Juntian777 commented Sep 15, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Reopen vLLM #56255 (closed unmerged), rebased on the #56876 base (1b5a7abb58) with the model path retargeted to deepseek_v41.
  • Keep the original implementation commit separate from the follow-up adaptation; its elfutils dependency is already in the base.
  • Preserve the current TileLang fused path for auxiliary capture and unsupported inputs, and preserve Engram injection order.
  • Pin the [Build] Move DeepGEMM pin to the vLLM fork and update the Mega MoE call convention #56876 vLLM DeepGEMM fork at ad1f1726 (2.8.0), including its SM90/SM120 support and API fixes.

Why this is not a duplicate

#56255 was closed without merging; this PR reopens that work. Open-PR searches show no competing Mega-mHC integration. #56611 fuses TileLang statistics with attention/FFN instead; this change uses DeepGEMM Mega-mHC fusion. Dependency changes intentionally reuse #56876 rather than re-opening them.

Benchmarks

Single GB200, H=5120 / 7168, hc_mult=4, BF16, 20 Sinkhorn iterations. Full post + delayed-pre + RMSNorm chain. CUPTI full-stage spans over CUDA graph replays, cold L2, 10 warmup + 100 samples per variant in forward/reverse (ABCCBA) order. Setup, JIT, and host allocation excluded; CPU launch overhead is outside the measured spans.

H Decode tokens Split (µs) Current TileLang fused (µs) Mega-mHC (µs) vs current
5120 1 16.29 13.30 11.68 1.14×
5120 8 17.44 13.31 11.62 1.15×
5120 64 18.21 18.30 12.64 1.45×
5120 256 20.90 21.14 15.90 1.33×
7168 1 20.67 17.02 12.86 1.32×
7168 8 20.61 15.71 12.13 1.30×
7168 64 22.27 22.37 14.85 1.51×
7168 256 25.41 25.47 17.28 1.47×

E2E Benchmarks

GB200 TP4, official DeepSeek-V4.1-Flash, fp8_ds_mla, no speculative decoding, max-model-len=40960. Same local source (e7fcd569dd) and dependencies; TileLang uses the existing fused-op worker hook, and #56611 Overlap is ported onto this base with TP4 enabled.

vllm bench serve: exactly 8192/32768 input + 1024 output tokens, seed 0, temperature 0, one warmup, ignore EOS, prefix caching disabled. C1: 20 requests/case; C32: 64. All 504 requests completed with exact token counts.

Latencies are in ms. Δ is relative to TileLang, shown as mean TPOT / output throughput; negative TPOT and positive throughput are better.

Concurrency 1:

Input Variant TPOT mean / p50 TTFT p50 TTFT p99 E2E p50 Output tok/s Δ TPOT / tok/s
8k TileLang 7.466 / 7.464 211.7 227.6 7845.1 130.5 —
8k Mega-mHC 7.352 / 7.351 190.1 192.9 7710.3 132.8 -1.5% / +1.8%
8k Overlap 7.355 / 7.351 204.7 215.1 7724.5 132.5 -1.5% / +1.6%
32k TileLang 7.503 / 7.502 788.2 807.3 8462.8 121.0 —
32k Mega-mHC 7.396 / 7.394 715.0 737.8 8284.4 123.6 -1.4% / +2.2%
32k Overlap 7.394 / 7.394 769.2 783.6 8336.5 122.9 -1.5% / +1.5%

Concurrency 32:

Input Variant TPOT mean / p50 TTFT p50 TTFT p99 E2E p50 Output tok/s Δ TPOT / tok/s
8k TileLang 13.565 / 14.518 1016.7 5555.9 15799.0 2055.2 —
8k Mega-mHC 13.659 / 13.692 913.4 4948.5 15740.2 2069.2 +0.7% / +0.7%
8k Overlap 14.037 / 14.394 1007.7 5517.2 16318.7 1995.2 +3.5% / -2.9%
32k TileLang 23.500 / 27.256 2947.8 21745.9 31014.7 1039.9 —
32k Mega-mHC 22.827 / 26.943 2732.4 20366.1 29700.7 1083.7 -2.9% / +4.2%
32k Overlap 23.842 / 28.315 2907.7 21991.1 31213.0 1032.6 +1.5% / -0.7%

Conclusion: Mega-mHC and Overlap have essentially equal C1 TPOT; Mega has lower TTFT. At C32, Mega delivers 3.7% / 5.0% more output tok/s than Overlap at 8k / 32k.

Tests

.venv/bin/python -m pytest tests/kernels/test_mhc_kernels.py -q -x: 174 passed, 32 skipped — covers empty/decode/prefill and changed-input CUDA graph replay. FP8 DeepGEMM tests: 100 passed, 25 skipped; matching-extension qnorm/RoPE tests: 6 passed. Pre-commit checks passed.

Task Configuration Score Request errors Output-limit hits
GSM8K 1319 problems, 5-shot, greedy, max output 4096 1225/1319 (92.87%) 0 1
GPQA Diamond 198 problems, 0-shot, default high thinking, temp 1.0, top_p 0.95, max output 262144 179/198 (90.40%) 0 0

Both accuracy evaluations used Mega-mHC with the official deepseek-ai/DeepSeek-V4.1-Flash checkpoint, on exclusive GB200 nodes with TP4+EP, fp8_ds_mla, DeepGEMM MegaMoE, CPU-offloaded Engram, no speculative decoding, and prefix caching disabled. One pass run at concurrency 32, request seed 0 and dataset/few-shot seed 1234. GSM8K: 1319 problems, 5-shot, completions endpoint, greedy (temperature=0, top_p=1), max output 4096 and server context 8192; strict-match and flexible-extract both scored 1225/1319 (92.87%), with one output-limit hit. GPQA Diamond: 198 problems, 0-shot, chat completions, think=true, default high reasoning effort (not explicitly overridden), temperature=1, top_p=0.95, max output 262144 and server context 1048576; 179/198 (90.40%), with no output-limit hits. Both had zero request errors; server max batched tokens was 8192, max sequences 256.

AI assistance

This change was developed with AI assistance (OpenAI Codex); all changes were reviewed and tested by the human submitter.

zyongye and others added 6 commits September 14, 2026 20:49
…ll convention

Repoint the DeepGEMM pin from deepseek-ai/DeepGEMM nv_dev (2.6.1) to
vllm-project/DeepGEMM dev at e49b29bb (2.8.0). The fork carries the SM120
port we relied on nv_dev for, plus configurable SwiGLU alpha/beta and the
SiTU activation for FP8/FP4 Mega MoE.

2.8.0 renames the Mega MoE activation parameters: the optional
situ_beta/situ_linear_beta pair becomes activation_alpha/activation_beta
(plain floats, defaulting to 1.0/0.0). For SiTU, activation_alpha is the
gate tanh scale and activation_beta the linear/up tanh scale, where 0.0
leaves the up branch untouched. Update the Kimi K3 MegaMoE call site
accordingly. The SwiGLU defaults reproduce the previous behavior, so the
DeepSeek V4 call sites are unchanged.

2.8.0 also swaps the third-party/fmt submodule for third-party/deep_jit,
so update the submodule list, the _C include path, and the header glob
that retriggers the _C rebuild.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Yongye Zhu <zyy1102000@gmail.com>
DeepGEMM 2.8.0 removes the legacy `fp8_m_grouped_gemm_nt_masked` Python
alias, so the getattr lookup silently resolved to None and every call
raised "DeepGEMM backend is unavailable" — breaking BatchedDeepGemmExperts.

Look up the canonical `m_grouped_fp8_gemm_nt_masked` first and keep the
legacy spelling as a fallback for externally pinned older DeepGEMM. Both
names alias the same `m_grouped_fp8_fp4_gemm_nt_masked` binding, whose
signature and pybind defaults are unchanged across the two versions.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Yongye Zhu <zyy1102000@gmail.com>
The fork commit this was first pinned to, 9a86ae2b, re-ported the SM90
paged-MQA kv_block=32/next_n=4 support onto the 2.8.0 base but dropped
the zero-context-length guards that deepseek-ai's nv_dev branch carried.
With all context lengths zero the metadata kernel reads
prefix_sum[batch_size], one past the end of a shared buffer sized to
exactly align(batch_size, 32) ints, and traps with
CUDBG_EXCEPTION_WARP_OUT_OF_RANGE_ADDRESS.

The DSA indexer warmup runs a dummy batch of max_num_seqs (default 1024,
already 32-aligned) rows with all context lengths zero, so every
DeepSeek V4 startup on Hopper hit it: nvidia-h100-lm-eval-kv-offload-large
failed deterministically on all 4 ranks of both
test_gsm8k_offloading_correctness cases.

Move the pin to the dev tip, which now carries vllm-project/DeepGEMM#8
restoring the four guards and adding a zero-context regression test.

Signed-off-by: Yongye Zhu <zyy1102000@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: OpenAI Codex <codex@openai.com>

Signed-off-by: Thien Tran <gau.nernst@yahoo.com.sg>
(cherry picked from commit 74c2daf)

Signed-off-by: Juntian Liu <Juntianl777@gmail.com>
Rebase the closed vllm-project#56255 Mega-mHC integration on the vllm-project#56876 dependency
base, retargeting deepseek_v41. Preserve the TileLang fallback and
Engram auxiliary-state semantics, and extend correctness and CUDA
graph coverage.

Co-authored-by: OpenAI Codex <codex@openai.com>
Signed-off-by: Juntian Liu <Juntianl777@gmail.com>

@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 added ci/build deepseek Related to DeepSeek models kimi k3 DSv4.1 Related to DeepSeek-V4.1 models labels Sep 15, 2026
Juntian777 and others added 2 commits September 15, 2026 07:04
Signed-off-by: Juntian Liu <Juntianl777@gmail.com>
@ywang96 ywang96 added the ready ONLY add when PR is ready to merge/full CI is needed label Sep 15, 2026
@github-actions

Copy link
Copy Markdown

✅ @Juntian777, CI is now available for this PR.

  • /ci run starts upstream CI; /amd-ci run starts AMD CI only.
  • Your branch must contain every commit currently on its upstream target branch. Merge or rebase onto the latest target branch, then rerun the command. Append --allow-stale to a run command to test an outdated branch at your own risk.
  • /ci retry retries failed jobs in the CI build for the current PR head. If the current head has no CI build, it starts a new CI build for the current head containing only jobs that failed in the latest earlier CI build for this PR.
  • /amd-ci retry retries failed jobs in AMD CI for the current PR head. Use /amd-ci run when the current head has no AMD CI build.
  • /ci cancel cancels scheduled or running CI builds for this PR branch; /amd-ci cancel does the same for AMD CI only.

@ywang96

ywang96 commented Sep 15, 2026

Copy link
Copy Markdown
Member

/ci run

@github-actions

Copy link
Copy Markdown

✅ Triggered Buildkite CI #89077 for commit 91368b7e2330.

@ywang96
ywang96 force-pushed the integrate/pr56255-mega-mhc branch from 6b53657 to 91368b7 Compare September 15, 2026 10:58
@ywang96
ywang96 merged commit bb55077 into vllm-project:main Sep 15, 2026
90 of 134 checks passed
gcanlin added a commit to gcanlin/vllm that referenced this pull request Sep 15, 2026
Upstream replaced the fused TileLang post+pre call sites with the DeepGEMM
Mega-mHC wrapper mhc_shifted_post_pre (vllm-project#56962); this branch had wrapped the
same call sites in the mhc_stream split path. Resolved by keeping both: the
split path when a coefficient stream is active, mhc_shifted_post_pre
otherwise.

Signed-off-by: Canlin Guo <canlinguosdu@gmail.com>
@Juntian777
Juntian777 deleted the integrate/pr56255-mega-mhc branch September 15, 2026 17:35
keneoneth pushed a commit to keneoneth/vllm that referenced this pull request Sep 16, 2026
…open of vllm-project#56255) (vllm-project#56962)

Signed-off-by: Yongye Zhu <zyy1102000@gmail.com>
Signed-off-by: Juntian Liu <Juntianl777@gmail.com>
Co-authored-by: Yongye Zhu <zyy1102000@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Thien Tran <gau.nernst@yahoo.com.sg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci/build deepseek Related to DeepSeek models DSv4.1 Related to DeepSeek-V4.1 models k3 kimi ready ONLY add when PR is ready to merge/full CI is needed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants