Skip to content

[Optimize] Optimize ttft for ep - #6098

Merged
Jiang-Jia-Jun merged 15 commits into
PaddlePaddle:developfrom
rainyfly:optimize_ttft_for_ep
Feb 4, 2026
Merged

Jiang-Jia-Jun merged 15 commits into
PaddlePaddle:developfrom
rainyfly:optimize_ttft_for_ep

Conversation

@rainyfly

@rainyfly rainyfly commented Jan 19, 2026

Copy link
Copy Markdown
Collaborator

Motivation

优化 zmq -> scheduler -> worker 的调度逻辑。
之前scheduler 和 worker 是完全异步分开进行的,schedule()会在引擎forward开始前发生并立即结束,容易造成每次调度的请求量不满,从而让请求易发生排队。
实际上,在整个引擎 forward 期间,都是可以预处理请求并且接收请求放在scheduler的队列里累积,在引擎 forward 结束后再进行schedule(),此时才能达到最佳组batch的效果。

Modifications

  1. 引擎 forward结束再 schedule()
  2. forward期间持续接收请求并做预处理,放到 scheduler的队列中等待 schedule()。

Usage or Command

None

Accuracy Tests

None

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

paddle-bot Bot commented Jan 19, 2026

Copy link
Copy Markdown

Thanks for your contribution!

Jiang-Jia-Jun pushed a commit that referenced this pull request Jan 21, 2026
* optimize ttft

* fix

* fix

* fix

* fix

* fix mix

* fix ci
@codecov-commenter

codecov-commenter commented Jan 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 53.84615% with 24 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (develop@9b0a82c). Learn more about missing BASE report.

Files with missing lines Patch % Lines
fastdeploy/engine/common_engine.py 14.28% 12 Missing ⚠️
fastdeploy/worker/worker_process.py 64.28% 6 Missing and 4 partials ⚠️
fastdeploy/scheduler/dp_scheduler.py 85.71% 0 Missing and 1 partial ⚠️
fastdeploy/splitwise/internal_adapter_utils.py 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             develop    #6098   +/-   ##
==========================================
  Coverage           ?   67.66%           
==========================================
  Files              ?      389           
  Lines              ?    51915           
  Branches           ?     8080           
==========================================
  Hits               ?    35130           
  Misses             ?    14234           
  Partials           ?     2551           
Flag Coverage Δ
GPU 67.66% <53.84%> (?)

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

此 PR 优化了专家并行(EP)场景下的调度逻辑,通过将 schedule() 调用时机从引擎 forward 开始前移到 forward 结束后,以实现更好的请求批处理效果。主要目标是优化 Time To First Token (TTFT)。

Changes:

  • 引入 engine_forward_signal IPC 信号来协调调度器和 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,但新的实现不再使用超时逻辑。

这些测试现在可能会产生误导性结果或给出假阳性。建议:

  1. 更新这些测试以反映新的实现行为
  2. 或者删除这些测试,如果它们测试的场景不再适用
  3. 验证 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, [])

Comment thread fastdeploy/engine/common_engine.py
Comment thread fastdeploy/scheduler/dp_scheduler.py
Comment thread tests/scheduler/test_dp_scheduler.py
Comment thread fastdeploy/worker/worker_process.py
Comment thread fastdeploy/engine/common_engine.py
Comment thread fastdeploy/engine/common_engine.py
Comment thread fastdeploy/scheduler/dp_scheduler.py
Comment thread tests/ci_use/metrics/test_metrics.py
Comment thread fastdeploy/worker/worker_process.py
@Jiang-Jia-Jun
Jiang-Jia-Jun merged commit 90db0bd into PaddlePaddle:develop Feb 4, 2026
19 of 24 checks passed
rainyfly added a commit that referenced this pull request Feb 9, 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
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
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
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.

4 participants