[Cherry-Pick][Speculative Decoding] Support mtp super ultra overlap in pd-split mode with insert_task overlap(#7323)#7794
Conversation
…de with insert_task overlap (PaddlePaddle#7323) * support mtp overlap in pd-split mode with insert_task overlap
|
Thanks for your contribution! |
There was a problem hiding this comment.
Pull request overview
该 PR(Cherry-Pick #7323)主要围绕 Speculative Decoding / MTP 在 PD 分离(splitwise)模式下的插入任务(insert_task)重叠能力做适配:通过更多使用 async_set_value 进行(尽量)异步写入 share buffer,减少同步开销,并补充了对应的单测覆盖关键分支。
Changes:
- 在
GPUModelRunner.insert_tasks_v1中,将多处 share_inputs 写入改为async_set_value,并在 splitwise_role=decode + SUFFIX 路径下调整 draft token 写入与缓存计数更新逻辑。 - 在
MTPProposer.insert_tasks_v1中同样引入async_set_value,并对input_ids_cpu写入增加 hybrid_mode 条件保护。 - 补充 splitwise SUFFIX 分支的单元测试;同时增强
async_expert_loader对 cuda-python 13.x import 结构变化的兼容性。
PR 标题/描述检查(按仓库模板要求):
- 标题格式符合 Cherry-Pick 约定(以
[Cherry-Pick]开头且结尾包含原 PR 号(#7323))。 - 当前 PR 描述中模板项(Motivation/Modifications/Usage/Accuracy Tests)未完整补充;建议在合入前补齐,尤其是性能收益与(如涉及输出一致性)accuracy 结果。
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/worker/test_gpu_model_runner.py | 新增 splitwise_role=decode + SUFFIX 分支的 insert_tasks_v1 单测,并用同步 stub 替代 async_set_value 以便无 CUDA 环境运行。 |
| fastdeploy/worker/gpu_model_runner.py | insert_tasks_v1 多处写入改为 async_set_value;splitwise decode + SUFFIX 分支写入 draft_tokens/seq_lens 并更新 cached token 计数;stop_seqs 写入方式改为 pad 后整块写入。 |
| fastdeploy/spec_decode/mtp.py | MTP proposer 的 insert_tasks_v1 多处写入改为 async_set_value,并对 hybrid_mode 下的 input_ids_cpu 写入增加保护。 |
| fastdeploy/model_executor/xpu_pre_and_post_process.py | 新增 XPU 路径的 async_set_value 实现,供 XPU MTP proposer 等路径使用。 |
| fastdeploy/model_executor/pre_and_post_process.py | 将 async_set_value 改为全平台可用(不再仅 CUDA 可用),并在 CUDA 下继续走 custom_numpy_to_tensor 优化路径。 |
| fastdeploy/eplb/async_expert_loader.py | 兼容 cuda-python 13.x(cuda.bindings.runtime)与旧版本(cuda.cudart)的导入差异,并改进缺失依赖时的提示信息。 |
| # 每条 stop sequence pad 到 stop_seqs_max_len,凑齐空行后整块写入 | ||
| # 避免对第 3 维做部分切片(非连续内存)导致 async_set_value stride 错位 |
|
|
||
| _cuda_ver = getattr(_cuda_pkg, "__version__", None) | ||
| if _cuda_ver is None: | ||
| # cuda-python >= 13.x 无顶层 __version__,通过 cuda-bindings 子包判断 |
CI报告基于以下代码生成(30分钟更新一次): 1 任务总览CI 存在 1 个 required 失败任务,另有 4 个 required 任务运行中,4 个 required 任务等待中。在 required 失败任务处理完成前,建议暂缓合并。
2 任务状态汇总2.1 Required任务 : 1/10 通过
2.2 可选任务 — 25/29 通过
3 失败详情(仅 required)Approval — PR审批缺失(置信度: 高)Approval
根因详情: 关键日志: 修复建议:
修复建议摘要: 请 @Deleter-D 对本PR进行Approve Review 链接: 查看日志 |
PaddlePaddle-bot
left a comment
There was a problem hiding this comment.
🤖 Paddle-CI-Agent | pr_review |
2026-05-12 18:34:17
📋 Review 摘要
PR 概述:在 PD 分离模式下为 MTP 投机解码支持 insert_tasks_v1 overlap,将所有同步 tensor 赋值替换为 async_set_value 异步写入;同时修复 cuda-python ≥13.x 兼容性并为 XPU 补充 async_set_value 实现。
变更范围:spec_decode/mtp.py、worker/gpu_model_runner.py、model_executor/pre_and_post_process.py、model_executor/xpu_pre_and_post_process.py、eplb/async_expert_loader.py
影响面 Tag:[Speculative Decoding] [PD Disaggregation] [XPU]
📝 PR 规范检查
PR 标题格式符合 Cherry-Pick 规范,但所有正文 section(Motivation / Modifications / Usage or Command / Accuracy Tests)均为空占位符,Checklist 全部未勾选。
标题建议(已合规,无需修改)
PR 描述建议(可直接复制):
## Motivation
在 PD 分离(splitwise)模式下,MTP 投机解码的 `insert_tasks_v1` 中大量同步 tensor 赋值阻塞了 overlap 并行执行。本 PR 将这些赋值全部替换为 `async_set_value` 异步写入,支持 insert_task 阶段的 overlap,提升 PD-split 模式推理吞吐。同时修复 cuda-python ≥13.x(cuda-bindings 包)的导入兼容性,并为 XPU 补充对应的 `async_set_value` 实现。
## Modifications
- `fastdeploy/eplb/async_expert_loader.py`:新增 cuda-python ≥13.x 版本检测,使用 `cuda.bindings.runtime`;`except ImportError` 改为 `except Exception` 并输出警告
- `fastdeploy/model_executor/pre_and_post_process.py`:`async_set_value` 从仅 CUDA 可用改为通用实现(非 CUDA 路径用 `paddle.to_tensor`);修复 `isinstance(src, np.array)` → `np.ndarray` 的 bug
- `fastdeploy/model_executor/xpu_pre_and_post_process.py`:新增 XPU 平台 `async_set_value` 实现(async numpy to tensor 待后续支持)
- `fastdeploy/spec_decode/mtp.py`:`insert_tasks_v1` 所有直接赋值改为 `async_set_value`;新增 XPU `async_set_value` 导入;`input_ids_cpu` 更新增加 `hybrid_mode` 保护
- `fastdeploy/worker/gpu_model_runner.py`:`insert_tasks_v1` 所有直接赋值改为 `async_set_value`;PD-split 投机解码路径改为仅写入 2 个 draft token;`stop_seqs` 三维写入改为整块填充;新增 `enable_mm` 保护
- `tests/worker/test_gpu_model_runner.py`:新增 `TestInsertTasksV1SplitwiseSuffix` 测试类,覆盖 5 个 PD-split suffix 场景
## 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.
- [x] Format your code, run `pre-commit` before commit.
- [x] 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.问题
| 级别 | 文件 | 概述 |
|---|---|---|
| 🟡 建议 | fastdeploy/eplb/async_expert_loader.py:38 |
except Exception 过于宽泛,可能静默吞掉非导入类异常 |
| ❓ 疑问 | fastdeploy/worker/gpu_model_runner.py:911 |
is_chunk_step 仍直接赋值,同块中 is_block_step 已改为 async_set_value,是否遗漏? |
| 🟡 建议 | fastdeploy/spec_decode/mtp.py:53 |
async_set_value 标注 "temporary solution",同函数在两个模块重复定义,建议提 issue 跟踪统一 |
| 📝 PR 规范 | — | PR 描述各 section 均为空,Checklist 全部未勾选 |
总体评价
整体思路清晰,async_set_value 批量替换覆盖全面且附有单测。async_set_value 跨模块重复为已知技术债(有 TODO 标注),不阻塞合入;is_chunk_step 直接赋值和 except Exception 过宽请作者确认是否为遗漏。
| _cuda_ver = _meta.version("cuda-bindings") | ||
| _cuda_major = int(_cuda_ver.split(".")[0]) | ||
| if _cuda_major >= 13: | ||
| from cuda.bindings import runtime as cudart |
There was a problem hiding this comment.
🟡 建议 except Exception 过于宽泛
当前将 except ImportError 改为 except Exception,会捕获所有异常(包括 AttributeError、NameError、TypeError 等非导入相关错误),可能让调试困难。例如 _cuda_ver.split(".")[0] 若返回非预期对象,int(...) 会抛 ValueError,被静默吞掉后 cudart = None,只留一行 warning,难以排查根因。
建议拆分为更精确的异常类型:
except (ImportError, AttributeError, ValueError) as _e:
import warnings
warnings.warn(f"cuda-python import failed, async_expert_loader will be unavailable: {_e}")
cudart = None| self.share_inputs["prompt_lens"][idx : idx + 1] = len(input_ids) | ||
| self.share_inputs["is_block_step"][idx : idx + 1] = False | ||
| async_set_value(self.share_inputs["step_seq_lens_decoder"][idx : idx + 1], 0) | ||
| async_set_value(self.share_inputs["prompt_lens"][idx : idx + 1], len(input_ids)) |
There was a problem hiding this comment.
❓ 疑问 is_chunk_step 是否遗漏 async_set_value?
同一代码块中,is_block_step 已改为 async_set_value 异步写入:
async_set_value(self.share_inputs["is_block_step"][idx : idx + 1], False)但 is_chunk_step 仍使用同步直接赋值:
self.share_inputs["is_chunk_step"][idx : idx + 1] = prefill_end_index < len(input_ids)如果 is_chunk_step 也被 overlap 读取,则可能存在竞态。请确认:是否 is_chunk_step 是 CPU tensor(类似 preempted_idx 的处理),如是建议补充注释说明。
| update_attn_mask_offsets, | ||
| ) | ||
|
|
||
| # temporary solution |
There was a problem hiding this comment.
🟡 建议 async_set_value 跨模块重复定义
当前 async_set_value 在 pre_and_post_process.py(CUDA 路径)和 xpu_pre_and_post_process.py(XPU 路径)分别实现,注释已标注 # temporary solution。两个实现逻辑高度相似,仅 CUDA 分支有 custom_numpy_to_tensor 优化。
建议后续提独立 issue 跟踪:将两个实现统一到 fastdeploy/model_executor/pre_and_post_process.py 或新建 common_ops.py,通过 current_platform.is_cuda() 分支区分,避免后续维护两份代码。
CI报告基于以下代码生成(30分钟更新一次): 1 任务总览CI 尚未完成:有 1 个 required 失败(
2 任务状态汇总2.1 Required任务 : 6/10 通过
2.2 可选任务 — 22/26 通过
3 失败详情(仅 required)Approval — PR审批检查(置信度: 高)Approval
根因详情: 关键日志: 修复建议:
修复建议摘要: 请 Deleter-D(wangyanpeng04) Review Approve 此 PR 关联变更: PR 修改了 |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## release/2.6 #7794 +/- ##
==============================================
Coverage ? 71.90%
==============================================
Files ? 378
Lines ? 53954
Branches ? 8440
==============================================
Hits ? 38793
Misses ? 12391
Partials ? 2770
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:
|
…de with insert_task overlap (#7323)
Motivation
Modifications
Usage or Command
Accuracy Tests
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.