[DCP] Allow fi_a2a on single-node systems Blackwell without MNNVL fabric ( ex B200 B300) (#37767)

Co-authored-by: Hao Phan <htphan@nvidia.com>
Co-authored-by: Khoa Pham <khoa.pham@radixark.ai>
This commit is contained in:
Thanhhao
2026-09-08 07:55:36 -07:00
committed by GitHub
co-authored by Hao Phan Khoa Pham
parent beecfda314
commit 325ab245a1
2 changed files with 44 additions and 11 deletions
@@ -16,7 +16,7 @@ from sglang.srt.arg_groups.model_override_base import (
resolving_view,
)
from sglang.srt.runtime_context import get_platform
from sglang.srt.utils.common import get_device_name, is_mnnvl_fabric_device
from sglang.srt.utils.common import get_device_name
logger = logging.getLogger(__name__)
@@ -110,8 +110,19 @@ def _kimi_k3_overrides(server_args: Any, hf_config: Any) -> dict:
logger.info("Kimi-K3 DCP enables replicated Q projection by default.")
overrides["dcp_replicate_q_proj"] = True
from sglang.srt.layers.dcp.comm import is_fi_a2a_supported
device_name = get_device_name()
dcp_comm_backend = "fi_a2a" if is_mnnvl_fabric_device() else "a2a"
dcp_comm_backend = (
"fi_a2a"
if is_fi_a2a_supported(
dcp_size=cfg.dcp_size,
tp_size=cfg.tp_size,
pp_size=cfg.pp_size,
nnodes=cfg.nnodes,
)
else "a2a"
)
logger.info(
"Kimi-K3 DCP selects communication backend on "
f"{device_name!r}: {cfg.dcp_comm_backend!r} -> "
+31 -9
View File
@@ -36,7 +36,8 @@ from sglang.srt.distributed.device_communicators.pynccl_allocator import (
use_symmetric_memory,
)
from sglang.srt.distributed.parallel_state import GroupCoordinator
from sglang.srt.runtime_context import get_parallel
from sglang.srt.runtime_context import get_parallel, get_platform
from sglang.srt.utils.common import is_mnnvl_fabric_device
def _warn_deprecated_dcp_accessor(name: str, replacement: str) -> None:
@@ -384,6 +385,17 @@ def all_gather_kv_cache_for_dcp(
_FI_A2A_STATE: Optional[dict] = None
def is_fi_a2a_supported(
*, dcp_size: int, tp_size: int, pp_size: int, nnodes: int
) -> bool:
if not get_platform().is_sm100:
return False
if is_mnnvl_fabric_device():
return True
tp_size_per_node = tp_size // max(nnodes // pp_size, 1)
return tp_size_per_node % dcp_size == 0
def init_fi_a2a_workspace(cp_group: "GroupCoordinator") -> None:
# Call once per process BEFORE CUDA-graph capture: the FlashInfer init syncs
# the stream and barriers cross-rank, neither of which is capturable.
@@ -401,7 +413,7 @@ def init_fi_a2a_workspace(cp_group: "GroupCoordinator") -> None:
decode_cp_a2a_init_workspace,
)
from flashinfer.comm.mapping import Mapping
from flashinfer.comm.mnnvl import MnnvlConfig, is_mnnvl_fabric_supported
from flashinfer.comm.mnnvl import MnnvlConfig
except ImportError as e:
raise ImportError(
"--dcp-comm-backend fi_a2a requires FlashInfer with the DCP "
@@ -416,15 +428,25 @@ def init_fi_a2a_workspace(cp_group: "GroupCoordinator") -> None:
TorchDistributedCommBackend,
)
if not is_mnnvl_fabric_supported(torch.cuda.current_device()):
raise RuntimeError(
"--dcp-comm-backend fi_a2a requires MNNVL fabric memory (e.g. "
"GB200 NVL72); is_mnnvl_fabric_supported() returned False. Use "
"--dcp-comm-backend a2a or ag_rs on clusters without MNNVL."
)
cp_size = cp_group.world_size
cp_rank = cp_group.rank_in_group
parallel = get_parallel()
if not is_fi_a2a_supported(
dcp_size=cp_size,
tp_size=parallel.tp_size,
pp_size=parallel.pp_size,
nnodes=parallel.nnodes,
):
raise RuntimeError(
"--dcp-comm-backend fi_a2a needs a Blackwell system whose DCP group "
"shares one MNNVL domain: either MNNVL fabric memory (GB200/GB300) "
f"or a DCP group inside one node (got dcp_size={cp_size}, "
f"tp_size={parallel.tp_size}, pp_size={parallel.pp_size}, "
f"nnodes={parallel.nnodes}). Use --dcp-comm-backend a2a or ag_rs "
"otherwise."
)
mapping = Mapping(
world_size=cp_size,
rank=cp_rank,