Prhub

#6680 [Optimization] Optimize ttft for prefill pd

PaddlePaddle/FastDeploy · 作者 rainyfly · 合并时间 2026-03-30 20:36

分析状态 已生成
文件变更 11提交数 28 · 评论 22
代码增减 +136 / -137
Optimization Scheduler

执行摘要

优化 PD 预填充场景下的调度逻辑,减少排队并提升批处理效率。

根据PR body描述,动机是“之前scheduler和worker是完全异步分开进行的,schedule()会在引擎forward开始前发生并立即结束,容易造成每次调度的请求量不满,从而让请求易发生排队”。优化目的是在引擎forward结束后再进行schedule(),以达到最佳组batch效果。

面向技术管理者和工程师,建议:

  • 精读重点:该PR值得精读,特别是engine_forward_signal的设计和调度时机变化,这些是性能优化的关键决策点。
  • 关注设计:留意讨论中的并发优化建议和接口语义问题,可应用于其他调度优化场景。
  • 跟进风险:建议后续补充测试覆盖,并监控生产环境中的性能表现和并发问题。
讨论亮点

review讨论的核心要点包括:

  • 锁竞争优化:Copilot建议在common_engine.py中使用exist_tasks()代替num_tasks()以减少锁竞争,rainyfly已采纳修改。
  • 空任务推送开销:Copilot指出EP空闲时频繁推送空任务可能增加CPU/IPC开销,rainyfly解释为同步需要,保持原逻辑。
  • 信号同步问题:Copilot担忧engine_forward_signal在多TP rank下的并发写入可能导致竞态,建议只让tp_rank 0更新,但rainyfly认为无影响,未采纳。
  • 接口语义模糊:Copilot批评dp_scheduler.py中get_requests函数参数未使用,接口语义不一致,此问题未明确解决,可能需后续重构。
  • 逻辑细节与注释:Jiang-Jia-Jun强调添加注释和警告日志,rainyfly已更新注释并改用assert处理空任务。

实现拆解

实现方案拆解为以下模块:

  1. 引擎层(Engine):在fastdeploy/engine/common_engine.py中新增engine_forward_signal(IPCSignal),用于标记forward状态;修改_schedule_request_to_worker_v1函数,在forward期间累积请求(通过检查engine_forward_signal.value[0] != 0),结束后统一调度;为EP并行添加空任务推送逻辑以同步worker。
  2. Worker层:在fastdeploy/worker/worker_process.py中修改event_loop_normal函数,在检测到新请求时设置engine_forward_signal为1,forward结束时置0;调整任务处理逻辑,支持空任务barrier;简化init_health_status以初始化信号。
  3. 调度器层(Scheduler):在fastdeploy/scheduler/dp_scheduler.py中简化get_requests函数,移除资源检查逻辑,改为只取一个请求,以适应V1资源管理。
  4. 文档和环境变量:移除FD_EP_BATCHED_TOKEN_TIMEOUT环境变量及其相关文档(docs/usage/environment_variables.md, fastdeploy/envs.py)。
  5. 测试更新:调整测试文件(如tests/engine/test_common_engine.py, tests/scheduler/test_dp_scheduler.py)以适应新逻辑,并注释不稳定测试。
文件 模块 状态 重要度
fastdeploy/engine/common_engine.py Engine modified 8.0
fastdeploy/worker/worker_process.py Worker modified 7.0
fastdeploy/scheduler/dp_scheduler.py Scheduler modified 6.0

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

关键符号

_schedule_request_to_worker_v1 event_loop_normal init_health_status get_requests

评论区精华

engine_forward_signal 锁竞争优化 性能

Copilot 建议在 common_engine.py 中使用 exist_tasks() 代替 num_tasks() 以减少锁竞争和调度线程开销。

结论:rainyfly 采纳建议并修改为使用 exist_tasks(),以减少开销。 · 已解决

空任务推送频率开销 性能

Copilot 指出在 EP 空闲时频繁推送空任务可能增加 CPU/IPC 开销,建议节流或使用轻量 signal。

