[Fix] Add fallback for flashinfer allreduce fusion (#20384)

This commit is contained in:
Baizhou Zhang
2026-03-13 01:24:55 -07:00
committed by GitHub
parent b638b25b22
commit f8668d9e78
3 changed files with 32 additions and 11 deletions
+2
View File
@@ -50,6 +50,7 @@ from sglang.srt.layers.dp_attention import (
is_allocation_symmetric, is_allocation_symmetric,
is_dp_attention_enabled, is_dp_attention_enabled,
) )
from sglang.srt.layers.flashinfer_comm_fusion import is_flashinfer_allreduce_unavailable
from sglang.srt.layers.moe import ( from sglang.srt.layers.moe import (
get_moe_a2a_backend, get_moe_a2a_backend,
should_use_flashinfer_cutlass_moe_fp4_allgather, should_use_flashinfer_cutlass_moe_fp4_allgather,
@@ -100,6 +101,7 @@ def apply_flashinfer_allreduce_fusion(batch_size: int):
and batch_size <= FUSE_ALLREDUCE_MAX_BATCH_SIZE and batch_size <= FUSE_ALLREDUCE_MAX_BATCH_SIZE
and not is_dp_attention_enabled() and not is_dp_attention_enabled()
and get_global_server_args().enable_flashinfer_allreduce_fusion and get_global_server_args().enable_flashinfer_allreduce_fusion
and not is_flashinfer_allreduce_unavailable()
) )
@@ -14,6 +14,7 @@ logger = logging.getLogger(__name__)
_flashinfer_comm = None _flashinfer_comm = None
_workspace_manager = None _workspace_manager = None
_flashinfer_allreduce_unavailable = False
if is_flashinfer_available(): if is_flashinfer_available():
try: try:
@@ -24,17 +25,23 @@ if is_flashinfer_available():
): ):
_flashinfer_comm = comm _flashinfer_comm = comm
else: else:
_flashinfer_allreduce_unavailable = True
logger.warning( logger.warning(
"flashinfer.comm unified allreduce_fusion API is not available, " "flashinfer.comm unified allreduce_fusion API is not available, "
"falling back to standard implementation" "falling back to standard implementation"
) )
except ImportError: except ImportError:
_flashinfer_allreduce_unavailable = True
logger.warning( logger.warning(
"flashinfer.comm is not available, falling back to standard " "flashinfer.comm is not available, falling back to standard "
"implementation" "implementation"
) )
def is_flashinfer_allreduce_unavailable() -> bool:
return _flashinfer_allreduce_unavailable
class FlashInferWorkspaceManager: class FlashInferWorkspaceManager:
def __init__(self): def __init__(self):
self.workspace = None self.workspace = None
@@ -57,7 +64,7 @@ class FlashInferWorkspaceManager:
"""Initialize workspace""" """Initialize workspace"""
if _flashinfer_comm is None: if _flashinfer_comm is None:
logger.warning( logger.warning(
"FlashInfer comm not available, skipping workspace " "initialization" "FlashInfer comm not available, skipping workspace initialization"
) )
return return
@@ -73,7 +80,12 @@ class FlashInferWorkspaceManager:
force_oneshot_support=bool(use_oneshot), force_oneshot_support=bool(use_oneshot),
) )
except Exception as e: except Exception as e:
logger.warning(f"Failed to initialize FlashInfer workspace: {e}") global _flashinfer_allreduce_unavailable
_flashinfer_allreduce_unavailable = True
logger.warning(
f"Failed to initialize FlashInfer workspace: {e}. "
"Disabling flashinfer allreduce fusion permanently."
)
self.workspace = None self.workspace = None
self.initialized = False self.initialized = False
return return
@@ -140,6 +152,9 @@ def ensure_workspace_initialized(
use_oneshot: Optional[bool] = None, use_oneshot: Optional[bool] = None,
): ):
"""Ensure workspace is initialized""" """Ensure workspace is initialized"""
if _flashinfer_allreduce_unavailable:
return False
if not is_flashinfer_available() or _flashinfer_comm is None: if not is_flashinfer_available() or _flashinfer_comm is None:
return False return False
@@ -220,7 +235,7 @@ def flashinfer_allreduce_residual_rmsnorm(
""" """
if not is_flashinfer_available() or _flashinfer_comm is None: if not is_flashinfer_available() or _flashinfer_comm is None:
logger.debug( logger.debug(
"FlashInfer not available, falling back to standard " "implementation" "FlashInfer not available, falling back to standard implementation"
) )
return None, None return None, None
+12 -8
View File
@@ -327,6 +327,12 @@ class RMSNorm(MultiPlatformOp):
) )
if fused_result is not None: if fused_result is not None:
return fused_result return fused_result
else:
logger.warning(
"AITER fused AR+RMSNorm failed, falling back to standard implementation"
)
x = tensor_model_parallel_all_reduce(x)
return self.forward(x, residual, None)
else: else:
fused_result = flashinfer_allreduce_residual_rmsnorm( fused_result = flashinfer_allreduce_residual_rmsnorm(
input_tensor=x, input_tensor=x,
@@ -336,14 +342,12 @@ class RMSNorm(MultiPlatformOp):
) )
if fused_result[0] is not None: if fused_result[0] is not None:
return fused_result return fused_result
else:
# For AITER route, preserve correctness when fused path is unavailable. logger.warning(
if ( "FlashInfer allreduce fusion failed, falling back to standard implementation"
_use_aiter )
and get_global_server_args().enable_aiter_allreduce_fusion x = tensor_model_parallel_all_reduce(x)
): return self.forward(x, residual, None)
x = tensor_model_parallel_all_reduce(x)
return self.forward(x, residual, None)
return self.forward(x, residual, post_residual_addition) return self.forward(x, residual, post_residual_addition)