feat(pytorch): add CuTeDSL W4A16 MoE backend - #4947
Open
qescccczmr wants to merge 4 commits into
Open
qescccczmr wants to merge 4 commits into
qescccczmr wants to merge 4 commits into
Conversation
qescccczmr
marked this pull request as ready for review
September 9, 2026 07:44
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Address the split-K uninitialized target issue and ensure auto checks DeepEP availability before selecting CuTe.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds a Hopper CuTe DSL W4A16 compressed-tensors MoE backend with configurable provider selection and extensive kernel, routing, and compatibility tests.
Changes:
- Adds CuTe WGMMA/TMA kernels with INT4 dequantization and split-K support.
- Adds
auto|triton|cuteprovider selection, defaulting to CuTe. - Adds numerical, graph, EP, routing, and provider-selection tests.
File summaries
| File | Description |
|---|---|
tests/pytorch/kernel/test_compressed_tensors_w4a16.py |
Legacy provider and builder coverage |
tests/pytorch/kernel/test_compressed_tensors_w4a16_cute.py |
CuTe numerical, graph, routing, and EP tests |
tests/pytorch/config/test_w4a16_moe_backend.py |
Provider compatibility and selection tests |
lmdeploy/pytorch/kernels/cuda/compressed_tensors_w4a16_cute.py |
CuTe W4A16 kernels and MoE execution paths |
lmdeploy/pytorch/envs.py |
Backend environment configuration |
lmdeploy/pytorch/backends/cuda/moe/compressed_tensors.py |
Provider selection and CuTe/DeepEP integration |
Review details
Suppressed comments (1)
lmdeploy/pytorch/backends/cuda/moe/compressed_tensors.py:390
- When
spec.ep_size > 1,_supports_cutecan still returnTrueon a system whereuse_deepepis false, because it only probes the CuTe kernel import.autothen selects_build_fused_moe_cute, whose DeepEP constructor raises before the Triton branch is selected, contradicting the documented compatibility-based provider selection. Include the DeepEP availability check in_supports_cute(while keeping explicitcutestrict).
if not torch.cuda.is_available() or torch.cuda.get_device_capability()[0] != 9:
return False
try:
from lmdeploy.pytorch.kernels.cuda.compressed_tensors_w4a16_cute import fused_moe_w4a16_cute # noqa: F401
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+306
to
+307
| target = out if split_k == 1 else torch.empty( | ||
| (out.shape[0] * split_k, out.shape[1]), device=out.device, dtype=torch.float32) |
grimoire
reviewed
Sep 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Add a Hopper CuTe DSL W4A16 provider for compressed-tensors MoE without expanding packed INT4 weights into a persistent BF16 cache.
Modification
FusedMoEW4A16BuildSpecand add provider selection throughLMDEPLOY_W4A16_MOE_BACKEND=auto|triton|cute, defaulting toauto.autoprefers CuTe when the build-time format, device and optional kernel imports are compatible, and DeepEP is available when EP > 1; otherwise it selects the existing Triton builder. Explicitcuteis strict; explicittritonretains the existing Triton path.Production changes remain limited to three files: the CuTe kernel, CUDA compressed-tensors MoE backend and environment configuration. Three related test files now cover the legacy builder, provider compatibility and Hopper CuTe numerical/graph behavior. Communication optimizations, router changes, documentation, unrelated tests and benchmarks remain excluded.
BC-breaking
The default is
auto: unsupported CuTe environments retain the existing Triton builder without requiring a new environment setting. CuTe requires Hopper SM90, BF16 activations/output, INT4 group-size 32 and optionalnvidia-cutlass-dsl/cuda-pythondependencies. Explicitcuteremains strict. Both providers require DeepEP for EP > 1; automatic local-kernel selection does not remove that communication dependency or hide invalid EP configuration errors.Use cases
Select the CuTe provider with
LMDEPLOY_W4A16_MOE_BACKEND=cutefor supported compressed-tensors W4A16 MoE models on Hopper. No TP all-reduce or DeepEP communication kernel is replaced by this PR.Benchmark
LMDeploy native Triton W4A16 baseline
2.13.0+cu129, Triton3.7.1, CuTe DSL4.4.2, CUDA Python13.3.1.20260908;renormalize=False.triton.testing.do_bench_cudagraph(rep=150), no profiler; three samples per shape with alternating implementation order, taking the median of each implementation's samples. Each sample is the mean of ten graph replays. Compilation, input generation, router score/top-k computation and communication are excluded.CuTe is 1.946x–3.650x faster than the existing LMDeploy Triton implementation in this sweep. All outputs are finite; maximum output NRMSE versus Triton is
0.003859(the benchmark checks< 0.02). This is a numerical smoke check, not a model-quality evaluation or bitwise-equivalence claim.This is a single-GPU local-MoE benchmark at a TP8 shard shape, not eight-rank TP8 service throughput or EP dispatch/combine performance. Benchmark scripts and raw results remain local, excluded from the PR's code diff. Do not conflate this native-Triton speedup with the separate SGLang Marlin comparison below.
SGLang Marlin comparison
2.13.0+cu129, Triton3.7.1, CuTe DSL4.4.2, CUDA Python13.3.1. Reference: local SGLang Marlin checkout based on9e692c9216c3b5e5c443fecf6b995700eb68d2e4. That checkout has other local changes; the Marlin wrapper, GEMM, repacking and scale-permutation Python files are unmodified.20260908. Marlin weight repacking is setup-only.triton.testing.do_bench_cudagraph(rep=150), no profiler; median of three runs, each reporting the mean of ten graph replays. The measured region includes route layout preparation, gather, gate/up GEMM, SiLU, down GEMM and weighted reduction. Router score/top-k computation, compilation, repacking and communication are excluded.Marlin / CuTe > 1means CuTe is faster. CuTe currently wins only at one token in this sweep. Maximum output NRMSE versus Marlin across the completed runs is0.008765; results are not bitwise identical.These are single-GPU MoE microbenchmarks at a TP8 shard shape, not eight-rank TP8 service measurements or end-to-end throughput. A separate 1024-token attempt did not complete the Marlin timing and remained in CUDA synchronization; its benchmark process was stopped. No completed 1024/2048-token Marlin comparison or speedup is reported, and no root cause is asserted for that incomplete run. Benchmark scripts and raw results remain local and are not included in the code diff.
Validation
hidden_dim=1builder test explicitly checksauto/triton. Explicitcutestill rejects unsupported hardware; CuTe numerical tests skip non-Hopper devices before importing optional CuTe dependencies. The default is nowautofollowing review.git diff --checkpass.Remaining CI / compatibility issues
auto; explicitcutecontinues to require a compatible environment.