[MoE][Kernel] Add optional HPC BF16xFP32 router GEMM - #49312
lengrongfu wants to merge 3 commits into
Conversation
74644df to
a3e63a4
Compare
|
@mgoin Hi, this pr have any issue? |
yewentao256
left a comment
There was a problem hiding this comment.
Thanks for the work!
Please attach with full reproduce command and full e2e benchmark result logs (running 3 times). Also, please test using lm_eval to make sure acc is correct.
|
@yewentao256 hi, thanks review, relevant information has been added as requested. |
yewentao256
left a comment
There was a problem hiding this comment.
Why total throughput reduce instead?
| import hpc | ||
|
|
||
| cache_key = ( | ||
| y.data_ptr(), |
There was a problem hiding this comment.
Please check if this would be safe,
vllm/vllm/model_executor/layers/linear.py
Lines 386 to 394 in 4d30c51
There was a problem hiding this comment.
In my view, although it is possible to directly overwrite the tensor's memory, vLLM likely does not perform such operations during runtime; I wonder if there are any scenarios I haven't considered.
There was a problem hiding this comment.
I can implement this weight splitting more safely within process_weights_after_loading.
There was an error in the compilation of this data; I have provided the latest test results and raw data. |
a3e63a4 to
d69c8f8
Compare
yewentao256
left a comment
There was a problem hiding this comment.
Thanks for the work!
Please take a look these AI generated comments
### [P1] Preserve HPC weight storage across weight reloads
`process_weights_after_loading()` reassigns `hpc_w_high`, `hpc_w_low`, and `hpc_split_flag` every time it runs. This changes their storage addresses, while CUDA Graph capture and weight reload flows rely on those addresses remaining stable. In a minimal reproduction, all three pointers changed after reprocessing, so a captured graph may continue reading the old router weights.
Please allocate these tensors only once and use `copy_()` on subsequent reloads. It would also be good to add a weight-reload test with CUDA Graph capture.
[[Code location](https://github.com/vllm-project/vllm/blob/d69c8f8af64e626b0031c6e140c8e2348c21d458/vllm/model_executor/layers/fused_moe/router/gate_linear.py#L195-L205)](https://github.com/vllm-project/vllm/blob/d69c8f8af64e626b0031c6e140c8e2348c21d458/vllm/model_executor/layers/fused_moe/router/gate_linear.py#L195-L205)
### [P1] Guard against split-K workspace overflow
`get_gemm_bf16xfp32_workspace(n)` uses the default `max_tokens=131072`, but the forward path does not enforce any corresponding token limit. For larger `max_num_batched_tokens`, the kernel indexes the workspace using the actual tile/token count, which may result in an out-of-bounds access.
Please size the workspace from the scheduler configuration, or track its capacity and fall back when `x.shape[0]` exceeds it. A boundary test above 131072 tokens would help cover this case.
[[HPC workspace API](https://github.com/Tencent/hpc-ops/blob/main/hpc/gemm.py)](https://github.com/Tencent/hpc-ops/blob/main/hpc/gemm.py) · [[Kernel indexing](https://github.com/Tencent/hpc-ops/blob/main/src/gemm/sm90/gemm_bf16xfp32.cu)](https://github.com/Tencent/hpc-ops/blob/main/src/gemm/sm90/gemm_bf16xfp32.cu)
### [P2] Recompute HPC eligibility in `set_out_dtype()`
`GateLinear` explicitly supports setting `out_dtype` after construction, but HPC eligibility is computed only in `__init__`. If `out_dtype` is initially `None`, `allow_hpc_router_gemm` remains `False` even after calling `set_out_dtype(torch.float32)`. I reproduced this behavior.
Please recompute the HPC eligibility in `set_out_dtype()`, ideally through a shared helper used by both initialization and the setter, and add coverage for the deferred-`out_dtype` path.
[[Code location](https://github.com/vllm-project/vllm/blob/d69c8f8af64e626b0031c6e140c8e2348c21d458/vllm/model_executor/layers/fused_moe/router/gate_linear.py#L150-L193)](https://github.com/vllm-project/vllm/blob/d69c8f8af64e626b0031c6e140c8e2348c21d458/vllm/model_executor/layers/fused_moe/router/gate_linear.py#L150-L193)Signed-off-by: rongfu.leng <lenronfu@gmail.com>
Signed-off-by: rongfu.leng <lenronfu@gmail.com>
Signed-off-by: rongfu.leng <lenronfu@gmail.com>
d69c8f8 to
5e378f4
Compare
|
@yewentao256 The issues raised in the comments have been addressed. |
| # Enable the experimental HPC BF16xFP32 router GEMM path on Hopper. | ||
| "VLLM_ENABLE_HPC_ROUTER_GEMM": lambda: bool( | ||
| int(os.getenv("VLLM_ENABLE_HPC_ROUTER_GEMM", "0")) | ||
| ), |
There was a problem hiding this comment.
Would this be faster than the default one? We should make it by default if it could work better in any case
|
This pull request has merge conflicts that must be resolved before it can be |
Purpose
Issues: #49277
Add an opt-in HPC BF16xFP32 GEMM path for FP32 MoE router weights on SM90 GPUs.
Guard the path by HPC availability, device capability, dtype, layout, and shape requirements. Cache the BF16 high/low weight
decomposition and preserve the existing router GEMM fallback when the HPC kernel is unavailable or ineligible.
Reproduce
Performance
Model: MiniMax-M3-MXFP8
Workload: 100 concurrent requests
Prefill-heavy workload
Decode-heavy workload
Model Evaluation
GSM8K 5-shot evaluation was run on all 1,319 questions using
MiniMax-M3-MXFP8.
No accuracy regression was observed. The 0.3 percentage-point difference is small relative to the expected run-to-run variation and is not treated as a statistically significant accuracy improvement.
The HPC run improved evaluation throughput by approximately 2%.
lm_eval
Test Plan
3 * Benchmark
disable hpc-ops
enable hpc-ops
Test Result
Essential Elements of an Effective PR Description Checklist
supported_models.mdandexamplesfor a new model.