diff --git a/python/sglang/srt/distributed/device_communicators/triton_symm_mem_ag.py b/python/sglang/srt/distributed/device_communicators/triton_symm_mem_ag.py index c06617d08..874ae121b 100644 --- a/python/sglang/srt/distributed/device_communicators/triton_symm_mem_ag.py +++ b/python/sglang/srt/distributed/device_communicators/triton_symm_mem_ag.py @@ -466,10 +466,19 @@ class MultimemAllGatherer: # Lazy import avoids a module-load dependency on the distributed facade. from sglang.srt.distributed import get_tp_group from sglang.srt.distributed.parallel_state import in_the_same_node_as + from sglang.srt.runtime_context import get_server_args tp_group = get_tp_group() - if tp_group.world_size > 1 and not all( - in_the_same_node_as(tp_group.cpu_group, source_rank=0) + # Only probe node topology when the deployment can actually span + # nodes. Check world_size first so a TP=1 gatherer short-circuits + # before reading server args (which may be unpublished on offline + # paths). On a single node every TP rank is co-located, so skip the + # in_the_same_node_as() all-reduce, which can segfault under some + # EP/mooncake setups, and keep multimem enabled. + if ( + tp_group.world_size > 1 + and get_server_args().nnodes > 1 + and not all(in_the_same_node_as(tp_group.cpu_group, source_rank=0)) ): logger.warning( "multimem all-gather disabled because the TP group spans "