Prhub

#24950 fix: SGLANG_RADIX_FORCE_MISS chunk-cache passthrough

原始 PR 作者 ch-wan 合并时间 2026-05-11 15:07 文件变更 2 提交数 1 评论 0 代码增减 +13 / -18

执行摘要

修复 chunk cache 在 FORCE_MISS 标志下崩溃

DeepSeek-V4 分离式部署中,prefill worker 使用 SWAChunkCache,启用 SGLANG_RADIX_FORCE_MISS=1 后调度器首次调用 match_prefix 即崩溃。ChunkCache 没有前缀匹配树,match_prefix 已返回空结果,FORCE_MISS 标志无需额外处理。

建议快速合并。这是一个明确的小范围 bugfix,修复了特定配置下的崩溃,测试覆盖到位,代码简洁。

讨论亮点

无实质 review 讨论,仅有一条 gemini-code-assist 的自动评论确认无反馈。

实现拆解

  1. 修改 zero_match_result 函数 (python/sglang/srt/mem_cache/base_prefix_cache.py):原逻辑通过 getattr(tree_cache, "root_node", None) 获取根节点,若为 None 则抛出 RuntimeError。新逻辑先调用 tree_cache.is_chunk_cache() 判断,若是 chunk cache 则直接原样返回 match_result,否则直接访问 tree_cache.root_node 进行置零操作。
  2. 更新测试用例 (test/registered/unit/mem_cache/test_radix_force_miss.py):移除 test_no_root_node_raises 测试(验证旧异常行为),新增 test_chunk_cache_is_passthrough 测试,使用实现 is_chunk_cache 方法的 _StubChunkCache 模拟 chunk cache,验证 zero_match_result 原样返回 MatchResult
文件 模块 状态 重要度
python/sglang/srt/mem_cache/base_prefix_cache.py 缓存层 modified 6.4
test/registered/unit/mem_cache/test_radix_force_miss.py 缓存层 modified 5.98

关键符号

zero_match_result

关键源码片段

python/sglang/srt/mem_cache/base_prefix_cache.py core-logic

核心修复文件,修改 `zero_match_result` 函数逻辑,增加 chunk cache 短路分支。

# python/sglang/srt/mem_cache/base_prefix_cache.py (head)def zero_match_result(tree_cache, match_result: "MatchResult") -> "MatchResult":
    # Chunk caches (ChunkCache, SWAChunkCache) 没有前缀匹配树,
    # match_prefix 已经返回空结果,因此直接透传,不做任何修改。
    if tree_cache.is_chunk_cache():
        return match_result
    # Tree cache 有 root_node,将 match_result 的字段置零,
    # 强制后续请求缓存未命中。
    root = tree_cache.root_node
    return match_result._replace(
        # [:0] 保留原始 tensor 的 dtype 和 device,无需重新分配空 tensor。
        device_indices=match_result.device_indices[:0],
        last_device_node=root,
        last_host_node=root,
        host_hit_length=0,
    )
test/registered/unit/mem_cache/test_radix_force_miss.py test-coverage

更新测试以覆盖新行为,移除旧异常测试,新增 chunk cache 透传测试。

# test/registered/unit/mem_cache/test_radix_force_miss.py (head)class TestZeroMatchResult(unittest.TestCase):
    # 原有 test_no_root_node_raises 已被移除
    def test_chunk_cache_is_passthrough(self):
        # 模拟一个 ChunkCache 子类,仅实现 is_chunk_cache 返回 True
        class _StubChunkCache:
            def is_chunk_cache(self) -> bool:
                return True
​
        # 构造一个空的 MatchResult(ChunkCache 的 match_prefix 返回空结果)
        original = MatchResult(
            device_indices=torch.empty((0,), dtype=torch.int64),
            last_device_node=None,
            last_host_node=None,
            host_hit_length=0,
        )
        # 验证 zero_match_result 原样返回 original
        self.assertIs(zero_match_result(_StubChunkCache(), original), original)

评论区精华

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

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

风险与影响

低风险。变更局限于 zero_match_result 单函数,对于 tree cache(RadixCache, SwaRadixCache)行为不变;chunk cache 路径改为直接返回 MatchResult,而 match_prefix 在 chunk cache 上已返回空结果,因此语义正确。需要确保所有 chunk cache 子类均正确实现了 is_chunk_cache 方法。

影响范围:仅影响使用 SGLANG_RADIX_FORCE_MISS=1 环境变量且缓存后端为 ChunkCache/SWAChunkCache 的用户。影响程度:修复崩溃 bug,对 tree cache 用户无影响。

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论