结论:rainyfly 解释为同步需要,保持原逻辑,认为开销可接受。 · addressed

engine_forward_signal 多 TP 同步 正确性

Copilot 担忧多 TP rank 下同时写入 engine_forward_signal 可能导致竞态,建议只让 tp_rank 0 更新并同步。

结论:rainyfly 表示多 TP 下无影响,未采纳建议,认为当前逻辑正确。 · closed

DP scheduler 接口语义 设计

Copilot 指出 get_requests 函数参数未使用,接口语义不一致,可能误导调用方。

结论:未明确解决,rainyfly 未回复此点,可能需要后续重构或文档更新。 · unresolved

worker 处理逻辑注释和细节 正确性

Jiang-Jia-Jun 询问 tasks[0][0] 判断逻辑并建议添加警告日志,以避免潜在卡死问题。

结论:rainyfly 添加注释并改用 assert 处理空任务,部分细节已澄清。 · 已解决

风险与影响

技术风险具体如下:

  1. 并发风险:engine_forward_signal在多TP rank下的写入可能引入竞态,影响调度时机正确性(fastdeploy/worker/worker_process.py)。
  2. 性能开销:在EP空闲时频繁推送空任务(fastdeploy/engine/common_engine.py)可能增加不必要的IPC和CPU开销,影响系统功耗和延迟抖动。
  3. 接口兼容性:dp_scheduler.py的get_requests函数参数未使用,接口语义模糊,可能误导后续维护者或调用方。
  4. 测试覆盖不足:Codecov报告显示50.9%的补丁覆盖率,新增调度逻辑(如engine_forward_signal gating)缺少单元测试,增加回归风险。
  5. 回归风险:移除FD_EP_BATCHED_TOKEN_TIMEOUT环境变量可能影响依赖此超时的旧配置或系统。

影响范围和程度:

  • 用户影响:对使用PD disaggregation的用户,此优化有望减少TTFT,提升请求响应速度和吞吐量,改善用户体验。
  • 系统影响:修改核心调度路径(引擎和worker交互),可能影响所有PD相关推理任务;性能提升但需监控并发开销。
  • 团队影响:工程师需理解新调度时机和信号机制,以避免后续修改引入回归;技术管理者可借鉴设计决策进行类似优化。
核心路径变更 并发风险 接口语义模糊 测试覆盖不足

关联 Issue

未识别关联 Issue

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

完整报告

执行摘要

  • 一句话:优化PD预填充场景下的调度逻辑,减少排队并提升批处理效率。
  • 推荐动作:面向技术管理者和工程师,建议:
  • 精读重点:该PR值得精读,特别是engine_forward_signal的设计和调度时机变化,这些是性能优化的关键决策点。
  • 关注设计:留意讨论中的并发优化建议和接口语义问题,可应用于其他调度优化场景。
  • 跟进风险:建议后续补充测试覆盖,并监控生产环境中的性能表现和并发问题。

功能与动机

根据PR body描述,动机是“之前scheduler和worker是完全异步分开进行的,schedule()会在引擎forward开始前发生并立即结束,容易造成每次调度的请求量不满,从而让请求易发生排队”。优化目的是在引擎forward结束后再进行schedule(),以达到最佳组batch效果。

实现拆解

实现方案拆解为以下模块:

  1. 引擎层(Engine):在fastdeploy/engine/common_engine.py中新增engine_forward_signal(IPCSignal),用于标记forward状态;修改_schedule_request_to_worker_v1函数,在forward期间累积请求(通过检查engine_forward_signal.value[0] != 0),结束后统一调度;为EP并行添加空任务推送逻辑以同步worker。
  2. Worker层:在fastdeploy/worker/worker_process.py中修改event_loop_normal函数,在检测到新请求时设置engine_forward_signal为1,forward结束时置0;调整任务处理逻辑,支持空任务barrier;简化init_health_status以初始化信号。
  3. 调度器层(Scheduler):在fastdeploy/scheduler/dp_scheduler.py中简化get_requests函数,移除资源检查逻辑,改为只取一个请求,以适应V1资源管理。
  4. 文档和环境变量:移除FD_EP_BATCHED_TOKEN_TIMEOUT环境变量及其相关文档(docs/usage/environment_variables.md, fastdeploy/envs.py)。
  5. 测试更新:调整测试文件(如tests/engine/test_common_engine.py, tests/scheduler/test_dp_scheduler.py)以适应新逻辑,并注释不稳定测试。

关键文件:

  • fastdeploy/engine/common_engine.py(模块 Engine): 核心调度逻辑修改,新增engine_forward_signal并调整_schedule_request_to_worker_v1函数,决定调度时机和累积机制。
  • fastdeploy/worker/worker_process.py(模块 Worker): worker处理逻辑调整,更新engine_forward_signal状态、处理空任务同步,影响forward期间的请求接收和调度。
  • fastdeploy/scheduler/dp_scheduler.py(模块 Scheduler): 调度器简化,get_requests函数移除资源检查逻辑,接口语义变化,需关注与V1资源管理的兼容性。

关键符号:_schedule_request_to_worker_v1, event_loop_normal, init_health_status, get_requests

评论区精华

review讨论的核心要点包括:

  • 锁竞争优化:Copilot建议在common_engine.py中使用exist_tasks()代替num_tasks()以减少锁竞争,rainyfly已采纳修改。
  • 空任务推送开销:Copilot指出EP空闲时频繁推送空任务可能增加CPU/IPC开销,rainyfly解释为同步需要,保持原逻辑。
  • 信号同步问题:Copilot担忧engine_forward_signal在多TP rank下的并发写入可能导致竞态,建议只让tp_rank 0更新,但rainyfly认为无影响,未采纳。
  • 接口语义模糊:Copilot批评dp_scheduler.py中get_requests函数参数未使用,接口语义不一致,此问题未明确解决,可能需后续重构。
  • 逻辑细节与注释:Jiang-Jia-Jun强调添加注释和警告日志,rainyfly已更新注释并改用assert处理空任务。

    • engine_forward_signal锁竞争优化 (performance): rainyfly采纳建议并修改为使用exist_tasks(),以减少开销。
    • 空任务推送频率开销 (performance): rainyfly解释为同步需要,保持原逻辑,认为开销可接受。
    • engine_forward_signal多TP同步 (correctness): rainyfly表示多TP下无影响,未采纳建议,认为当前逻辑正确。
    • DP scheduler接口语义 (design): 未明确解决,rainyfly未回复此点,可能需要后续重构或文档更新。
    • worker处理逻辑注释和细节 (correctness): rainyfly添加注释并改用assert处理空任务,部分细节已澄清。

风险与影响

  • 风险:技术风险具体如下:
    1. 并发风险:engine_forward_signal在多TP rank下的写入可能引入竞态,影响调度时机正确性(fastdeploy/worker/worker_process.py)。
    2. 性能开销:在EP空闲时频繁推送空任务(fastdeploy/engine/common_engine.py)可能增加不必要的IPC和CPU开销,影响系统功耗和延迟抖动。
    3. 接口兼容性:dp_scheduler.py的get_requests函数参数未使用,接口语义模糊,可能误导后续维护者或调用方。
    4. 测试覆盖不足:Codecov报告显示50.9%的补丁覆盖率,新增调度逻辑(如engine_forward_signal gating)缺少单元测试,增加回归风险。
    5. 回归风险:移除FD_EP_BATCHED_TOKEN_TIMEOUT环境变量可能影响依赖此超时的旧配置或系统。
  • 影响:影响范围和程度:
  • 用户影响:对使用PD disaggregation的用户,此优化有望减少TTFT,提升请求响应速度和吞吐量,改善用户体验。
  • 系统影响:修改核心调度路径(引擎和worker交互),可能影响所有PD相关推理任务;性能提升但需监控并发开销。
  • 团队影响:工程师需理解新调度时机和信号机制,以避免后续修改引入回归;技术管理者可借鉴设计决策进行类似优化。
  • 风险标记:核心路径变更, 并发风险, 接口语义模糊, 测试覆盖不足

关联脉络

  • 暂无明显关联 PR

参与讨论