Prhub

#41145 better logging for large uncachable items

原始 PR 作者 h-avsha 合并时间 2026-04-30 00:48 文件变更 1 提交数 6 评论 1 代码增减 +21 / -5

执行摘要

改进大对象未缓存时的日志

在 multimoda 缓存中,当多媒体项因体积过大或缓存满而无法缓存时,原有统一使用 logger.debug,难以在生产环境中快速定位配置不足的问题。PR 旨在区分两种场景并给出可操作的参数建议,便于排查缓存未命中的根因。

虽然逻辑合理且维护者已 approve,但需确认 logger.warning_once 在传异常对象时不会崩溃。建议在合并后观察生产环境是否出现 TypeError 异常上报。

讨论亮点

review 中 gemini-code-assist[bot] 指出使用 logger.warning_once 传入异常对象 e 可能导致 TypeError,因为 warning_once 内部使用 functools.lru_cache 要求参数可哈希,而异常对象不可哈希。此外建议区分 ValueError 中的大小相关错误和并发重复键场景,避免误导性警告。最终该评论未被作者解决,但 PR 被维护者批准合并。

实现拆解

vllm/multimodal/cache.pyget_and_update_item 方法中,将原先合并捕获 (ValueError, MemoryError) 的异常处理拆分为两个独立的 except 子句:

  1. 捕获 ValueError 时,首先检查异常信息中是否包含 "already exists"(并发重复键情况),若是则静默处理(不打印日志);否则使用 logger.warning_once 输出警告,提示调整 --mm-shm-cache-max-object-size-mb
  2. 捕获 MemoryError 时,使用 logger.debug 输出调试信息,提示调整 --mm-processor-cache-gb
    两个分支均返回原 mm_item 作为 fallback。
文件 模块 状态 重要度
vllm/multimodal/cache.py 多模态缓存 modified 6.22

关键符号

get_and_update_item

关键源码片段

vllm/multimodal/cache.py core-logic

核心变更文件:拆分异常处理并为 oversize 和 cache-full 场景提供差异化日志与配置建议。

# vllm/multimodal/cache.py (head 版本 )
from vllm.logger import loggerclass MultiModalSharedMemoryCacheManager:
    ...
​
    @override
    def get_and_update_item(
        self,
        mm_item: MultiModalProcessorCacheInItem,
        mm_hash: str,
    ) -> MultiModalProcessorCacheOutItem:
        if self._shm_cache.is_cached(mm_hash):
            self._hits += 1
            self._total += 1
            address, monotonic_id = self._shm_cache.get_cached(mm_hash)
            prompt_updates = self._p0_cache[mm_hash]
            return self.address_as_item(address, monotonic_id), prompt_updates
​
        assert mm_item is not None, f"Expected a cached item for {mm_hash=}"
        item, prompt_updates = mm_item
        self._total += 1
​
        try:
            address, monotonic_id = self._shm_cache.put(mm_hash, item)
            # ... (remove dangling items logic)
            self._p0_cache[mm_hash] = prompt_updates
            return self.address_as_item(address, monotonic_id), prompt_updates
        except ValueError as e:
            # `put` 可能因对象过大或重复键(并发插入)而抛出 ValueError;
            # 后者是良性的,所以只对过大情况发出警告。
            # 后续仅 UUID 的请求会因缓存未命中而失败。
            if "already exists" not in str(e):
                logger.warning_once(
                    "mm_input %s too large to cache; "
                    "raise --mm-shm-cache-max-object-size-mb. (%s)",
                    mm_hash,
                    str(e),
                )
            return mm_item
        except MemoryError as e:
            # 缓存满且受保护对象阻止了驱逐。
            logger.debug(
                "mm_input %s not cached; shm cache full, "
                "consider raising --mm-processor-cache-gb. (%s)",
                mm_hash,
                str(e),
            )
            return mm_item

评论区精华

logger.warning_once 传入异常对象可能导致 TypeError 正确性

gemini-code-assist[bot] 指出,使用 `logger.warning_once` 时传入异常对象 `e` 会导致 `TypeError`,因为内部 `lru_cache` 要求参数可哈希,而异常对象不可哈希。

结论:未在 PR 中解决,但 PR 仍被批准合并。 · unresolved

ValueError 中区分大小错误和重复键 正确性

gemini-code-assist[bot] 建议,`put` 在重复键时也会抛出 `ValueError`,应忽略该场景以避免误导性警告。

结论:作者通过检查异常字符串中是否包含 "already exists" 来区分两种情况,已采纳。 · 已解决

风险与影响

如果 logger.warning_once 确实因异常对象不可哈希而抛出 TypeError,会导致请求处理崩溃,影响稳定性。但由于该日志仅在缓存 put 失败时触发,且生产环境中缓存配置通常合理,实际触发概率较低。建议在合并前验证异常对象是否可哈希或采用字符串化参数。

仅影响 vllm/multimodal/cache.pyget_and_update_item 方法的异常处理路径,正常缓存命中/未命中路径无变化。对用户而言,大对象未缓存时将从静默 debug 变为可见警告;对运维而言,提供了明确的参数调整指引,有助于快速诊断缓存配置问题。

潜在 TypeError 风险 缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论