Prhub

#57027 [Bugfix][HiSparse] Preserve per-layer offsets in KV cache bindings

原始 PR 作者 LucasWilkinson 合并时间 2026-09-16 04:27 文件变更 4 提交数 5 评论 7 代码增减 +48 / -6

执行摘要

修复 HiSparse 跨层 KV 覆盖,逐层计算绑定偏移

issue #57019(GLM-5.2 sparse MLA + HiSparse host-resident KV)从第一个 decode 步就产生 token noise。作者用 curl 最小复现确认:未修复时回答为 ' ( is is'] .istsististig...' 的纯噪声,修复后输出可读续写。PR body 定位根因是 #53781 引入的 KV bindings 在多层共享分配时丢失逐层偏移,并用负对照(仅恢复旧版单函数,64 题 GSM8K 0/64)证明该缺陷与内存容量无关、低压力即可暴露。同时声明 #56158 的 host-mirror replay 属独立失败路径,避免重复工作。

值得精读。修复本身只有 15 行,但揭示了共享分配(packed allocation)场景下 byte offset 计算的经典陷阱;PR 的调试与验证方法论(恢复单个函数到旧 commit 做负对照、curl 最小复现、全量 GSM8K + nightly 精度门槛)对处理类似缓存绑定类 bug 有直接借鉴意义。重点关注 bind_hisparse_kv_caches 的 tensor_configs 推导重构,以及 nightly 作业的 source_file_dependencies 设计。

讨论亮点
  • 独立验证确认:issue #57019 上 simon-veitner-redhat 评论 "LGTM, validated locally on a diverse set of prompts additional to above tests",在作者测试之外补充了多 prompt 独立验证。
  • 审核意见:NickLucche 直接 APPROVED,全程 0 条 review 评论;claude[bot] 因 fork PR 自动 review 被禁用,未产生自动审阅意见。
  • CI 分支同步门禁:两次 /ci run 均被 github-actions[bot] 以 "This PR is N commits behind upstream main" 拒绝,作者两次 merge main(commit 801ea761、c9395974)后成功触发 Buildkite CI #89153。
  • AI 辅助披露:PR body 明确说明 OpenAI Codex 参与了调查、实现、验证与描述撰写,人类提交者负责逐行审查与独立验证,符合开源协作的透明披露惯例。

实现拆解

  1. 数据流改造(核心修复):vllm/v1/hisparse/binding.py 的 bind_hisparse_kv_caches 中,tensor_configs 字典从 {name: tensor_config} 改为 {name: (tensor_config, byte_offset)},利用 enumerate(tensor_config.layers) 同时记录层索引,逐层计算 tensor_config.offset + layer_index * tensor_config.layer_stride。这是修复关键:HiSparse 将多层打包进同一块 GPU 分配时,每层真实字节偏移必须叠加层步长。

  2. resident 与 hot 双绑定统一替换:resident 分支 cache_handle.bind_cache(...) 与 hot 分支 cache_handle.runtime.bind_hot_cache(...) 的 byte_offset 参数都改为查找表返回的逐层偏移。两个分支共用同一套偏移计算,保证 resident 与 hot 缓存在同一物理层偏移上对齐;后续的布局一致性校验(data_ptr 与 stride 对比)保持不变。

  3. 新增 Nightly 精度测试载体:新增 tests/evals/gsm8k/configs/GLM-5.2-NVFP4-HiSparse.yaml,指定真实 nvidia/GLM-5.2-NVFP4 权重、--tensor-parallel-size 4、--kv-cache-dtype bfloat16、--enforce-eager、32 GiB host pool,全量 1,319 题、5-shot、90% 精度阈值(tolerance: 0.0 不允许波动);request_timeout_seconds: 1800 是为容纳排队请求(600 秒默认值曾导致约 60 个排队请求超时)。

  4. CI 作业接入:.buildkite/test_areas/lm_eval.yaml 新增 lm-eval-hisparse-nightly-4xb200(4 卡 B200、60 分钟超时、optional: true),source_file_dependencies 覆盖 vllm/v1/hisparse/、HiSparse connector、MLA 后端、稀疏注意力层、worker 与 hisparse_kernels.cu,相关改动自动触发回归;tests/evals/gsm8k/configs/models-hisparse.txt 一行指向新配置文件。

  5. 验证与已知限制:负对照(恢复 0136df94b0 版本的单函数)在 TP4/BF16/eager 下 64 题 0/64;修复后本地 4×B300 全量 94.39%(1,245/1,319)、零 invalid answers、594.9 秒完成;30 个 HiSparse 注意力测试与 2 个 spill/prefix-restore 测试通过。PR 明确未增加单元测试,也未建立内存压力 spill 场景覆盖。

文件 模块 状态 重要度
vllm/v1/hisparse/binding.py 缓存绑定 modified 6.16
tests/evals/gsm8k/configs/GLM-5.2-NVFP4-HiSparse.yaml 评测配置 added 5.14
.buildkite/test_areas/lm_eval.yaml CI 配置 modified 3.71
tests/evals/gsm8k/configs/models-hisparse.txt 测试清单 added 1.63

关键符号

bind_hisparse_kv_caches

关键源码片段

tests/evals/gsm8k/configs/GLM-5.2-NVFP4-HiSparse.yaml test-coverage

新增 nightly 精度守护配置,用真实权重端到端验证 HiSparse 修复,全量 1,319 题、90% 精度门槛。

# Nightly HiSparse 精度守护:用真实权重端到端验证跨层偏移修复。
# 全量 1,319 题、5-shot、90% 精度门槛;本地 4×B300 实测 94.39%。
model_name: "nvidia/GLM-5.2-NVFP4"
accuracy_threshold: 0.90
tolerance: 0.0
num_questions: 1319
num_fewshot: 5
max_tokens: 256
max_concurrency: 32
# 600 秒默认值曾使约 60 个排队请求超时,放大后重测通过
request_timeout_seconds: 1800
startup_max_wait_seconds: 1200
server_args: >-
  --tensor-parallel-size 4
  --max-model-len 8192
  --max-num-seqs 32
  --max-num-batched-tokens 4096
  --enforce-eager
  --kv-cache-dtype bfloat16
  --attention-config '{"hisparse_config":{}}'
  --kv-transfer-config '{"kv_connector":"HiSparseConnector","kv_role":"kv_both","kv_connector_extra_config":{"host_pool_gib":32}}'
env:
  VLLM_USE_V2_MODEL_RUNNER: "1"

评论区精华

本地多 prompt 独立验证 测试

simon-veitner-redhat 在 issue #57019 下评论 LGTM,并说明在作者测试之外的一组多样化 prompt 上做了本地验证。

结论:修复获得 issue 报告者的独立验证,信任度提升。 · 已解决

CI 分支同步门禁 other

两次 /ci run 均被拒绝:PR 分别落后 upstream main 7 个与 1 个 commit,机器人要求 merge 或 rebase 后重试。

结论:作者两次 merge main 后同步到最新,第三次触发 Buildkite CI #89153。 · 已解决

AI 辅助实现披露 other

PR body 声明 OpenAI Codex 协助调查、实现、验证与描述撰写,人类提交者对每行负责审查;仓库未对此提出质疑。

结论:以透明披露方式完成 AI 辅助协作,NickLucche APPROVED 表明审核接受。 · 已解决

风险与影响

  • 绑定偏移回归风险:核心改动集中在 bind_hisparse_kv_caches,若 KVCacheConfig 侧 offset 或 layer_stride 语义变化,需同步此逻辑;PR 未新增直接覆盖偏移计算的单元测试,原有单元回归测试被替换为全模型精度测试。
  • 精度对齐未完全验证:PR body 明确 "Accuracy parity remains unverified",采样对比 HiSparse disabled 61/64 与 fixed 59/64 存在差异且未归因,存在 HiSparse 开启后精度仍略低于关闭状态的残余风险。
  • spill 路径覆盖不足:负对照组显式声明 "This does not establish memory-pressure spill coverage",即低缓存容量下 host pool 换入换出的跨层覆盖场景没有专项测试。
  • CI 资源开销:新增 nightly 作业使用 4×B200 真实权重,虽标记 optional: true,仍占用较大 GPU 集群资源;依赖 source_file_dependencies 触发,若遗漏某个相关路径会导致守护失效。
  • 测试基建噪音:本地 pytest 因 RemoteOpenAIServer._get_gpu_memory_used 读取物理 NVML 索引而非 CUDA_VISIBLE_DEVICES 映射导致 teardown 失败,属测试基建问题,非本 PR 引入。
  • 用户侧:修复 GLM-5.2 等稀疏 MLA 模型在 HiSparse host-resident KV 下首个 decode 即输出乱码的问题,curl 复现从纯噪声变为可读续写;所有启用 HiSparse + HiSparseConnector 的部署均受益。
  • 系统侧:binding.py 是 HiSparse KV 绑定的唯一入口,改动影响 resident 与 hot 两层缓存视图的物理地址计算;打包布局下所有层获得正确偏移,单层未打包场景偏移公式退化为 offset + 0,行为不变。
  • 团队侧:新增 nightly 精度守护(lm-eval-hisparse-nightly-4xb200)为 HiSparse 后续 kernel 与 attention 改动提供自动回归信号;PR 的"负对照 + 全量评测"验证方法论值得沉淀。
  • CI 侧:.buildkite/test_areas/lm_eval.yaml 增加一个可选作业,不影响常规 CI 关键路径。
核心绑定路径变更 缺少直接单元测试 spill 场景无专项覆盖 精度对齐未完全验证 真实权重 CI 开销大

关联 Issue

#57019 [Bug]: HiSparse host-resident KV produces token noise from the first decode step (GLM-5.2, sparse MLA)

完整报告

参与讨论