Prhub

#7364 [BugFix][PD Disaggregation][KVCache] Fix low cache hit rate in PD split (disaggregation) scenario

PaddlePaddle/FastDeploy · 作者 kevincheng2 · 合并时间 2026-04-14 16:15

分析状态 已生成
文件变更 1提交数 1 · 评论 5
代码增减 +6 / -0
bugfix KVCache Scheduler Engine

执行摘要

修复 PD 分离场景下 prefill 节点未及时更新 prefix cache 命中信息导致的低命中率问题。

根据PR body描述,在PD分离场景下,prefill节点收到请求后未能及时更新prefix cache block的命中信息,导致prefix cache命中率异常偏低,影响推理性能。具体问题是prefill节点在通过_allocate_gpu_blocks成功分配block后,没有调用update_cache_blocks更新cache block状态,导致已命中的prefix cache无法被正确记录。

该PR值得精读,特别是关注prefill节点在PD分离架构中的cache状态管理设计。建议重点关注:1. update_cache_blocks参数选择的权衡(need_prefill_tokens vs num_computed_tokens)及其对cache一致性的影响;2. PD分离模式下prefill与decode节点职责划分的边界设计。

讨论亮点

review中主要讨论了update_cache_blocks参数选择的正确性问题。fastdeploy-bot指出使用request.need_prefill_tokens作为num_computed_tokens参数可能导致cache state不一致,建议使用request.num_computed_tokens更合适。Copilot进一步解释使用need_prefill_tokens会让PrefixCacheManager认为整段prompt都已计算完成,可能为cache miss部分提前创建radix tree节点并绑定未填充的GPU block,造成错误复用或状态污染,建议改为使用request.num_computed_tokens或延后调用时机。但作者未回应这些建议,最终代码仍使用need_prefill_tokens。

实现拆解

本次变更仅修改了fastdeploy/engine/sched/resource_manager_v1.py文件,包含两处关键改动:1. 在_free_blocks_when_stop方法中,将update_cache_blocks的触发条件从仅排除decode节点扩展为同时排除prefill节点(新增and self.config.scheduler_config.splitwise_role != "prefill"),避免prefill节点重复更新cache block状态。2. 在preallocate_resource_in_p方法中,prefill节点成功分配block后,主动调用cache_manager.update_cache_blocks,使用request.need_prefill_tokens作为已计算token数量参数。

文件 模块 状态 重要度
fastdeploy/engine/sched/resource_manager_v1.py Engine/Scheduler modified 8.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

_allocate_decode_and_extend preallocate_resource_in_p update_cache_blocks

评论区精华

update_cache_blocks 参数选择正确性 正确性

fastdeploy-bot 和 Copilot 均指出使用 request.need_prefill_tokens 作为 num_computed_tokens 参数可能导致 cache 状态不一致,建议使用 request.num_computed_tokens 或调整调用时机。

结论:作者未回应建议,最终代码仍使用 need_prefill_tokens,问题未解决。 · unresolved

风险与影响

主要风险在于update_cache_blocks参数选择可能导致的cache状态不一致:1. 当只有部分prompt tokens命中cache时,使用need_prefill_tokens(所有prompt tokens)而非num_computed_tokens(已命中tokens)可能导致cache tree记录的cached blocks数量与实际不一致。2. 可能为未填充的GPU block创建radix tree节点,后续请求可能匹配到未完成的cache,造成错误复用。此外,变更涉及PD分离核心调度逻辑,但缺少单元测试(PR body中说明需要端到端PD分离环境验证),回归风险需通过集成测试保障。

直接影响PD分离场景下的prefix cache命中率,修复后应显著提升,从而改善推理性能。影响范围限于使用PD分离模式的服务,对非分离模式无影响。对用户透明,无需配置变更。对团队而言,修复了调度器与cache管理器间的状态同步漏洞,但参数选择争议未解决可能遗留潜在问题。

核心路径变更 缺少测试覆盖 参数选择争议

关联 Issue

未识别关联 Issue

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

完整报告

执行摘要

本次PR修复了PD分离(disaggregation)场景下prefill节点未及时更新prefix cache命中信息导致的低命中率问题,通过在调度器的preallocate_resource_in_p方法中主动调用update_cache_blocks并调整角色排除逻辑,确保cache状态正确同步。变更直接影响PD分离模式的推理性能,但参数选择争议未解决可能遗留cache状态不一致风险。

功能与动机

在PD分离场景中,prefill节点负责处理prompt的预填充,但成功分配GPU block后未更新prefix cache的命中信息,导致已命中的cache无法被正确记录,命中率异常偏低,影响推理性能。PR body明确指出:“prefill 节点在通过 _allocate_gpu_blocks 成功分配block后,没有调用 update_cache_blocks 更新 cache block 状态,导致已命中的 prefix cache 无法被正确记录”。

实现拆解

仅修改fastdeploy/engine/sched/resource_manager_v1.py文件,包含两处关键改动:

  1. 调整_allocate_decode_and_extend中的角色排除逻辑
    python if ( self.config.cache_config.enable_prefix_caching and self.config.scheduler_config.splitwise_role != "decode" and self.config.scheduler_config.splitwise_role != "prefill" # 新增排除prefill ):
    避免prefill节点在_free_blocks_when_stop中重复更新cache block状态。

  2. preallocate_resource_in_p中主动更新cache block
    python self.cache_manager.update_cache_blocks( request, self.config.cache_config.block_size, request.need_prefill_tokens )
    prefill节点分配block后立即调用,使用need_prefill_tokens作为已计算token数量。

评论区精华

review中聚焦于update_cache_blocks参数选择的正确性:

  • fastdeploy-bot指出:“使用 request.need_prefill_tokens 作为 update_cache_blocks 的第三个参数需要进一步说明...当只有部分 prompt tokens 命中 cache 时,使用 need_prefill_tokens 可能导致 cache tree 中记录的 cached blocks 数量与实际不一致。”
  • Copilot进一步解释:“传入 request.need_prefill_tokens 会让 PrefixCacheManager 认为整段 prompt 都已‘计算完成’,从而为 cache miss 部分也提前创建 radix tree 节点并绑定新分配的 GPU block...可能造成错误复用或状态污染。”
    但作者未回应这些建议,最终代码仍使用need_prefill_tokens

风险与影响

风险

  1. cache状态不一致:当部分prompt命中cache时,使用need_prefill_tokens(所有prompt tokens)而非num_computed_tokens(已命中tokens)可能导致cache tree记录不准确。
  2. 错误复用风险:可能为未填充的GPU block创建radix tree节点,后续请求匹配到未完成的cache。
  3. 回归风险:变更涉及调度器核心路径,但缺少单元测试(PR body说明需端到端PD分离环境验证)。

影响

  • 正面:修复后应显著提升PD分离场景的prefix cache命中率,改善推理性能。
  • 范围:仅影响PD分离模式,对非分离模式无影响。
  • 用户:透明修复,无需配置变更。

关联脉络

本次修复是FastDeploy在PD分离架构优化中的一环:

  • PR #7241(移除KV Cache块数上限)同样关注cache利用率提升。
  • PR #7299(移除CacheManager与WorkerProcess间IPCLock)优化了cache相关组件交互。
  • PR #7323(支持PD分离模式下MTP超重叠)同样针对PD分离模式进行调度优化。
    这些PR共同反映了团队对PD分离场景性能的持续打磨,特别是调度器与cache管理器的协同优化。

参与讨论