Repository navigation
[Kernel] Add prepared-input fast path with MiniMax-M2 top-k/act quant fusion - #43592
qianlihuang wants to merge 26 commits into
Conversation
Signed-off-by: qianlihuang <yiliu.dong@qq.com>
Signed-off-by: qianlihuang <yiliu.dong@qq.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request introduces optimizations for the MiniMax-M2 model by enabling the pre-computation of MoE inputs, including top-k weights, IDs, and quantized activations, which are then passed directly to fused MoE kernels. Key changes include a new CUDA kernel for expert alignment in small-batch scenarios, a specialized Triton kernel for fused top-k sigmoid and FP8 quantization, and significant updates to the MoE runner and modular kernel infrastructure to support these prepared inputs. Feedback focuses on ensuring the Triton kernel robustly handles cases where hidden size is not a multiple of the block size and addressing potential silent performance fallbacks if input padding is inconsistent between the model preparation logic and the MoE runner.
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
Signed-off-by: Yiliu Dong <91178480+qianlihuang@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a specialized fused top‑k (sigmoid + bias) routing + FP8 activation quantization path for MiniMax‑M2, and threads “prepared” MoE inputs through the fused MoE stack to reuse precomputed routing/quantization.
Changes:
- Introduces a new Triton custom op that fuses top‑k routing and per-token-group FP8 quantization, with a dispatch threshold.
- Adds “prepared_*” plumbing across MoE runner / kernel / quant methods so callers can skip internal routing/quantization when precomputed.
- Adds a standalone benchmark for the new fused kernel.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| vllm/model_executor/models/minimax_m2.py | Detects when MiniMax‑M2 can use prepared MoE inputs and calls the fused topk+quant dispatch op. |
| vllm/model_executor/layers/quantization/fp8.py | Exposes supports_prepared_inputs and forwards prepared tensors into the MoE kernel apply path. |
| vllm/model_executor/layers/fused_moe/topk_quant_kernels.py | New Triton kernel + custom ops to fuse top‑k routing and FP8 quantization (plus baseline fallback). |
| vllm/model_executor/layers/fused_moe/runner/moe_runner_interface.py | Extends runner interface to accept prepared routing/quant inputs. |
| vllm/model_executor/layers/fused_moe/runner/moe_runner.py | Validates/discards incompatible prepared inputs and threads prepared tensors through runner execution. |
| vllm/model_executor/layers/fused_moe/router/base_router.py | Adds post-processing helper for externally-computed top‑k results. |
| vllm/model_executor/layers/fused_moe/prepare_finalize/no_dp_ep.py | Implements prepared-input preparation for the no-dp-ep path. |
| vllm/model_executor/layers/fused_moe/modular_kernel.py | Adds prepared-input support plumbing into the modular MoE kernel, including capability checks. |
| vllm/model_executor/layers/fused_moe/layer.py | Forwards prepared inputs from layer forward into the runner. |
| vllm/model_executor/layers/fused_moe/fused_moe_modular_method.py | Exposes supports_prepared_inputs and forwards prepared tensors to the MoE kernel. |
| vllm/model_executor/layers/fused_moe/fused_moe_method_base.py | Adds base API surface for prepared inputs. |
| benchmarks/kernels/benchmark_minimax_moe_topk_quant.py | Benchmark harness comparing fused vs baseline routing+quantization. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| block_k: int, | ||
| ) -> tuple[torch.Tensor, torch.Tensor]: | ||
| return per_token_group_quant_fp8(hidden_states, block_k, use_ue8m0=False) | ||
|
|
There was a problem hiding this comment.
use_ue8m0=False Could you also test with use_ue8m0=True?
There was a problem hiding this comment.
Thanks for the suggestion. MiniMax-M2.7 uses the non-UE8M0 FP8 MoE path, and the fused kernel in this PR intentionally matches per_token_group_quant_fp8(..., use_ue8m0=False). I also benchmarked standalone per_token_group_quant_fp8 with use_ue8m0=True vs False on the MiniMax-M2 shape (M, 3072), block_k=128. The latency is very close.
Command and results
PYTHONPATH=. python3 - <<'PY'
import torch
from vllm.model_executor.layers.quantization.utils.fp8_utils import per_token_group_quant_fp8
from vllm.triton_utils import triton
ms = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
H = 3072
block_k = 128
N_RUNS = 3
def bench_us(fn):
results = []
for _ in range(N_RUNS):
r = triton.testing.do_bench(fn)
if isinstance(r, tuple):
r = r[0]
results.append(float(r) * 1000.0)
return sum(results) / len(results)
print(f"{'M':>6} {'ue8m0=false us':>16} {'ue8m0=true us':>16} {'ratio':>8}")
for m in ms:
x = torch.randn((m, H), device="cuda", dtype=torch.bfloat16)
torch.cuda.synchronize()
t_false = bench_us(
lambda: per_token_group_quant_fp8(x, block_k, use_ue8m0=False)
)
t_true = bench_us(
lambda: per_token_group_quant_fp8(x, block_k, use_ue8m0=True)
)
print(f"{m:6d} {t_false:16.3f} {t_true:16.3f} {t_true / t_false:8.3f}")
PY M ue8m0=false us ue8m0=true us ratio
1 6.024 6.226 1.034
2 6.262 6.234 0.995
4 6.304 6.271 0.995
8 6.149 6.542 1.064
16 6.302 6.385 1.013
32 6.443 6.705 1.041
64 6.744 6.616 0.981
128 6.790 7.102 1.046
256 7.421 7.707 1.038
512 9.638 9.785 1.015
1024 11.990 11.862 0.989
There was a problem hiding this comment.
Would this PR changes the behavior of e8m0 = True path? Please take a check
There was a problem hiding this comment.
Yes, this can change the E8M0 path since the fused kernel matches use_ue8m0=False. And I think False is more appropriate for MiniMax-M2.7, but I can add a guard to keep E8M0 unchanged if preferred.
There was a problem hiding this comment.
As E8M0 is widely used currently, I am not sure if we really want this complicated optimization for non-e8m0 path. Also CC @mgoin
|
This pull request has merge conflicts that must be resolved before it can be |
Purpose
This PR adds a MiniMax-M2 decode fast path for the supported modular FP8 MoE path.
There are two parts to the change:
Adds a narrow prepared-input hook to shared
FusedMoE, similar in spirit to DeepSeek V4 MegaMoE’sprepare_megamoe_inputs. MiniMax-M2 uses sharedFusedMoE, so this avoids building a separate model-specific MoE path just for prepared routing/quant inputs. The same hook can also be reused by other shared-FusedMoEmodels with similar router/FP8 staging if they add their own staging kernels later.Fuses two independent small-batch decode operations: sigmoid+bias top-k routing and per-token-group FP8 activation quantization. The fused Triton op produces prepared top-k weights/ids plus FP8 activations/scales, then the MoE runner consumes them directly. The optimization is gated to the MiniMax-M2 Triton FP8 MoE path.
bs=16, TP4 H800
Before ~8us

dp0_pp0_tp0_dcp0_ep0_rank0.1779861662605309419.pt.trace.json.gz
After ~3us

dp0_pp0_tp0_dcp0_ep0_rank0.1779875418507998155.pt.trace.json.gz
Test Plan
microbench
serve
bench
Test Result
Before
After
Essential Elements of an Effective PR Description Checklist
supported_models.mdandexamplesfor a new model.