执行摘要
本PR优化了FastDeploy中PD Disaggregation场景下的抢占请求处理,通过将抢占请求的KV cache写入storage后端以提升缓存复用率,并调整调度逻辑避免死锁。关键变更包括新增环境变量控制、调度器写cache逻辑和缓存管理函数参数调整,影响系统性能和稳定性,但review中未解决锁内调用和类型一致性等风险,需后续关注。
功能与动机
根据PR作者juncaipeng的描述,此变更旨在解决三个核心问题:
- 优化抢占请求处理:当启用缓存池化时,抢占请求的KV cache应写入storage,以便后续请求复用,减少重复计算开销。
- 资源预留调整:p实例向d实例申请block时,d实例需为运行中的请求预留block ids,避免资源竞争导致的调度失败。
- 修复数据修改bug:原write_cache_to_storage函数在构造token_ids时会意外修改request中的prompt_token_ids,本PR通过引入中间变量input_token_ids修复此问题。
实现拆解
实现方案按模块拆解如下:
| 模块 | 关键文件 | 主要变更 |
|------|----------|----------|
| 调度器 | fastdeploy/engine/sched/resource_manager_v1.py | 在_trigger_preempt函数中添加条件检查,当环境变量FD_SAVE_OUTPUT_CACHE_FOR_PREEMPTED_REQUEST开启且storage backend启用时,调用write_cache_to_storage或write_cache_to_storage_decode;调整preallocate_resource_in_d函数使用_get_can_schedule_prefill_threshold_block计算总需blocks。 |
| 缓存管理器 | fastdeploy/cache_manager/prefix_cache_manager.py | 修改can_allocate_gpu_blocks函数,新增try_free_gpu_blocks参数(默认True),在request_match_blocks中设为False以避免死锁;修复write_cache_to_storage和write_cache_to_storage_decode函数,防止修改原始token_ids。 |
| 环境配置 | fastdeploy/envs.py | 新增环境变量FD_SAVE_OUTPUT_CACHE_FOR_PREEMPTED_REQUEST,默认值1,控制是否在抢占时保存cache到storage。 |
| 缓存传输 | fastdeploy/cache_manager/cache_transfer_manager.py | 调整read_storage_task函数,在token_ids为空时传入None,减少跨进程数据量。 |
| 引擎 | fastdeploy/engine/common_engine.py | 将日志级别从error改为warning,降低错误处理噪音。 |
评论区精华
Review讨论中,Copilot作为主要评论者,提出了多项关键洞察:
- 环境变量细节:
"这里的注释里 preemted 拼写错误,建议更正为 preempted,避免后续搜索/文档引用时产生歧义。"
"这个环境变量是新引入的'是否开启'开关,但默认值设为 '1' 会导致默认启用写入 storage 的行为,可能带来额外 I/O 与延迟,并改变历史默认行为。"
- 设计风险:
"在 schedule() 持有 self.lock 的情况下,这里同步调用 write_cache_to_storage*() 可能会把潜在的 I/O/等待放到调度锁里,导致调度线程长时间阻塞甚至影响并发。"
- 类型一致性:
"ReadStorageTask/CacheTask 的 token_ids 在类型标注里是 List[int] 且为必填字段,但这里在非 attention_store 后端时传入 None。建议统一传入空列表([])或把 CacheTask.token_ids 改为 Optional[List[int]]。"
- 测试覆盖:
"新增的'preempt 时写 cache 到 storage'逻辑目前在单测中没有覆盖...建议补充对应的单元测试,避免该关键路径在后续重构中回归。"
作者juncaipeng在部分评论中简要解释修改原因,如"避免可能的死锁卡住"和"减少跨进程传输的数据量",但未直接回应风险建议。
风险与影响
技术风险:
- 性能瓶颈:调度锁内同步I/O操作可能阻塞线程,放大抢占路径的尾延迟,影响系统响应时间。
- 运行时错误:token_ids传入None违反类型约定,若后续代码无条件操作可能引发异常。
- 行为变更:环境变量默认开启改变历史行为,未评估场景下可能引入不必要I/O开销。
- 回归风险:缺少单元测试,Codecov报告显示patch覆盖率仅57.14286%,新增逻辑易在重构中失效。
影响评估:
- 正面影响:提升缓存复用率,减少抢占请求的重新计算,优化PD Disaggregation资源利用率。
- 负面影响:默认开启写cache可能增加存储I/O和延迟;未解决的设计风险可能降低系统并发性。
- 团队影响:需关注环境变量配置和类型约定,review中未决问题提示后续开发需加强设计评审。
关联脉络
从同仓库近期历史PR分析,本PR与多个KVCache和Scheduler相关变更形成关联脉络:
- PR #6929:修复KVCache中hash边界比较bug,共享缓存管理逻辑,显示前缀缓存计算的持续优化。
- PR #6992:新增中断请求端点,涉及Scheduler和KVCache资源管理,与本PR的抢占处理互补。
- PR #7046 和 #7075:关于KVCache storage cache的锁添加与回滚,突显缓存并发控制的复杂性,与本PR中锁内调用风险相呼应,提示团队在类似场景需谨慎权衡同步与异步设计。
整体上,这些PR共同推动FastDeploy在缓存持久化和调度优化方向的演进,本PR作为其中一环,强化了抢占场景下的缓存复用能力,但遗留的设计争议需在后续迭代中解决。
参与讨论