[Optimization][Speculative Decoding]opt mtp logprob#7883
Conversation
|
Thanks for your contribution! |
CI报告基于以下代码生成(30分钟更新一次): 1 任务总览Required 任务当前 8/10 通过,仍有 2 个 required 失败,暂不建议合入;其中 1 个为 PR 相关单测失败,1 个为人工 Approval 待处理。Optional 失败/取消仅供参考。
2 任务状态汇总日志列说明:失败任务直接使用日志链接;运行中任务使用 Job 链接。 2.1 Required任务 : 8/10 通过
2.2 可选任务 — 28/32 通过
3 失败详情(仅 required)Run FastDeploy Unit Tests and Coverage / run_tests_with_coverage — 测试失败(置信度: 高)Run FastDeploy Unit Tests and Coverage / run_tests_with_coverage
失败用例:
根因详情: 此外,e2e 请求使用 关键日志: 修复建议:
修复建议摘要: 统一打包meta[1]并修正topk协议 关联变更: 链接: 查看日志 Approval — 需要人工审批(置信度: 高)该 Job 需要人工 Approval,完成审批后 CI 才会继续执行。 |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #7883 +/- ##
==========================================
Coverage ? 63.86%
==========================================
Files ? 462
Lines ? 64488
Branches ? 9880
==========================================
Hits ? 41185
Misses ? 20502
Partials ? 2801
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:
|
PaddlePaddle-bot
left a comment
There was a problem hiding this comment.
🤖 Paddle-CI-Agent | pr_review |
2026-05-22 13:49:56
📋 Review 摘要
PR 概述:优化 MTP + logprob 路径,仅传输实际需要的 logprob 列数(top_logprobs:0 场景下性能提升 10%),并将 Python 侧张量索引改为预转 list 减少重复开销。
变更范围:custom_ops/gpu_ops/speculate_decoding/(3 个 C++ 算子)、fastdeploy/output/token_processor.py、fastdeploy/worker/gpu_model_runner.py
影响面 Tag:[Speculative Decoding] [OP] [DataProcessor]
问题
| 级别 | 文件 | 概述 |
|---|---|---|
| 🟡 建议 | speculate_save_output_with_topk.cc:127 |
max_num_logprobs << 8 存入 16 位高位,词表 > 65535 时 actual_topk 被静默截断 |
| ❓ 疑问 | speculate_get_output_with_topk.cc:81 |
real_k 参数循环中已不再使用,是否为死代码? |
| 📝 PR 规范 | — | Modifications、Usage or Command、Accuracy Tests 三节为空 |
📝 PR 规范检查
PR 标题格式合规,已包含 [Optimization] 和 [Speculative Decoding] 两个合法 Tag;但描述模板中 Modifications、Usage or Command、Accuracy Tests 三节均为空白,未按模板填写。
标题建议(可直接复制):
[Optimization][Speculative Decoding] opt mtp logprob: reduce topk transfer to actual needed columns
PR 描述建议(可直接复制,必须复刻 checklist §D2 模板的完整结构):
## Motivation
MTP + logprob(top_logprobs:0) 场景下,旧代码始终传输固定 SPEC_LOGPROB_K+1=21 列 token/score,其中大量未使用的列被置为 -1/0.0。通过仅传输实际需要的 max_num_logprobs 列,可减少消息体写入量,性能提升约 10%。
## Modifications
- `speculate_save_output_with_topk.cc` / `mtp_save_first_token_with_topk.cc`:将 `max_num_logprobs` 打包入 `meta[1]` 高 16 位,写循环从 `SPEC_LOGPROB_K+1` 改为 `max_num_logprobs` 列,不再填充无用 -1/0.0 槽位
- `speculate_get_output_with_topk.cc`:从 `meta[1]` 解包 `actual_topk`,读循环改为 `actual_topk` 列
- `token_processor.py`:Python 侧解包 `packed_meta1`,对 tokens/scores 张量做 `[:, :, :actual_topk]` 裁剪;将热路径中的逐元素 `.item()` / `.tolist()` 改为批量 `.tolist()` 预转换
- `gpu_model_runner.py`:移除 speculative decoding 路径中 `max_logprobs` 硬限为 20 的特判,改为按实际请求计算
## Usage or Command
N/A(性能优化,接口不变)
## Accuracy Tests
N/A(本次变更不修改推理逻辑,仅减少无效数据传输;top_logprobs 输出结果不变)
## 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.总体评价
优化思路清晰,通过减少无效 topk 槽位传输和批量 .tolist() 转换来降低热路径开销,代码改动结构合理。主要关注点是 max_num_logprobs 打包到 16 位高位后的词表溢出边界问题,建议加防御断言;real_k 参数的清理也可一并处理。
| // Pack message_flag (low 8 bits) and max_num_logprobs (high 16 bits) into | ||
| // meta[1]. Receiver unpacks both to avoid reading unused topk slots. | ||
| int max_num_logprobs = logprob_token_ids.shape()[1]; | ||
| msg_sed.meta[1] = message_flag | (max_num_logprobs << 8); |
There was a problem hiding this comment.
🟡 建议 max_num_logprobs 打包进 16 位高位存在截断风险
当 max_num_logprobs > 65535 时(例如用户请求全词表 logprobs,vocab_size > 65K),接收端 (meta[1] >> 8) & 0xFFFF 会静默截断,导致 actual_topk 错误,进而越界读写或丢失数据。
旧代码中 speculative decoding 的 max_logprobs 硬限为 20,本次 gpu_model_runner.py 移除该上限后,此场景已可触发。
建议在此处加防御断言:
PD_CHECK(max_num_logprobs <= 0xFFFF,
"max_num_logprobs %d exceeds 16-bit limit", max_num_logprobs);| // Unpack message_flag (low 8 bits) and actual_topk (high 16 bits) from | ||
| // meta[1]. Keep packed value; Python unpacks message_flag and actual_topk. | ||
| output_tokens_data[1] = (int64_t)msg_rcv.meta[1]; | ||
| output_tokens_data[2] = (int64_t)msg_rcv.meta[2]; |
There was a problem hiding this comment.
❓ 疑问 real_k 参数是否已成死代码?
本次修改将循环条件从 k < real_k + 1 改为 k < actual_topk,real_k 参数不再出现在循环体中。但 Python 侧在调用此算子时仍传入 K=20(token_processor.py 中的常量)作为 real_k 属性。
请确认 real_k 是否还被用于输出 tensor 的预分配或其他地方;若已完全废弃,建议清理该参数以避免后续维护误解。
Motivation
MTP + logprob(top_logprobs:0) 性能提升10%
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.