[feat] use cachebuffer to store mm feature to speedup hash (#14386)

This commit is contained in:
Nicholas
2025-12-08 10:35:20 +08:00
committed by GitHub
parent b7b7524e95
commit f57d4fe78e
3 changed files with 78 additions and 0 deletions

View File

@@ -322,6 +322,7 @@ class Envs:
SGLANG_VLM_CACHE_SIZE_MB = EnvInt(100)
SGLANG_IMAGE_MAX_PIXELS = EnvInt(16384 * 28 * 28)
SGLANG_RESIZE_RESAMPLE = EnvStr("")
SGLANG_MM_BUFFER_SIZE_MB = EnvInt(0)
# Release & Resume Memory
SGLANG_MEMORY_SAVER_CUDA_GRAPH = EnvBool(False)

View File

@@ -12,6 +12,7 @@ import torch
from torch import nn
from sglang.srt.distributed.parallel_state import get_tp_group
from sglang.srt.environ import envs
from sglang.srt.layers.multimodal import gpu_tensor_hash
from sglang.srt.managers.schedule_batch import (
CudaIpcTensorTransportProxy,
@@ -37,6 +38,59 @@ _is_npu = is_npu()
TensorTransportMode = Literal["cuda_ipc", "auto", "default"]
_GPU_FEATURE_BUFFER: Optional[torch.Tensor] = None
_BUFFER_OFFSET = 0
def init_feature_buffer(device):
global _GPU_FEATURE_BUFFER, _BUFFER_OFFSET
if (
device == "cpu"
or envs.SGLANG_MM_BUFFER_SIZE_MB.get() == 0
or _GPU_FEATURE_BUFFER is not None
):
return
try:
size_mb = envs.SGLANG_MM_BUFFER_SIZE_MB.get()
num_elements = int(size_mb * 1024 * 1024 / 4)
_GPU_FEATURE_BUFFER = torch.empty(
num_elements, dtype=torch.float32, device=device
)
logger.info(f"Preallocated {size_mb}MB GPU buffer")
except RuntimeError as e:
_GPU_FEATURE_BUFFER = None
def reset_buffer_offset():
global _BUFFER_OFFSET
_BUFFER_OFFSET = 0
def is_feature_buffer_initialized():
global _GPU_FEATURE_BUFFER
if _GPU_FEATURE_BUFFER is None:
return False
return True
def try_add_to_buffer(tensor: torch.Tensor) -> Optional[torch.Tensor]:
global _BUFFER_OFFSET
if _GPU_FEATURE_BUFFER is None:
return tensor
tensor_size = tensor.numel()
if _BUFFER_OFFSET + tensor_size <= _GPU_FEATURE_BUFFER.numel():
buffer_view = _GPU_FEATURE_BUFFER[_BUFFER_OFFSET : _BUFFER_OFFSET + tensor_size]
buffer_view.copy_(tensor.flatten(), non_blocking=True)
result = buffer_view.view(tensor.shape)
_BUFFER_OFFSET += tensor_size
return result
else:
return tensor
class TransportProxyTensor(torch.Tensor):
"""
A convenient torch.Tensor subclass that carries extra metadata and supports

View File

@@ -325,9 +325,32 @@ class MultimodalInputs:
assert isinstance(ret.mm_items, list)
ret.mm_items = [item for item in ret.mm_items if item.is_valid()]
if envs.SGLANG_MM_BUFFER_SIZE_MB.get() > 0:
from sglang.srt.managers.mm_utils import (
init_feature_buffer,
is_feature_buffer_initialized,
reset_buffer_offset,
try_add_to_buffer,
)
device = torch.cuda.current_device() if torch.cuda.is_available() else "cpu"
if not is_feature_buffer_initialized():
init_feature_buffer(device)
reset_buffer_offset()
for item in ret.mm_items:
if item.feature is not None:
if isinstance(item.feature, torch.Tensor):
item.feature = try_add_to_buffer(item.feature)
for item in ret.mm_items:
item.set_pad_value()
if envs.SGLANG_MM_BUFFER_SIZE_MB.get() > 0:
for item in ret.mm_items:
if item.feature is not None:
item.feature = item.feature.to("cpu", non_blocking=True)
optional_args = [
"mrope_positions",
"mrope_position_delta",