Reenable MNNVL backend for FlashInfer allreduce fusion (#23402)

This commit is contained in:
Shu Wang
2026-06-15 20:19:15 -07:00
committed by GitHub
parent b23477af44
commit 32685874f3
7 changed files with 481 additions and 69 deletions
@@ -82,6 +82,7 @@ class TestLoRAQwen3_30B_A3B_Instruct_2507_LogprobDiff(CustomTestCase):
lora_paths={"my_lora": adapter_path},
lora_backend=LORA_BACKEND,
attention_backend="flashinfer",
flashinfer_allreduce_fusion_backend="trtllm",
moe_runner_backend=MOE_RUNNER_BACKEND,
experts_shared_outer_loras=EXPERTS_SHARED_OUTER_LORAS,
prefill_attention_backend=PREFILL_ATTENTION_BACKEND,
@@ -46,7 +46,15 @@ class TestDeepseekV32FP4TPSpec(GSM8KMixin, DefaultServerBase):
gsm8k_accept_length_thres = 2.7
def test_z_bs_1_speed(self):
args = BenchArgs(port=int(self.base_url.split(":")[-1]), max_new_tokens=2048)
args = BenchArgs(
port=int(self.base_url.split(":")[-1]),
max_new_tokens=2048,
prompt=(
"Human: Think carefully before answering. Build a fully functional FastAPI todo server. "
"Start with a short design plan, then output the complete Python code, then show how to run it "
"and test three endpoints.\n\nAssistant:"
),
)
acc_length, speed = send_one_prompt(args)
print(f"{acc_length=:.2f} {speed=:.2f}")
@@ -0,0 +1,181 @@
import types
import unittest
from unittest.mock import patch
import torch
from sglang.srt.layers import flashinfer_comm_fusion as fusion
from sglang.test.ci.ci_register import register_cuda_ci
register_cuda_ci(est_time=30, stage="base-c", runner_config="4-gpu-h100")
register_cuda_ci(est_time=30, stage="base-c", runner_config="4-gpu-b200")
register_cuda_ci(est_time=30, stage="base-c", runner_config="4-gpu-gb300")
class _FakeWorkspace:
def __init__(self, backend, world_size):
self.backend = backend
self.world_size = world_size
def is_buffer_size_sufficient(self, **_kwargs):
return True
class _FakeFlashInferComm:
class AllReduceFusionPattern:
kARResidualRMSNorm = object()
def __init__(self):
self.calls = []
def create_allreduce_fusion_workspace(self, **kwargs):
self.calls.append(kwargs)
return _FakeWorkspace(kwargs["backend"], kwargs["world_size"])
def allreduce_fusion(
self,
*,
input,
workspace,
residual_out,
norm_out,
residual_in,
rms_gamma,
rms_eps,
**_kwargs,
):
allreduced = input * workspace.world_size
expected_residual = allreduced + residual_in
variance = expected_residual.to(torch.float32).pow(2).mean(dim=-1, keepdim=True)
expected_norm = (
expected_residual.to(torch.float32)
* torch.rsqrt(variance + rms_eps)
* rms_gamma.to(torch.float32)
).to(input.dtype)
residual_out.copy_(expected_residual)
norm_out.copy_(expected_norm)
def _torch_allreduce_residual_rmsnorm_baseline(
input_tensor, residual, weight, world_size, eps
):
allreduced = input_tensor * world_size
residual_out = allreduced + residual
variance = residual_out.to(torch.float32).pow(2).mean(dim=-1, keepdim=True)
norm_out = (
residual_out.to(torch.float32)
* torch.rsqrt(variance + eps)
* weight.to(torch.float32)
).to(input_tensor.dtype)
return norm_out, residual_out
class TestFlashInferCommFusion(unittest.TestCase):
def test_auto_backend_resolves_by_arch(self):
single_node = types.SimpleNamespace(
flashinfer_allreduce_fusion_backend="auto", nnodes=1
)
multi_node = types.SimpleNamespace(
flashinfer_allreduce_fusion_backend="auto", nnodes=2
)
# Blackwell: mnnvl regardless of node count.
with patch.object(fusion, "is_sm100_supported", return_value=True):
self.assertEqual(
fusion.resolve_flashinfer_allreduce_fusion_backend(single_node), "mnnvl"
)
self.assertEqual(
fusion.resolve_flashinfer_allreduce_fusion_backend(multi_node), "mnnvl"
)
# SM90: mnnvl on single-node, trtllm fallback on multi-node.
with (
patch.object(fusion, "is_sm100_supported", return_value=False),
patch.object(fusion, "is_sm90_supported", return_value=True),
):
self.assertEqual(
fusion.resolve_flashinfer_allreduce_fusion_backend(single_node), "mnnvl"
)
self.assertEqual(
fusion.resolve_flashinfer_allreduce_fusion_backend(multi_node), "trtllm"
)
# Pre-SM90: trtllm everywhere.
with (
patch.object(fusion, "is_sm100_supported", return_value=False),
patch.object(fusion, "is_sm90_supported", return_value=False),
):
self.assertEqual(
fusion.resolve_flashinfer_allreduce_fusion_backend(single_node),
"trtllm",
)
def test_allreduce_fusion_backends_match_torch_baseline(self):
fake_comm = _FakeFlashInferComm()
original_comm = fusion._flashinfer_comm
original_create = fusion._create_allreduce_fusion_workspace
original_manager = fusion._attn_tp_workspace_manager
original_unavailable = fusion._flashinfer_allreduce_unavailable
try:
fusion._flashinfer_comm = fake_comm
fusion._create_allreduce_fusion_workspace = (
fake_comm.create_allreduce_fusion_workspace
)
fusion._flashinfer_allreduce_unavailable = False
for backend in ("trtllm", "mnnvl"):
with self.subTest(backend=backend):
world_size = 4
manager = fusion.FlashInferWorkspaceManager()
manager.workspace = _FakeWorkspace(backend, world_size)
manager.initialized = True
fusion._attn_tp_workspace_manager = manager
if not torch.cuda.is_available():
self.skipTest("FlashInfer allreduce custom op is CUDA-only")
device = torch.device("cuda")
torch.manual_seed(0)
input_tensor = torch.randn(4, 8, dtype=torch.float32, device=device)
residual = torch.randn(4, 8, dtype=torch.float32, device=device)
weight = torch.randn(8, dtype=torch.float32, device=device)
eps = 1e-6
expected_norm, expected_residual = (
_torch_allreduce_residual_rmsnorm_baseline(
input_tensor, residual, weight, world_size, eps
)
)
with (
patch.object(
fusion, "is_flashinfer_available", return_value=True
),
patch.object(
fusion,
"get_attn_tensor_model_parallel_world_size",
return_value=world_size,
),
patch.object(
fusion, "ensure_workspace_initialized", return_value=True
),
):
norm_out, residual_out = (
fusion.flashinfer_allreduce_residual_rmsnorm(
input_tensor=input_tensor,
residual=residual,
weight=weight,
eps=eps,
max_token_num=8,
)
)
torch.testing.assert_close(norm_out, expected_norm)
torch.testing.assert_close(residual_out, expected_residual)
finally:
fusion._flashinfer_comm = original_comm
fusion._create_allreduce_fusion_workspace = original_create
fusion._attn_tp_workspace_manager = original_manager
fusion._flashinfer_allreduce_unavailable = original_unavailable
if __name__ == "__main__":
unittest.main()