[NVIDIA] Add flashinfer MNNVL backend for allreduce only - #30700
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
|
@wenscarl Could you resolve the conflicts and set this PR as ready for review? Thanks! |
|
@shyeh25 could you share your perf results in this PR comment? thanks |
|
59ab05c to
1ed97b3
Compare
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
Correction about this: DSV4 has mHC so AR+Norm cannot be fused. so SGLang only supported FlashInfer MNNVL AR for DSV3 but not DSV4. This PR adds that support for DSV4 and can improve DSV4 GB200 TP8 small-conc perf significantly. |
|
@wenscarl could you fix the linter failure? thanks! |
|
/tag-and-rerun-ci |
|
We tested this PR end to end on SM120 (2x RTX PRO 6000 Blackwell, TP2, DeepSeek-V4-Flash MTP2, CUDA graphs) on top of main
|
|
@wenscarl Could you address the comments and fix the conflicts? thanks! |
|
/rerun-test test/registered/unit/layers/test_flashinfer_comm_fusion.py |
|
Results for 🚀 🚀 🚀 |
|
Results for 🚀 🚀 🚀 |
sgl-project#30700 made should_fuse_mlp_allreduce_with_next_layer read parallel.moe_ep_size and parallel.moe_tp_size, but the get_parallel mock in the AMD gate test only carries tp_size, so every case raises AttributeError. Set both to 1, which is the dense-TP configuration these tests exercise.
…e test stub The hybrid EP+TP guard added in #30700 reads parallel.moe_ep_size and parallel.moe_tp_size at the top of should_fuse_mlp_allreduce_with_next_layer, but the AMD gate test still stubs get_parallel() with a SimpleNamespace that only carries tp_size, so every gate case raises AttributeError.
The kAllReduce path added in sgl-project#30700 hardcoded fp32_acc=False, so it kept rounding to the input dtype once per rank after the fused path stopped.
Motivation
SGLang already supports fused allreduce via FlashInfer (
kARResidualRMSNorm: allreduce + residual + RMSNorm in one kernel) for DeepSeek-V3/V4 models. However, not every allreduce site can use the fused path —RowParallelLinear, attention output fallback, and MoE TP fallback all perform pure (non-fused) allreduce that currently always falls back to NCCL/custom-allreduce even when the FlashInfer mnnvl/trtllm workspace is already initialized and available.This PR routes those pure allreduce calls through FlashInfer
AllReduceFusionPattern.kAllReduce, reusing the existing workspace with no extra memory cost.Changes
flashinfer_comm_fusion.py— newflashinfer_allreduce()Wraps
AllReduceFusionPattern.kAllReducefor pure TP allreduce. ReturnsNoneon any of:_flashinfer_commnot initializedparallel_state.py— dispatch hook + group tagging_tag_groups_for_flashinfer_pure_allreduce(): stamps a_fi_workspace_hintattribute ("attn_tp"/"moe_tp"/"moe_ep") on_TP,_ATTN_TP,_MOE_TP,_MOE_EPgroup coordinators afterinitialize_model_parallel().GroupCoordinator.all_reduce(): checks_fi_workspace_hintand dispatches toflashinfer_allreduce()before the existingca_comm/pymscclpp/NCCL chain. Falls back transparently ifflashinfer_allreduce()returnsNone.server_args.py— new flag--enable-flashinfer-pure-allreduce(resolvable=Trueso post-process passes can set it).model_runner.py— wiringCalls
set_flashinfer_pure_all_reduce()and_tag_groups_for_flashinfer_pure_allreduce()alongside the existingset_custom_all_reduce/set_mscclpp_all_reducesetup.overrides.py— auto-enable for DeepSeek-V3/V4DeepseekV4ForCausalLMto_FLASHINFER_ALLREDUCE_FUSION_ARCHS._FLASHINFER_PURE_ALLREDUCE_ARCHSfrozenset (DeepseekV3ForCausalLM,DeepseekV32ForCausalLM,DeepseekV4ForCausalLM)._flashinfer_allreduce_fusion_auto_enablenow also setsenable_flashinfer_pure_allreduce=Truefor archs in_FLASHINFER_PURE_ALLREDUCE_ARCHS— users running DeepSeek-V3/V4 no longer need to pass--flashinfer-allreduce-fusion-backendor--enable-flashinfer-pure-allreducemanually._enforce_disable_allreduce_fusionnow also clearsenable_flashinfer_pure_allreducewhen the fused backend is force-disabled.test_flashinfer_pure_allreduce.py— unit tests5 unit tests using
_FakeFlashInferCommcovering: correctness (output == input × world_size), 1D/3D shape guard, non-contiguous guard, unavailable flag, uninitialized workspace.Performance and Accuracy
Benchmarked DeepSeek V4 Flash on Blackwell with
sglang.benchmark.one_batch, using TP=4 and sweeping batch sizes.Command:
Accuracy:
Without this PR:
With this PR: