Prhub

#35727 [NPU][Bugfix] Fix OOB gather in decode KV allocation when free pool is tight

原始 PR 作者 xdtbynd 合并时间 2026-08-27 19:44 文件变更 1 提交数 3 评论 1 代码增减 +1 / -0

执行摘要

修复 NPU decode 分配器在空闲页池紧张时的越界 gather

PR 正文明确指出,当空闲页池恰好紧密时(len(self.free_pages) == num_new_pages),start_new_pages 的最后一个元素会等于 num_new_pages,导致 self.free_pages[start_new_pages] 索引越界。该问题仅在池恰好用尽时触发,并在 CI 的 test_npu_schedule_conservativeness.py 中导致 AI Core 错误和服务器崩溃。

值得快速阅读,理解 NPU 分配器的边界条件处理。建议后续补充针对该边界情况的单元测试,以巩固修复效果。

讨论亮点

该 PR 仅由机器人审查并批准,无人工评论。PR 正文中详细解释了 clamp 的安全性和正确性依据。

实现拆解

  1. 在 python/sglang/srt/hardware_backend/npu/allocator_npu.py 的 alloc_decode 方法中,在计算 out_indices 之前,对 start_new_pages 应用 clamp,限制其最大值不超过 num_new_pages - 1。
  2. 由于 num_new_pages == 0 的分支提前返回,clamp 操作不会出现上限为 -1 的情况。
  3. 该 clamp 不影响实际结果,因为被 clamp 的行 need_new_pages == 0,在后续计算中会被乘以 0 而屏蔽。
  4. 对每个 decode batch 仅增加一次元素级 clamp 操作,性能开销可忽略。
文件 模块 状态 重要度
python/sglang/srt/hardware_backend/npu/allocator_npu.py 内存分配 modified 4.58

关键符号

alloc_decode

关键源码片段

python/sglang/srt/hardware_backend/npu/allocator_npu.py core-logic

这是唯一的变更文件,修复了 NPU decode KV 分配器中的越界索引问题。

# python/sglang/srt/hardware_backend/npu/allocator_npu.py
# 修复空闲页池恰好用尽时的越界 gather
def alloc_decode(
    self,
    seq_lens: torch.Tensor,
    seq_lens_cpu: torch.Tensor,
    last_loc: torch.Tensor,
):
    # ...(前置检查和计算 num_new_pages 等)
​
    need_new_pages = (seq_lens % self.page_size == 1).int()
    end_new_pages = torch.cumsum(need_new_pages, 0)
    # start_new_pages 是 free_pages 的前缀索引,范围应为 [0, num_new_pages-1]
    start_new_pages = end_new_pages - need_new_pages
    if num_new_pages == 0:
        out_indices = last_loc + 1
    else:
        # 关键修复:clamp 防止 start_new_pages 等于 num_new_pages 时越界
        # 被 clamp 的行 need_new_pages == 0,后续会被 * 0 屏蔽,不影响结果
        start_new_pages = start_new_pages.clamp(max=num_new_pages - 1)
        out_indices = (last_loc + 1) * (1 - need_new_pages) + self.free_pages[
            start_new_pages
        ] * self.page_size * need_new_pages
​
    # ...(debug 断言和更新 free_pages)
    return out_indices.int()

评论区精华

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

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

风险与影响

该变更仅增加了一行 clamp 操作,逻辑简单,风险较低。但未添加针对该边界情况的单元测试,可能在未来重构中再次引入回归。此外,该修复仅针对 NPU 后端,其他后端的类似逻辑是否存在相同问题值得检查。

影响范围集中在 NPU 后端的 KV 缓存分配路径,解决了在特定内存紧张场景下的崩溃问题。对正常路径无性能影响,提高了 NPU 后端的稳定性。

缺少测试覆盖

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论