Prhub

#30602 [Fix] Prevent silent VLM server crash when /dev/shm is exhausted during multimodal feature transport

原始 PR 作者 hnyls2002 合并时间 2026-07-09 15:44 文件变更 1 提交数 1 评论 2 代码增减 +31 / -4

执行摘要

防止 VLM 因 /dev/shm 耗尽而静默崩溃

在多模态请求突发场景下,ShmPointerMMData 在拷贝中途可能耗尽 /dev/shm(tmpfs 页在 ftruncate 后延迟分配),导致进程被 SIGBUS 杀死。该 PR 旨在将静默崩溃转变为可优雅降级的错误,并修复哈希函数对混合列表的支持。

建议精读本 PR,特别是 posix_fallocate 的使用模式和 fallback 函数的设计,对于处理共享内存资源稀缺的场景具有参考价值。

讨论亮点

该 PR 的 review 评论较少,主要讨论围绕 fallback 策略:作者选择在构造 ShmPointerMMData 时立即 fallback,而不是在 _wrap_tensor_or_list 中统一处理,这样每个元素独立降级,粒度更细。此外,posix_fallocate 仅在 Linux 上调用,避免了其他平台上的兼容性问题。

实现拆解

  1. 导入新增:在 mm_utils.py 中添加 import osimport sys,用于平台判断和 posix_fallocate 调用。
  2. ShmPointerMMData.init 改造:在创建共享内存后、拷贝数据前,针对 Linux 平台调用 os.posix_fallocate(shm._fd, 0, nbytes) 预分配 tmpfs 页,使得 /dev/shm 不足时抛出 OSError(ENOSPC),而不是在拷贝时触发 SIGBUS。
  3. 新增 fallback 函数 _wrap_shm_or_inline:尝试构造 ShmPointerMMData,如果捕获到 OSError 则打印警告并直接返回原始 tensor,调度器后续会将其 pickle 传输。
  4. _wrap_tensor_or_list 迁移:将内部的 ShmPointerMMData 构造调用替换为 _wrap_shm_or_inline,确保单一 tensor 或列表元素均能触发 fallback。
  5. hash_feature 修复:将列表类型检查从 isinstance(f[0], ShmPointerMMData) 改为 any(isinstance(x, ShmPointerMMData) for x in f),以支持混合了 ShmPointerMMData 和普通 tensor 的列表。
文件 模块 状态 重要度
python/sglang/srt/managers/mm_utils.py 多模态工具 modified 7.3

关键符号

_wrap_shm_or_inline ShmPointerMMData.__init__ hash_feature _wrap_tensor_or_list

关键源码片段

python/sglang/srt/managers/mm_utils.py dependency-wiring

核心变更文件:新增 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)))
    # ... 其余分支不变

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

  1. posix_fallocate 依赖文件系统支持:某些非 Linux 平台或不支持 fallocate 的文件系统可能引发 AttributeErrorOSError,但代码已通过 sys.platform == "linux" 保护。
  2. 性能影响posix_fallocate 会增加一次系统调用,但在共享内存分配后、数据拷贝前执行,对整体延迟影响很小。
  3. fallback 路径正确性:内联传输通过 pickle 序列化 tensor,可能导致更大的内存拷贝开销,但这是降级路径,不应在正常流程中触发。

直接效果:在 /dev/shm 不足时,多模态 VLM 服务器不再静默崩溃,而是打印警告并降级为内联传输,保证服务可用性。
影响范围:所有使用 ShmPointerMMData 的多模态请求流程(涉及多个进程间 tensor 传输)。
影响程度:中等,属于稳定性增强,不改变正常路径的行为。

核心路径变更 依赖于 Linux-specific syscall

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论