Prhub

#36425 HiCache: avoid unnecessary all-reduce in check_prefetch_progress

原始 PR 作者 stepinto 合并时间 2026-08-29 00:52 文件变更 2 提交数 6 评论 5 代码增减 +21 / -15

执行摘要

优化 HiCache 预取进度检查,减少不必要 all-reduce

作为 PR#27010 的后续修复,PR#27010 引入了 all-reduce 来保证 PP/TP 下各 rank 对预取状态达成一致,但 check_prefetch_progress 在每次调用时都会无条件执行 all-reduce,即使在 best_effort 或 wait_complete 策略下,或预取已经完成的情况下,这种同步也是不必要的。这些场景下,可以直接本地判断终止条件,避免额外的通信开销。HICache 作为提升 LLM 推理性能的缓存机制,降低调度路径上的通信开销对于缩短 TTFT 有直接意义。

该 PR 值得精读,尤其是对于理解 HiCache 在 PP/TP 下的同步机制,以及如何通过按需执行集合通信来优化性能。其设计决策(将 all-reduce 从公共路径中移出,仅保留在需要跨 rank 一致的 timeout 分支)具有借鉴意义。建议关注 _can_terminate_prefetch 上的 rank_consensus 装饰器的作用,以及未来可能对测试覆盖的补充。

讨论亮点

Review 讨论主要涉及 CI 测试的失败和修复:

  • hzh0425 通过 /rerun-group radix_cache/unified_radix_tree 触发了相关测试的重跑,结果显示 4 个测试失败,包括 test_unified_radix_cache_pp_kl.py 等。
  • stepinto 指出测试失败是由于 main 分支上的已有问题(TestUnifiedDeepSeekV4FlashDSparkHiCacheL3)以及函数重命名未同步到测试文件所致,并进行了相应修复。
  • 最终 hzh0425 予以批准,评论中附带了构建通过的截图。

实现拆解

实现拆解分为以下几步:

  1. 重构终止判断逻辑:在 python/sglang/srt/mem_cache/unified_radix_cache.py 中,将原来的 can_terminate_prefetch 方法重命名为 _can_terminate_prefetch,并为其添加 @rank_consensus(same_results=True) 装饰器。这意味着该方法的返回值需要在所有 rank 间保持一致。
  2. 按策略优化 all-reduce:在 _can_terminate_prefetch 中,对于 best_effortwait_complete 策略,直接返回固定值(TrueFalse),不执行 any all-reduce。对于 timeout 策略,则保留原有的逻辑:由 pp_rank == 0 的 rank 根据本地时钟判断是否超时,然后通过 all-reduce(ReduceOp.MAX)同步给所有 rank,确保所有 rank 得到一致的终止决定。这样既保证了 timeout 策略下跨 rank 的一致性,又避免了其他场景下的额外通信。
  3. 简化 check_prefetch_progresscheck_prefetch_progress 本身不再直接执行 all-reduce,而是调用 _can_terminate_prefetch 来获取终止决定。由于 _can_terminate_prefetch 已经封装了 rank 一致性逻辑,check_prefetch_progress 的代码变得更简洁,且避免了在预取尚未完成和已完成等场景下的不必要同步。
  4. 同步测试修改:在 test/registered/unit/mem_cache/test_unified_radix_cache_unittest.py 中,将针对 can_terminate_prefetch 的 mock 调用更新为 _can_terminate_prefetch,以匹配重命名后的函数。
文件 模块 状态 重要度
python/sglang/srt/mem_cache/unified_radix_cache.py 缓存层 modified 7.21
test/registered/unit/mem_cache/test_unified_radix_cache_unittest.py 单元测试 modified 3.59

关键符号

_can_terminate_prefetch check_prefetch_progress

关键源码片段

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

核心逻辑修改:将 all-reduce 从 check_prefetch_progress 中移除,并封装到 _can_terminate_prefetch,仅在 timeout 策略下执行。

@rank_consensus(same_results=True)
def _can_terminate_prefetch(self, operation: PrefetchOperation) -> bool:
    """判断预取是否可以终止。    该函数需要所有 rank 返回一致的结果,因此使用 rank_consensus 装饰器。
    在 best_effort 和 wait_complete 策略下,可以直接返回固定值,避免不必要的 all-reduce
    通信。仅在 timeout 策略下,由于各个 rank 的墙钟时间可能不同,需要通过 all-reduce
    来同步决策,防止 PP/TP 各 rank 分歧。
    """
    if self.prefetch_stop_policy == "best_effort":
        return True
    if self.prefetch_stop_policy == "wait_complete":
        return False
    elif self.prefetch_stop_policy == "timeout":
        # 各 rank 的墙钟时间可能不同,需要通过 all-reduce 确保所有 rank 得到相同的最终结果,
        # 否则 PP/TP 各 rank 会发散。
        #
        # 对于 TP,只要任一 rank 超时,最终结果就判定为超时。
        #
        # 对于 PP,由 PP0 做决策,其他 rank 跟随 PP0 的决策。
        should_terminate = False
        if self.pp_rank == 0:
            should_terminate = self._prefetch_timeout_check_linear_func(operation)
        should_terminate_tensor = torch.tensor(
            int(should_terminate), dtype=torch.int, device="cpu"
        )
        self._all_reduce(should_terminate_tensor, torch.distributed.ReduceOp.MAX)
        return should_terminate_tensor.item() == 1
    else:
        return True

评论区精华

CI 测试失败与修复 测试

reviewer 触发了相关 CI 测试,结果显示多个测试失败。author 指出失败是由于 main 分支已有的问题以及函数重命名未同步到测试。

结论:author 更新代码修复了测试,最终 CI 通过。 · 已解决

风险与影响

主要风险在于 timeout 策略下的 all-reduce 逻辑变更:

  • 如果 all-reduce 未正确调用或 rank 间时钟偏差过大,可能导致各 rank 对预取终止状态产生分歧,引发 PP 下调度不一致,但该逻辑继承了 PR#27010 的原有设计,风险可控。
  • 另外,_can_terminate_prefetch@rank_consensus 修饰,要求所有 rank 调用同一路径,但 best_effort 和 wait_complete 路径没有显式的 all-reduce,若未来这些策略的决策依赖全局状态,则可能存在隐患。
  • 测试仅更新了 mock 名称,并未新增针对 all-reduce 移除的专项测试,覆盖不足。

影响范围:HiCache L3 预取的调度路径,主要影响启用 HiCache 的 PP/TP 分布式推理场景。
用户/系统影响:在 best_effort 和 wait_complete 策略下,消除了每请求的 all-reduce 通信,降低了调度开销,有助于缩短 TTFT(作者测试显示轻微改善)。TP 下 timeout 策略的通信量不变,但减少了在预取完成后的同步调用。
团队影响:由于改动集中在 UnifiedRadixCache 内部,对外部 API 无影响,测试代码同步更新,对团队维护影响较小。

核心路径变更 缺少新增测试

关联 Issue

#27010 [HiCache] Fix PP inconsistency with HiCache L3 (#22607)

完整报告

参与讨论