执行摘要
- 一句话:防止 VLM 因 /dev/shm 耗尽而静默崩溃
- 推荐动作:建议精读本 PR,特别是
posix_fallocate 的使用模式和 fallback 函数的设计,对于处理共享内存资源稀缺的场景具有参考价值。
功能与动机
在多模态请求突发场景下,ShmPointerMMData 在拷贝中途可能耗尽 /dev/shm(tmpfs 页在 ftruncate 后延迟分配),导致进程被 SIGBUS 杀死。该 PR 旨在将静默崩溃转变为可优雅降级的错误,并修复哈希函数对混合列表的支持。
实现拆解
- 导入新增:在
mm_utils.py 中添加 import os 和 import sys,用于平台判断和 posix_fallocate 调用。
- ShmPointerMMData.init 改造:在创建共享内存后、拷贝数据前,针对 Linux 平台调用
os.posix_fallocate(shm._fd, 0, nbytes) 预分配 tmpfs 页,使得 /dev/shm 不足时抛出 OSError(ENOSPC),而不是在拷贝时触发 SIGBUS。
- 新增 fallback 函数
_wrap_shm_or_inline:尝试构造 ShmPointerMMData,如果捕获到 OSError 则打印警告并直接返回原始 tensor,调度器后续会将其 pickle 传输。
_wrap_tensor_or_list 迁移:将内部的 ShmPointerMMData 构造调用替换为 _wrap_shm_or_inline,确保单一 tensor 或列表元素均能触发 fallback。
hash_feature 修复:将列表类型检查从 isinstance(f[0], ShmPointerMMData) 改为 any(isinstance(x, ShmPointerMMData) for x in f),以支持混合了 ShmPointerMMData 和普通 tensor 的列表。
关键文件:
python/sglang/srt/managers/mm_utils.py(模块 多模态工具;类别 source;类型 dependency-wiring;符号 _wrap_shm_or_inline, ShmPointerMMData.init, hash_feature, _wrap_tensor_or_list): 核心变更文件:新增 import、改造 ShmPointerMMData、引入 fallback 函数、修复 hash_feature。
关键符号:_wrap_shm_or_inline, ShmPointerMMData.init, hash_feature, _wrap_tensor_or_list
关键源码片段
python/sglang/srt/managers/mm_utils.py
核心变更文件:新增 import、改造 ShmPointerMMData、引入 fallback 函数、修复 hash_feature。
# 关键片段:ShmPointerMMData.__init__ 中预分配 tmpfs 页
class ShmPointerMMData:
def __init__(self, tensor: torch.Tensor, precomputed_hash: Optional[int] = None):
if not tensor.is_cpu:
tensor = tensor.cpu()
if not tensor.is_contiguous():
tensor = tensor.contiguous()
self.shape = tensor.shape
self.dtype = tensor.dtype
self.precomputed_hash = precomputed_hash
nbytes = tensor.numel() * tensor.element_size()
shm = shared_memory.SharedMemory(
create=True, size=nbytes, name=make_shm_name("mm")
)
try:
if sys.platform == "linux":
# 预分配 tmpfs 页,将 SIGBUS 转化为可捕获的 OSError
os.posix_fallocate(shm._fd, 0, nbytes)
dst = torch.frombuffer(shm.buf, dtype=torch.uint8)
dst.copy_(tensor.view(torch.uint8).reshape(-1))
except BaseException:
shm.close()
shm.unlink()
raise
# ...
# 新增 fallback 函数:尝试创建 ShmPointerMMData,失败则返回原始 tensor
# 调用方(如 _wrap_tensor_or_list)会将其视为内联传输
def _wrap_shm_or_inline(tensor: torch.Tensor, precomputed_hash: Optional[int] = None):
try:
return ShmPointerMMData(tensor, precomputed_hash=precomputed_hash)
except OSError as e:
print_warning_once(
f"Failed to allocate shared memory for multimodal feature transport "
f"({e}); falling back to inline transport. "
f"Consider increasing /dev/shm size."
)
return tensor
# hash_feature 修复:支持混合列表
def hash_feature(f):
if isinstance(f, list):
# 当列表混合 ShmPointerMMData 和普通 tensor 时,统一处理
if len(f) > 0 and any(isinstance(x, ShmPointerMMData) for x in f):
return tensor_hash(
[x.tensor if isinstance(x, ShmPointerMMData) else x for x in f]
)
if len(f) > 0 and isinstance(f[0], torch.Tensor):
return tensor_hash(f)
return data_hash(tuple(flatten_nested_list(f)))
# ... 其余分支不变
评论区精华
该 PR 的 review 评论较少,主要讨论围绕 fallback 策略:作者选择在构造 ShmPointerMMData 时立即 fallback,而不是在 _wrap_tensor_or_list 中统一处理,这样每个元素独立降级,粒度更细。此外,posix_fallocate 仅在 Linux 上调用,避免了其他平台上的兼容性问题。
风险与影响
关联脉络
- PR #28534 [AMD] Enable JIT staged HiCache write-back and fix CPU-index crash: 同样涉及共享内存管理(HiCache)和 JIT 写回策略,共享内存的稳定性改进与此 PR 有协同效应。
- PR #30461 [DSV4] Fix draft SWA transfer for disaggregated MTP: 涉及进程间数据传输的修复,与本 PR 的多模态共享内存传输有类似的稳定性关注。
参与讨论