Skip to content

perf(sampling): optimize generic greedy and bounded top-k/top-p - #1573

Open
sufubao wants to merge 2 commits into
ModelTC:mainfrom
sufubao:optimize-generic-sampling
Open

sufubao wants to merge 2 commits into
ModelTC:mainfrom
sufubao:optimize-generic-sampling

Conversation

@sufubao

@sufubao sufubao commented Sep 15, 2026

Copy link
Copy Markdown
Collaborator

通用采样在 greedy 请求中生成完整 softmax 概率矩阵,在小 top-k 请求中仍排序完整词表,增加后处理开销。本 PR 从 upstream/main 8e1ddf29 独立拆出两个采样优化,不依赖 #1534 的词表候选通信、回填或输出层改动。

改动

  • 全 greedy 的 FP32 批次:小张量使用 argmax + log_softmax;大张量使用分块归约直接生成 token ID 和 logprob,避免完整概率矩阵。保留原地温度处理、同分取最小 token ID,以及已有 penalty、EOS 和 invalid-token 前处理。
  • Triton 的 FP32 多请求 top-k/top-p:无请求种子、所有 top-k>1 且最大 top-k 不超过词表四分之一时,只选取并排序 top-k 前缀,减少累计概率、过滤和 multinomial 的输入宽度。完整词表 softmax 与原始概率质量保持不变。
  • 单请求、带种子、混合 greedy、大 top-k、非 FP32 及仅 top-p 沿用完整排序,FlashInfer 分支不变。新增相关回归测试。

缩短 multinomial 输入会改变无种子请求的随机序列,同分截断边界也可能选择不同 token;浮点归约实现变化不保证 logprob 逐位一致。

验证与性能依据

两个提交从 #1534 原样拆出,git range-diff 确认补丁不变;Black、flake8 和 git diff --check 通过。原分支相关 GPU 回归共 152 项通过;此次独立分支的三个测试文件成功收集,112 项因禁用 CUDA 跳过;未重跑 GPU 测试或性能实验。

此前 m34 / H200、PyTorch 2.9.1+cu128、Triton 3.5.1,交替计时完整 sample() 的 CPU+GPU eager 墙钟中位数:

场景 基线 → 优化后 耗时降低
Greedy,B128 / V151936 307.8 → 301.5 μs 2.0%
Greedy,B128 / V262144 465.3 → 302.1 μs 35.1%
top-k128 / top-p0.9,B128 / V151936 2946.47 → 729.40 μs 75.2%
top-k128 / top-p0.9,B128 / V262144 4913.02 → 947.91 μs 80.7%

这些历史输入为 FP32、每行回填 128 个候选,greedy 基线为 a68f16a5、top-k/top-p 基线为 7fd62182;不含模型前向、通信和网络,不能作为此独立分支相对 main 在普通稠密分布上的实测收益。

此前 m33 的 Qwen2.5-14B TP2、每 rank 128 候选、GSM8K 并发128评测中,top-k/top-p 三轮合计输出吞吐提高11.1%,双方均答对3696/3957。Greedy 三轮吞吐变化为−19.3%、+7.2%、+2.17%,第三轮正确题数1234→1228,尚不能认定稳定端到端加速或精度完全一致。这些同样是原分支的历史观察,未完成此独立分支相对最新 main 的 LLM Bench 对照。

实验通过 exp -m 归档于 ~/experiments/pr1534-generic-greedy-20260914/~/experiments/pr1534-topk-topp-20260914/~/experiments/pr1534-m33-e2e-20260915/

FP32 全 greedy 批次按张量规模使用 log_softmax 或分块归约,减少调度与完整概率矩阵的开销。
保留原 penalty、EOS、invalid-token 与约束流程,以及 logits 原地温度处理和同分最小 token ID 行为。

实验:m34 H200,PyTorch 2.9.1+cu128,Triton 3.5.1。
基线 a68f16a;完整 sample() 的 CPU+GPU eager 墙钟,同进程轮换顺序,9轮、每轮90次调用取中位数。
输入为 FP32 完整词表 logits,每行预先回填128个候选;temperature=1,默认 GPU counter penalty。
- B1/V151936:178.6 -> 168.2 us,耗时降低5.8%。
- B128/V151936:307.8 -> 301.5 us,耗时降低2.0%。
- B128/V262144:465.3 -> 302.1 us,耗时降低35.1%。
这些数据不含候选提取、模型前向、网络或服务吞吐。

验证:114项相关回归通过,Black/flake8和diff检查通过。
覆盖两套 penalty counter、非默认温度、EOS、invalid-token、同分、NaN/Inf和CUDA Graph重放;
额外以FP64参考核对集中分布的归约精度,token ID和原地logits与基线精确一致。
实验配置、源码快照和原始数据归档:~/experiments/pr1534-generic-greedy-20260914/。
通用 triton 采样在 FP32、B>1、无请求种子、所有 top-k>1 且
max(top-k) 不超过词表四分之一时,只选取并排序 top-k 前缀,
减少累计概率、过滤和 multinomial 的输入宽度。

保留 penalty、EOS、invalid-token、temperature、完整词表 softmax
及调用方约束流程。top-p 和返回 logprob 使用原始概率质量。
单请求、带种子、混合 greedy、大 top-k、非 FP32 和仅 top-p
沿用完整排序;FlashInfer 分支不变。快路径会改变无种子请求的
随机序列,同分截断边界也可能选择不同 token。

实验:m34/H200,PyTorch 2.9.1+cu128,Triton 3.5.1;
基线 7fd62182,真实 sample,GPU counter,FP32,temperature=1,
top-k=128/top-p=0.9,预先回填128候选;9轮×60次交替计时中位数:
- B16/V151936:711.62 -> 400.68 us,耗时降低43.7%。
- B128/V151936:2946.47 -> 729.40 us,耗时降低75.2%。
- B128/V262144:4913.02 -> 947.91 us,耗时降低80.7%。
- B1 回退后基本持平;K65536/V262144 边界仍有收益。

测量包含 CPU 参数准备、H2D 和完整 sample,不含候选提取/回填、
模型前向、网络或服务吞吐。所有实验通过 exp 归档:
~/experiments/pr1534-topk-topp-20260914/report.md

验证:152项相关测试通过,其中新增38项 top-k/top-p 回归;
覆盖原始概率、过滤支持集、同分、种子/RNG、回退及前处理兼容。
Black、flake8、git diff --check 通过。
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.

1 participant