Support symmetric memory pre-allocation to avoid fragmentation (#17089)

This commit is contained in:
Nicolas Castet
2026-01-23 17:57:04 +08:00
committed by GitHub
parent b23470e95a
commit 48e9daadff
7 changed files with 100 additions and 1 deletions
@@ -58,6 +58,9 @@ from sglang.srt.distributed import (
set_mscclpp_all_reduce,
set_torch_symm_mem_all_reduce,
)
from sglang.srt.distributed.device_communicators.pynccl_allocator import (
use_symmetric_memory,
)
from sglang.srt.distributed.parallel_state import monkey_patch_vllm_parallel_state
from sglang.srt.elastic_ep.elastic_ep import ElasticEPStateManager
from sglang.srt.environ import envs
@@ -365,6 +368,9 @@ class ModelRunner(ModelRunnerKVCacheMixin):
# Get memory before model loading
min_per_gpu_memory = self.init_torch_distributed()
# Init forward stream for overlap schedule
self.forward_stream = torch.get_device_module(self.device).Stream()
# CPU offload
set_offloader(create_offloader_from_server_args(server_args, dp_rank=dp_rank))
@@ -593,6 +599,8 @@ class ModelRunner(ModelRunnerKVCacheMixin):
# Initialize piecewise CUDA graph
self.init_piecewise_cuda_graphs()
self.prealloc_symmetric_memory_pool()
def init_routed_experts_capturer(self):
if not self.server_args.disable_shared_experts_fusion and hasattr(
self.model, "num_fused_shared_experts"
@@ -2483,6 +2491,27 @@ class ModelRunner(ModelRunnerKVCacheMixin):
logger.error(f"IPC weight update failed: {e}")
return False, str(e)
def prealloc_symmetric_memory_pool(self):
# PyTorch mempools never de-fragment memory in OOM scenarios, so we need to pre-allocate a large chunk of memory to limit fragmentation.
if (
self.is_draft_worker
or not self.server_args.enable_symm_mem
or envs.SGLANG_SYMM_MEM_PREALLOC_GB_SIZE.get() <= 0
):
return
# Memory allocation is tied to a cuda stream, use the forward stream
with torch.get_device_module(self.device).stream(self.forward_stream):
logger.info(
f"Pre-allocating symmetric memory pool with {envs.SGLANG_SYMM_MEM_PREALLOC_GB_SIZE.get()} GiB"
)
with use_symmetric_memory(get_tp_group()):
torch.empty(
(envs.SGLANG_SYMM_MEM_PREALLOC_GB_SIZE.get() * 1024 * 1024 * 1024,),
dtype=torch.uint8,
device=self.device,
)
def _model_load_weights_direct(model, named_tensors: List[Tuple[str, torch.Tensor]]):
params_dict = dict(model.named_parameters())