Support symmetric memory pre-allocation to avoid fragmentation (#17089)
This commit is contained in:
@@ -453,6 +453,9 @@ class Envs:
|
||||
# TokenizerManager
|
||||
SGLANG_REQUEST_STATE_WAIT_TIMEOUT = EnvInt(4)
|
||||
|
||||
# Symmetric Memory
|
||||
SGLANG_SYMM_MEM_PREALLOC_GB_SIZE = EnvInt(-1)
|
||||
|
||||
# Aiter
|
||||
SGLANG_USE_AITER_FP8_PER_TOKEN = EnvBool(False)
|
||||
# fmt: on
|
||||
|
||||
@@ -551,6 +551,7 @@ class Scheduler(
|
||||
self.max_req_input_len,
|
||||
self.random_seed,
|
||||
self.device,
|
||||
self.forward_stream,
|
||||
_,
|
||||
_,
|
||||
_,
|
||||
@@ -971,7 +972,6 @@ class Scheduler(
|
||||
if self.device == "cpu":
|
||||
self.default_stream.synchronize = lambda: None # No-op for CPU
|
||||
|
||||
self.forward_stream: CudaStream = self.device_module.Stream()
|
||||
self.forward_stream_ctx: CudaStreamContext = self.device_module.stream(
|
||||
self.forward_stream
|
||||
)
|
||||
|
||||
@@ -400,6 +400,7 @@ class TpModelWorker(BaseTpWorker):
|
||||
self.max_req_input_len,
|
||||
self.random_seed,
|
||||
self.device,
|
||||
self.model_runner.forward_stream,
|
||||
self.model_runner.req_to_token_pool.size,
|
||||
self.model_runner.req_to_token_pool.max_context_len,
|
||||
self.model_runner.token_to_kv_pool.size,
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -1036,6 +1036,17 @@ class ServerArgs:
|
||||
if model_config.is_multimodal:
|
||||
self.adjust_mem_fraction_for_vlm(model_config)
|
||||
|
||||
# If symm mem is enabled and prealloc size is not set, set it to 4GB
|
||||
if (
|
||||
self.enable_symm_mem
|
||||
and not envs.SGLANG_SYMM_MEM_PREALLOC_GB_SIZE.is_set()
|
||||
):
|
||||
envs.SGLANG_SYMM_MEM_PREALLOC_GB_SIZE.set(4)
|
||||
logger.warning(
|
||||
"Symmetric memory is enabled, setting symmetric memory prealloc size to 4GB as default."
|
||||
"Use environment variable SGLANG_SYMM_MEM_PREALLOC_GB_SIZE to change the prealloc size."
|
||||
)
|
||||
|
||||
def _generate_cuda_graph_batch_sizes(self):
|
||||
"""
|
||||
Generate the list of batch sizes for CUDA graph capture based on cuda_graph_max_bs.
|
||||
|
||||
Reference in New Issue
Block a user