[Optimize] Optimize ttft for ep - #6098
Merged
Jiang-Jia-Jun merged 15 commits intoFeb 4, 2026
Merged
Conversation
…into optimize_ttft_for_ep
|
Thanks for your contribution! |
Jiang-Jia-Jun
pushed a commit
that referenced
this pull request
Jan 21, 2026
…into optimize_ttft_for_ep
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #6098 +/- ##
==========================================
Coverage ? 67.66%
==========================================
Files ? 389
Lines ? 51915
Branches ? 8080
==========================================
Hits ? 35130
Misses ? 14234
Partials ? 2551
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Contributor
There was a problem hiding this comment.
Pull request overview
此 PR 优化了专家并行(EP)场景下的调度逻辑,通过将 schedule() 调用时机从引擎 forward 开始前移到 forward 结束后,以实现更好的请求批处理效果。主要目标是优化 Time To First Token (TTFT)。
Changes:
- 引入
engine_forward_signalIPC 信号来协调调度器和 worker 之间的同步 - 简化
DPLocalScheduler.get_requests()方法,移除资源检查和超时逻辑 - 调整 worker 事件循环,将 EP 负载均衡(eplb)操作移至引擎 forward 之后
- 修改调度器循环以等待引擎 forward 完成后再进行调度
- 为 EP 场景添加空任务处理机制
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| fastdeploy/scheduler/dp_scheduler.py | 大幅简化 get_requests 方法,移除资源检查、批处理和超时逻辑;删除 envs 导入 |
| fastdeploy/engine/common_engine.py | 添加 engine_forward_signal 初始化;修改调度循环以等待 forward 完成;为 EP 添加空任务处理 |
| fastdeploy/worker/worker_process.py | 添加 engine_forward_signal 支持;在检测到任务和完成 forward 时设置/重置信号;添加 EP prefill barrier;移动 eplb 调用时机 |
| tests/scheduler/test_dp_scheduler.py | 删除两个测试资源不足场景的测试用例 |
| tests/ci_use/metrics/test_metrics.py | 注释掉验证 clear_load_weight 后指标为 0 的断言 |
Comments suppressed due to low confidence (1)
tests/scheduler/test_dp_scheduler.py:478
- 现有的测试用例 test_get_requests_timeout 和 test_get_requests_no_requests_available 现在已经过时,因为它们仍然 mock envs.FD_EP_BATCHED_TOKEN_TIMEOUT,但新的实现不再使用超时逻辑。
这些测试现在可能会产生误导性结果或给出假阳性。建议:
- 更新这些测试以反映新的实现行为
- 或者删除这些测试,如果它们测试的场景不再适用
- 验证 test_get_requests_successful_batching 仍然正确测试新的行为
保留使用已删除功能的测试会让未来的维护者困惑。
@patch("time.time")
@patch.object(dp_scheduler_module, "envs")
def test_get_requests_no_requests_available(self, mock_envs, mock_time):
"""Test getting requests when no requests are available."""
# Mock envs to return our mock environment
mock_envs.FD_EP_BATCHED_TOKEN_TIMEOUT = 0.1
# Mock time to return consistent values - provide enough values for multiple calls
time_values = [100.0, 100.1, 100.2, 100.3, 100.4, 100.5] # Multiple values for the loop
mock_time.side_effect = time_values
# Mock the condition variable to avoid threading issues
with patch.object(self.scheduler, "requests_not_empty"):
requests = self.scheduler.get_requests(
available_blocks=20, block_size=16, reserved_output_blocks=10, max_num_batched_tokens=1024, batch=1
)
# Should return empty list after timeout
self.assertEqual(requests, [])
def test_get_requests_successful_batching(self):
"""Test successful request batching."""
# Add a mock request
mock_request = MockRequest("test_req", prompt_tokens_ids_len=10)
self.scheduler.requests["test_req"] = mock_request
self.scheduler.ids = ["test_req"]
# Mock calc_required_blocks to return small value
self.scheduler.calc_required_blocks = Mock(return_value=1)
requests = self.scheduler.get_requests(
available_blocks=20, block_size=16, reserved_output_blocks=10, max_num_batched_tokens=1024, batch=1
)
# Should get the request
self.assertEqual(len(requests), 1)
self.assertEqual(requests[0].request_id, "test_req")
@patch("time.time")
@patch.object(dp_scheduler_module, "envs")
def test_get_requests_timeout(self, mock_envs, mock_time):
"""Test request batching with timeout."""
# Mock envs to return our mock environment
mock_envs.FD_EP_BATCHED_TOKEN_TIMEOUT = 0.1
# Mock time to return consistent values - provide enough values for multiple calls
time_values = [100.0, 100.1, 100.2, 100.3, 100.4, 100.5] # Multiple values for the loop
mock_time.side_effect = time_values
# Add a mock request
mock_request = MockRequest("test_req", prompt_tokens_ids_len=10)
self.scheduler.requests["test_req"] = mock_request
self.scheduler.ids = ["test_req"]
# Mock calc_required_blocks to return large value to exceed available blocks
self.scheduler.calc_required_blocks = Mock(return_value=50)
# Mock the condition variable to avoid threading issues
with patch.object(self.scheduler, "requests_not_empty"):
requests = self.scheduler.get_requests(
available_blocks=20, block_size=16, reserved_output_blocks=10, max_num_batched_tokens=1024, batch=1
)
# Should return empty due to timeout
self.assertEqual(requests, [])
…into optimize_ttft_for_ep
Jiang-Jia-Jun
approved these changes
Feb 4, 2026
Jiang-Jia-Jun
pushed a commit
that referenced
this pull request
Feb 9, 2026
kesmeey
pushed a commit
to kesmeey/FastDeploy
that referenced
this pull request
Feb 22, 2026
* optimize ttft * fix * fix * fix ci * fix ci * fix * fix bug * fix * add comments * fix ci * fix
kesmeey
pushed a commit
to kesmeey/FastDeploy
that referenced
this pull request
Feb 22, 2026
…addle#6402) This reverts commit 90db0bd.
chang-wenbin
pushed a commit
to chang-wenbin/FastDeploy
that referenced
this pull request
Mar 2, 2026
* optimize ttft * fix * fix * fix ci * fix ci * fix * fix bug * fix * add comments * fix ci * fix
chang-wenbin
pushed a commit
to chang-wenbin/FastDeploy
that referenced
this pull request
Mar 2, 2026
…addle#6402) This reverts commit 90db0bd.
xiaoguoguo626807
pushed a commit
to xiaoguoguo626807/FastDeploy
that referenced
this pull request
May 7, 2026
* optimize ttft * fix * fix * fix ci * fix ci * fix * fix bug * fix * add comments * fix ci * fix
xiaoguoguo626807
pushed a commit
to xiaoguoguo626807/FastDeploy
that referenced
this pull request
May 7, 2026
…addle#6402) This reverts commit 6efee44.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
优化 zmq -> scheduler -> worker 的调度逻辑。
之前scheduler 和 worker 是完全异步分开进行的,schedule()会在引擎forward开始前发生并立即结束,容易造成每次调度的请求量不满,从而让请求易发生排队。
实际上,在整个引擎 forward 期间,都是可以预处理请求并且接收请求放在scheduler的队列里累积,在引擎 forward 结束后再进行schedule(),此时才能达到最佳组batch的效果。
Modifications
Usage or Command
None
Accuracy Tests
None
Checklist
[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]]pre-commitbefore commit.releasebranch, make sure the PR has been submitted to thedevelopbranch, then cherry-pick it to thereleasebranch with the[Cherry-Pick]PR tag.