Skip to content

[feature] provide lock free scheduler#7937

Draft
liyonghua0910 wants to merge 2 commits into
PaddlePaddle:developfrom
liyonghua0910:develop+20260526_lockfree_scheduler
Draft

[feature] provide lock free scheduler#7937
liyonghua0910 wants to merge 2 commits into
PaddlePaddle:developfrom
liyonghua0910:develop+20260526_lockfree_scheduler

Conversation

@liyonghua0910
Copy link
Copy Markdown
Collaborator

Motivation

💡 If this PR is a Cherry Pick, the PR title needs to follow the format by adding the [Cherry-Pick] label at the very beginning and appending the original PR ID at the end. For example, [Cherry-Pick][CI] Add check trigger and logic(#5191)

💡 如若此PR是Cherry Pick,PR标题需遵循格式,在最开始加上[Cherry-Pick]标签,以及最后面加上原PR ID,例如[Cherry-Pick][CI] Add check trigger and logic(#5191)

Modifications

Usage or Command

Accuracy Tests

Checklist

  • Add at least a tag in the PR title.
    • Tag list: [[FDConfig],[APIServer],[Engine], [Scheduler], [PD Disaggregation], [Executor], [Graph Optimization], [Speculative Decoding], [RL], [Models], [Quantization], [Loader], [OP], [KVCache], [DataProcessor], [BugFix], [Docs], [CI], [Optimization], [Feature], [Benchmark], [Others], [XPU], [HPU], [GCU], [DCU], [Iluvatar], [Metax]]
    • You can add new tags based on the PR content, but the semantics must be clear.
  • Format your code, run pre-commit before commit.
  • Add unit tests. Please write the reason in this PR if no unit tests.
  • Provide accuracy results.
  • If the current PR is submitting to the release branch, make sure the PR has been submitted to the develop branch, then cherry-pick it to the release branch with the [Cherry-Pick] PR tag.

@paddle-bot
Copy link
Copy Markdown

paddle-bot Bot commented May 27, 2026

Thanks for your contribution!

PaddlePaddle-bot

This comment was marked as outdated.

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 27, 2026

Codecov Report

❌ Patch coverage is 42.51208% with 119 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (develop@8bb4479). Learn more about missing BASE report.

Files with missing lines Patch % Lines
fastdeploy/engine/sched/resource_manager_v2.py 40.66% 89 Missing ⚠️
fastdeploy/engine/sched/request_manager.py 33.33% 12 Missing ⚠️
fastdeploy/output/token_processor.py 10.00% 6 Missing and 3 partials ⚠️
fastdeploy/engine/common_engine.py 40.00% 4 Missing and 2 partials ⚠️
fastdeploy/engine/sched/resource_manager_v1.py 80.00% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             develop    #7937   +/-   ##
==========================================
  Coverage           ?   63.73%           
==========================================
  Files              ?      470           
  Lines              ?    65254           
  Branches           ?     9991           
==========================================
  Hits               ?    41590           
  Misses             ?    20857           
  Partials           ?     2807           
Flag Coverage Δ
GPU 72.76% <42.51%> (?)
XPU 7.15% <35.26%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@PaddlePaddle-bot
Copy link
Copy Markdown

PaddlePaddle-bot commented May 27, 2026

🤖 Paddle-CI-Agent | ci_status_monitor | 2026-05-29 02:26:29

CI报告基于以下代码生成(30分钟更新一次):


1 任务总览

Required 任务尚未全部通过:当前 required 失败任务数 2,等待处理的 required 任务数 0。请优先处理覆盖率门禁失败并完成 Approval。

总执行(rerun次数) 总任务 ✅ 通过 ❌ 失败 ⏳ 运行中 ⏸️ 等待中 跳过
42(0) 42 36 6 0 0 0

2 任务状态汇总

日志列说明:失败任务直接使用 CI 日志链接,运行中任务使用 Job 链接。

2.1 Required任务 : 8/10 通过

必选任务阻塞合并,失败需优先处理。

状态 任务 耗时 根因 修复建议 日志 重跑
Run FastDeploy Unit Tests and Coverage / run_tests_with_coverage 1h23m PR问题:diff覆盖率46%,低于80%阈值 为新增调度代码补充单测覆盖 Job -
Approval 18s 需要 Approval 请通过人工审批 Job -
其余 8 个必选任务通过 - - - - -

2.2 可选任务 — 28/32 通过

可选任务不阻塞合并,失败仅供参考。

状态 任务 耗时 日志 重跑
Run iluvatar Tests / run_iluvatar_cases 2m32s Job -
Check PR Template 21s Job -
CI_HPU 1h4m Job -
Trigger Jenkins for PR 22s Job -
其余 28 个可选任务通过 - - -

3 失败详情(仅 required)

Run FastDeploy Unit Tests and Coverage / run_tests_with_coverage — 覆盖率门禁失败(置信度: 高)

Run FastDeploy Unit Tests and Coverage / run_tests_with_coverage

  • 状态: ❌ 失败
  • 错误类型: 覆盖率门禁失败
  • 置信度: 高
  • 根因摘要: diff覆盖率46%,低于80%阈值
  • 分析器: ci_analyze_unittest_fastdeploy

失败用例: 无。日志显示单元测试已通过,失败发生在覆盖率校验步骤。

根因详情:
CI 日志中 TEST_EXIT_CODE=0 且输出 All tests passed,说明 pytest 单测本身通过;随后 Verify Code Coverage Threshold (80%) 步骤因 COVERAGE_EXIT_CODE=9 失败。上传的 diff_coverage.json 显示本 PR diff 总覆盖率 total_percent_covered=46,低于 80% 阈值;低覆盖主要集中在新增/修改的调度代码:fastdeploy/engine/sched/resource_manager_v2.py 覆盖率 40.67%、fastdeploy/engine/sched/request_manager.py 33.33%、fastdeploy/output/token_processor.py 40%、fastdeploy/engine/common_engine.py 60%。这与 PR 新增 lock-free scheduler、RequestManager、V2 开关及资源回收分支直接相关。

关键日志:

All tests passed
Coverage generation failed (exit code 9)
GPU Patch Coverage Details:
"fastdeploy/engine/sched/resource_manager_v2.py": {"percent_covered": 40.666666666666664, ...}
"fastdeploy/engine/sched/request_manager.py": {"percent_covered": 33.33333333333334, ...}
"fastdeploy/output/token_processor.py": {"percent_covered": 40.0, ...}
"fastdeploy/engine/common_engine.py": {"percent_covered": 60.0, ...}
"total_num_lines": 207, "total_num_violations": 111, "total_percent_covered": 46
Process completed with exit code 9.

修复建议:

  1. fastdeploy/engine/sched/resource_manager_v2.py 补充单测,覆盖 _drain_messagesschedule/prefill_schedulefinish_requests、同步查询 _sync_query 及各 _process_* 分支。
  2. fastdeploy/engine/sched/request_manager.py 补充单测,覆盖 acquire_slotrelease_slotget_available_position 成功/无可用槽异常、available_batch
  3. 补充 ENABLE_V2_KVCACHE_SCHEDULER 分支相关测试,覆盖 fastdeploy/engine/common_engine.py:175-181fastdeploy/output/token_processor.py:605-631 的 V2/V1 开关逻辑。

修复建议摘要: 为新增调度代码补充单测覆盖

关联变更: fastdeploy/engine/sched/resource_manager_v2.pyfastdeploy/engine/sched/request_manager.pyfastdeploy/engine/common_engine.py:175-181fastdeploy/output/token_processor.py:605-631

Approval — 需要人工 Approval(置信度: 高)

该 Job 需要人工 Approval,完成审批后 CI 才会继续执行。

Copy link
Copy Markdown

@PaddlePaddle-bot PaddlePaddle-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Paddle-CI-Agent | pr_review | 2026-05-27 15:49:11

📋 Review 摘要

PR 概述:新增无锁调度器 ResourceManagerV2(基于消息队列)及 V1 的 prefill_schedule() P 实例专用调度路径。

变更范围fastdeploy/engine/sched/fastdeploy/engine/common_engine.pyfastdeploy/output/token_processor.pyfastdeploy/envs.py

影响面 Tag[Scheduler] [Engine] [PD Disaggregation] [DataProcessor]

问题

级别 文件 概述
🔴 Bug fastdeploy/engine/common_engine.py:1131 splitwise_role=="prefill" 时无条件调用 prefill_schedule(),默认 ResourceManager 无此方法,会 AttributeError

历史 Findings 修复情况

Finding 问题 状态
F1 event.wait() 无超时,存在永久阻塞风险 ⚠️ 仍存在
F2 release_slot_enqueue_msg 之间存在竞态窗口 ⚠️ 仍存在
F3 _process_add_request 手动复制 V1 逻辑而非调用 super() ⚠️ 仍存在
F4 token_processor.py 中重复的 ENABLE_V1_KVCACHE_SCHEDULER 运行时校验 ⚠️ 仍存在

📝 PR 规范检查

标题 [feature] 不在官方 Tag 列表中(大小写不符),描述各 section 均为空,本次 PR 未修复。

标题建议(可直接复制):

  • [Scheduler] provide lock-free scheduler (ResourceManagerV2)
PR 描述建议(点击展开,可直接复制)
## Motivation
V1 调度器通过全局锁保护状态变更,外部线程(token_processor、splitwise connector 等)在高并发场景下频繁竞争锁,影响调度吞吐。V2 通过消息队列将所有状态变更序列化到 schedule() 单写线程,消除锁竞争。

## Modifications
- 新增 `fastdeploy/engine/sched/request_manager.py`:统一封装 slot 分配/释放接口(`acquire_slot` / `release_slot` / `get_available_position` / `available_batch`- 新增 `fastdeploy/engine/sched/resource_manager_v2.py`:继承 V1,替换全局锁为 `_NoOpLock`,外部线程调用通过 `deque` 消息队列异步化;P/D 分离的同步查询方法通过 `threading.Event` Future 机制实现
- `fastdeploy/engine/sched/__init__.py`:导出 `RequestManager``ResourceManagerV1``ResourceManagerV2`
- `fastdeploy/engine/common_engine.py`:新增 `ENABLE_V2_KVCACHE_SCHEDULER` 分支,优先于 V1 初始化;P 实例调度路径切换为 `prefill_schedule()`
- `fastdeploy/envs.py`:新增环境变量 `ENABLE_V2_KVCACHE_SCHEDULER`(默认 0)
- `fastdeploy/output/token_processor.py``_recycle_resources` 中新增 V2 分支,调用 `finish_requests`(同步入队)替代 V1 的 `finish_requests_async`

## Usage or Command
```bash
export ENABLE_V1_KVCACHE_SCHEDULER=1
export ENABLE_V2_KVCACHE_SCHEDULER=1
# 启动服务后 V2 无锁调度器生效
```

## Accuracy Tests
N/A(调度器变更不影响模型输出)

## Checklist

- [x] Add at least a tag in the PR title.
  - Tag list: [`[FDConfig]`,`[APIServer]`,`[Engine]`, `[Scheduler]`, `[PD Disaggregation]`, `[Executor]`, `[Graph Optimization]`, `[Speculative Decoding]`, `[RL]`, `[Models]`, `[Quantization]`, `[Loader]`, `[OP]`, `[KVCache]`, `[DataProcessor]`, `[BugFix]`, `[Docs]`, `[CI]`, `[Optimization]`, `[Feature]`, `[Benchmark]`, `[Others]`, `[XPU]`, `[HPU]`, `[GCU]`, `[DCU]`, `[Iluvatar]`, `[Metax]`]
  - You can add new tags based on the PR content, but the semantics must be clear.
- [ ] Format your code, run `pre-commit` before commit.
- [ ] Add unit tests. Please write the reason in this PR if no unit tests.
- [x] Provide accuracy results.
- [ ] If the current PR is submitting to the `release` branch, make sure the PR has been submitted to the `develop` branch, then cherry-pick it to the `release` branch with the `[Cherry-Pick]` PR tag.

总体评价

无锁调度器设计思路清晰,通过消息队列将状态变更序列化到调度线程。本次新增了 prefill_schedule() P 实例专用路径,但该方法被无条件调用于所有 resource_manager 实例存在兼容性 Bug,需修复。历史遗留的 F1(event.wait 无超时)、F2(竞态窗口)问题建议尽快跟进。

# 2. Schedule requests
batch_request, error_tasks = self.resource_manager.schedule()
if self.cfg.scheduler_config.splitwise_role == "prefill":
batch_request, error_tasks = self.resource_manager.prefill_schedule()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 BugENABLE_V1_KVCACHE_SCHEDULER=0(使用默认 ResourceManager)且 splitwise_role=="prefill" 时,此处调用 self.resource_manager.prefill_schedule() 会触发 AttributeError,因为默认 ResourceManager 没有该方法。

prefill_schedule() 仅在 ResourceManagerV1(及继承它的 V2)中定义,但当前代码无条件地对所有 resource_manager 实例调用。

建议修复方式:

if self.cfg.scheduler_config.splitwise_role == "prefill" and hasattr(self.resource_manager, "prefill_schedule"):
    batch_request, error_tasks = self.resource_manager.prefill_schedule()
else:
    batch_request, error_tasks = self.resource_manager.schedule()

或者在 ResourceManager 基类中定义 prefill_schedule() 并回退到 schedule(),确保接口一致。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants