[Cherry-Pick][BugFix] fix consume_signals barrier deadlock in PD separation(#8034)#8035
Conversation
15e5ab9 to
d00f59e
Compare
In PD separation mode, different ranks may receive cache_info at different times. When consume_signals gets a layer0 signal, some ranks find the engine_idx already in idx_cache_task_dict (ready) while others don't (pending). This causes different ranks to put different batch_engine_signals into the queue, leading to mismatched finish_send_cache_barrier.wait() calls and deadlock. Fix: route all layer0 signals through pending_layer0_signals uniformly, then immediately recover any that already have cache_info registered. Each recovered signal is put into the queue individually (single-request batch) to ensure all ranks have identical batch granularity regardless of recovery timing.
d00f59e to
693d90c
Compare
PaddlePaddle-bot
left a comment
There was a problem hiding this comment.
🤖 Paddle-CI-Agent | pr_review |
2026-06-10 17:47:58
📋 Review 摘要
PR 概述:修复 PD separation 下 consume_signals 在 cache_info 异步注册时按 rank 产生不同 layer0 signal 入队粒度导致的 barrier 死锁。
变更范围:fastdeploy/cache_manager/cache_messager.py
影响面 Tag:[KVCache] [PD Disaggregation]
问题
未发现阻塞性问题。PR 规范问题在下面章节报,不要在这里重复
历史 Findings 修复情况
| Finding | 问题 | 状态 |
|---|---|---|
| F1 | pending_layer0_signals 恢复时一次性批量入队导致不同 rank 的 cache_prefilled_engine_ids_queue 粒度仍可能不一致 |
✅ 已修复 |
📝 PR 规范检查
当前 PR 提交到 release/2.6 且描述为 cherry-pick,但标题缺少 [Cherry-Pick] 和原 PR 号;PR 描述也未包含 checklist §D2 要求的固定章节。
标题建议(可直接复制):
[Cherry-Pick][BugFix] fix consume_signals barrier deadlock in PD separation(#8034)
PR 描述建议(点击展开,可直接复制)
## Motivation
In PD separation mode, consume_signals may observe cache_info registration at different times across ranks. This can make layer0 signal enqueue granularity differ by rank and cause cache send barriers to deadlock.
## Modifications
- In fastdeploy/cache_manager/cache_messager.py, route layer0 signals through pending_layer0_signals and recover registered signals after cache_info is available.
- Cherry-pick of https://github.com/PaddlePaddle/FastDeploy/pull/8034 to release/2.6.
## Usage or Command
N/A
## 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.
- [ ] Provide accuracy results.
- [x] 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.总体评价
本轮按风险优先审查了 consume_signals layer0 signal 入队、_add_cache_task_thread 恢复路径、prefill_layerwise_send_cache_thread 的 barrier/finished queue 下游,以及 EngineWorkerQueue 的 cache_info/finished queue 同步逻辑。当前 diff 将已注册 cache_info 的 layer0 signal 逐个 put([signal]),修复了历史指出的 batch 粒度不一致风险;未发现新的阻塞性问题。
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## release/2.6 #8035 +/- ##
==============================================
Coverage ? 72.14%
==============================================
Files ? 386
Lines ? 55752
Branches ? 8756
==============================================
Hits ? 40225
Misses ? 12691
Partials ? 2836
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Thanks for your contribution! |
Cherry-pick of #8034 to release/2.6.
Problem
In PD separation mode,
consume_signalsthread splits layer0 signals intoready_engine_signalsandpending_engine_signalsbased on whetherengine_idxexists inidx_cache_task_dict. Since_add_cache_task_threadfillsidx_cache_task_dictasynchronously, different ranks may see different states at the same moment, causing mismatchedfinish_send_cache_barrier.wait()calls and deadlock.Fix
Route all layer0 signals through
pending_layer0_signalsuniformly. The_add_cache_task_threadrecovers them one-by-one aftercache_infoarrives, ensuring all ranks produce identical per-request signals into the queue.