执行摘要
- 一句话:XPU radix 缓存测试补 cache_salt 字段,修复 CI 崩溃
- 推荐动作:值得花 2 分钟快速阅读,作为「API 迁移导致测试桩漂移」的最小修复范例:PR body 的根因提交定位、波及面证据(运行 ID 列表)、修复对齐方式三步论证很规范,适合作为测试桩维护的参考样例;但对推理引擎架构学习价值有限,无需精读。建议顺手排查仓库内是否仍有其他未补
cache_salt 的 SimpleNamespace 测试桩。
功能与动机
30827(feat: add cache salt support to KV cache events)在 python/sglang/srt/mem_cache/radix_cache.py:485 的 cache_finished_req 中新增了 cache_salt=req.cache_salt 读取,目的是让外部 KV-aware 路由器的缓存命名空间与 extra_key 解耦。但 XPU 测试 test/registered/xpu/test_lmcache_radix_cache.py 用 SimpleNamespace 手工构造假请求,未同步补上该字段,导致 AttributeError: 'types.SimpleNamespace' object has no attribute 'cache_salt' 沿 lmc_radix_cache.py:446 -> radix_cache.py:485 调用链抛出。PR body 明确指出:#30827 当时修补了同构的 test/registered/unit/mem_cache/test_swa_eviction_boundary.py(本文件 docstring 也声明与之互为镜像),却遗漏了 XPU 兄弟测试,本 PR 是一次一行对齐修复。
实现拆解
- 问题定位:基于失败堆栈,确认崩溃点在
RadixCache.cache_finished_req 读取 req.cache_salt,而测试桩 _make_req(test/registered/xpu/test_lmcache_radix_cache.py:64)的 SimpleNamespace 缺少该属性。
- 一行修复:在
_make_req 的 SimpleNamespace 字面量中、extra_key=None 之后插入 cache_salt=None,以未加盐语义匹配真实请求默认值,并保持与 test_swa_eviction_boundary.py 的既有写法完全一致。
- 验证与合入:本次改动不涉及生产代码、配置或 schema;Extra CI 运行 #31758802269 通过(:white_check_mark:),Base 运行 #31697254447 失败,经 mingfeima 确认「failures unrelated」。第二个 commit 为 merge main,无实质变更。
关键文件:
test/registered/xpu/test_lmcache_radix_cache.py(模块 缓存测试;类别 test;类型 test-coverage;符号 _make_req): 唯一变更文件:在 _make_req 的 SimpleNamespace 请求桩中补充 cache_salt=None,修复 #30827 引入 cache_salt=req.cache_salt 读取后 XPU CI 的 AttributeError,并与 test_swa_eviction_boundary.py 的既有修复对齐。
关键符号:_make_req
关键源码片段
test/registered/xpu/test_lmcache_radix_cache.py
唯一变更文件:在 _make_req 的 SimpleNamespace 请求桩中补充 cache_salt=None,修复 #30827 引入 cache_salt=req.cache_salt 读取后 XPU CI 的 AttributeError,并与 test_swa_eviction_boundary.py 的既有修复对齐。
def _make_req(rid, req_pool_idx, token_ids, tree):
"""构造一个假的 Req 对象,字段集对齐 RadixCache / LMCRadixCache 实际读取的属性。
这里用 SimpleNamespace 手工拼字段,避免依赖完整调度器;也因此存在
与真实 Req 字段漂移的风险——每次缓存路径新增读取属性时都要同步补桩。
本文件的桩与 test_swa_eviction_boundary.py 互为镜像,修复需保持一致。
"""
req = SimpleNamespace(
rid=rid,
req_pool_idx=req_pool_idx,
origin_input_ids=token_ids,
output_ids=[],
extra_key=None,
# 自 #30827 起 cache_finished_req 会直接读取 req.cache_salt 拼接
# radix key,缺失会触发 AttributeError;None 表示未加盐
cache_salt=None,
last_node=tree.root_node,
cache_protected_len=0,
priority=0,
kv_committed_freed=False,
kv_committed_len=len(token_ids),
)
# 缓存写入路径还会调用 pop_committed_kv_cache() 获取已提交长度
req.pop_committed_kv_cache = lambda: len(token_ids)
return req
评论区精华
仅有 1 条 Issue 评论:审核人 mingfeima 对 Base CI 失败给出结论「failures unrelated.」。结合 PR body 的 CI 插槽(Base 运行 #31697254447 失败、Extra 运行 #31758802269 通过),该评论澄清了失败并非本 PR 引入,而是 XPU 套件在 #30827 合并后的存量问题。无 review comment,审核直接 APPROVED;这也间接说明一行修复与仓库既有惯例(镜像 test_swa_eviction_boundary.py 的写法)一致,没有设计分歧或未解决疑虑。
- Base CI 运行失败的归因 (question): Base 运行失败属于存量问题(#30827 合并后 XPU 套件的既有污染),与本 PR 一行修改无关;改动本身经 Extra 运行验证通过,mingfeima APPROVED 并合并。
风险与影响
- 风险:改动本身零回归面(仅测试文件 +1 行)。真正值得警惕的是测试桩的「字段漂移」模式:
test_swa_eviction_boundary.py 与本文件这套 SimpleNamespace 桩依赖手工维护与 Req 的属性对齐,后续缓存路径再新增字段时,仓库内其他用桩测试(不止 XPU 这一个)都可能再次被漏掉。本 PR 仅覆盖 XPU 注册套件,是否有其他测试文件仍缺 cache_salt 未在材料中确认,建议后续全局排查。
- 影响:修复直接恢复 XPU
stage-b-test-1-gpu-xpu 套件,终结 #30827 合并以来 11+ 次无关 PR 的 XPU CI 失败噪音(PR body 列出了 11 个受影响运行 ID);对 intel/xpu 开发者和所有跑该套件的 contributor 都有正向收益。对生产代码、模型推理、性能无任何影响。
- 风险标记:测试桩字段漂移, 跨平台同步遗漏
关联脉络
- PR #30827 feat: add cache salt support to KV cache events: 根因来源:#30827 在
RadixCache.cache_finished_req 中新增 cache_salt=req.cache_salt 读取,本 PR 补齐其遗漏的 XPU 测试桩字段;#30827 当时只修补了同构的 test_swa_eviction_boundary.py,未覆盖 XPU 兄弟测试。
参与讨论