NInfer 性能测量方法论:如何像官方一样复现 tok/s 与 TTFT 基准测试
【免费下载链接】ninferHigh-performance single-GPU inference for selected model checkpoints and GPUs.项目地址: https://gitcode.com/gh_mirrors/ni/ninfer
想知道 NInfer 单卡推理到底有多快?本文带你用官方同一套方法复现tok/s 吞吐与TTFT(首 token 延迟)基准测试:从固定测试环境、指标定义,到一条命令跑出可对比的报告,全部讲清楚。🚀
一、先搞清楚:NInfer 的三层基准测试体系
NInfer 的性能数字不是一锤子测出来的,而是分三层、各有分工(详见 bench/README.md):
| 层级 | 工具 | 测什么 | 能证明什么 |
|---|---|---|---|
| Op 层 | ninfer_<op>_bench系列 | 单个算子(Linear、Attention、RMSNorm…) | 内核实现效率 |
| 引擎层 | ninfer_bench | 完整 Engine 的 prefill/decode 吞吐 | 引擎路线吞吐 |
| 服务层 | ninfer-serve+ Python runner | 真实 HTTP 请求下的 tok/s 与 TTFT | 官方发布的性能数字 |
⚠️ 新手最容易踩的坑:Op 层的速率不能代表 HTTP 服务性能。官方文档明确要求三者边界不可混用(见 bench/README.md 开头)。本文重点教你复现第 2、3 层。
二、官方通用测试环境:复现数字的第一块基石
官方所有公开数据都来自同一张NVIDIA RTX 5090(32 GiB)的固定画像,完整定义在 docs/performance/methodology.md 的 "Common serving profile":
- 路由:常驻
ninfer-serve,本地回环 OpenAI Chat Completions,stream=false - Prefill 分块:1024 tokens
- KV 缓存:Qwen3.8 用 FP8 E4M3 row-256,Qwen3.6 用 INT8 group-64
- CUDA Graph 开启、前缀复用关闭
- 采样固定:温度 0.6、top-p 0.95、top-k 20(贪心则为精确 argmax)
- 启动与预热不计入测量请求
复现时只要改变其中任何一项,结果就和官方数字"不可直接对比"——这正是方法论的价值所在。
三、读懂 tok/s:三个解码速率千万别混用
NInfer 的方法论里最严谨的一点,是把"时间边界"写死在指标定义里(methodology.md "Metrics and statistics" 一节):
| 指标 | 公式 | 适合回答的问题 |
|---|---|---|
| Prefill phase (tok/s) | prompt_tokens ÷ prefill 秒数 | 长文档处理速度 |
| Server TTFT (ms) | prepare + vision + prefill 三阶段之和 | 服务端首响应快慢 |
| Decode phase (tok/s) | (completion_tokens − 1) ÷ decode 秒数 | 单请求解码速度 |
| Corpus decode (tok/s) | 总解码 token ÷ 整个语料 makespan | 一批请求整体有多快 |
| Steady decode (tok/s) | 稳态区间提交 token ÷ 区间秒数 | 满并发下可持续吞吐 |
📌 记住:三种 decode 速率的时间分母不同,官方严禁把它们放进同一个不带标签的列里。
四、如何复现 tok/s 吞吐基准测试
4.1 引擎级:ninfer_bench
先开启 benchmark 目标并构建(约两步):
cmake -S . -B build -DNINFER_BUILD_BENCHMARKS=ON cmake --build build -j --target ninfer_bench然后跑一个 2048 输入 + 128 输出的用例:
./build/bench/ninfer_bench --weights out/qwen3_6_27b.ninfer -pg '2048,128' -r 5 --warmup 1它从冻结语料 bench/fixtures/bench_corpus.ids 中切片出精确 token 数,只走公开的Engine::generate(),报告 schema v15。想要整套矩阵,可直接用编排脚本(默认输出 JSON + summary.csv 到profiles/bench/):
python3 tools/bench/run_ninfer_bench_matrix.py --preset core4.2 服务级:真实 HTTP 吞吐
官方模型页(如 docs/performance/qwen3.6-27b.md)里的表格,全部由 tools/bench/run_serve_corpus.py 串行跑固定 fixture 得到。复现命令长这样:
python3 tools/bench/run_serve_corpus.py \ --serve build/apps/ninfer-serve \ --artifact qwen3_6_27b=out/qwen3_6_27b.ninfer \ --mode mtp3 \ --output profiles/bench/my_mtp3_run工作负载是冻结的:15 个 fixture(AIME 长推理 ×3 + Code/Story/Translation/Structured ×12)× 5 个种子 = 75 个请求,定义见 examples/cli/manifest.json。输出包含run.jsonl(原始请求响应)、summary.csv/summary.md(分类汇总)——原始报告就是你复现结果的可审计证据。
并发饱和测试(C=1/2/4/8 的 steady decode)则用 tools/bench/run_serve_concurrency.py,每个并发点都会新起一个 Serve 进程,避免状态污染。
五、如何测量 TTFT 首 token 延迟
TTFT 在 NInfer 里有两个边界,必须分清:
- Server TTFT(内部相位和):prepare + vision + prefill 三阶段时长之和,不含网络传输与排队;
- 外部流式 TTFT(黑盒测量):由 tools/bench/ttft/README.md 定义的客户端计时——
TTFT = t1 − t0,其中 t0 是请求字节写出的瞬间,t1 是收到第一个非空模型输出 delta的时刻。建连、JSON 序列化不算在内;HTTP 头、usage 等元数据也不算"模型输出"。
黑盒客户端只发公开 HTTP 请求,从不调用 Engine、不读服务端日志,保证测量的独立性。它使用冻结的文本/媒体 fixture——比如这 56 张字节确定、互不相同的 1024×1024 测试图(bench/fixtures/ttft/README.md),每张展开成 12 MiB 的 Vision 预处理张量,专门压测媒体路径:
一条命令跑完整个受控 campaign(自动为每个样本启动全新 Serve 进程、落盘 raw/summary 三件套):
python3 tools/bench/run_serve_ttft_campaign.py --campaign resource --samples 5汇总报告给出 min / 中位数 / max / MAD,不发布QPS、P95 或推测性内部缓存动作——报告里没写的,就不要自己脑补。
六、像官方一样发布:统计与对比规则 📊
复现出数字只是第一步,methodology.md 还规定了怎么"诚实地"使用它们:
- 单请求表报告算术平均 ± 样本标准差;单波/单语料点没有样本偏差
- 接受率(acceptance)在相位表里取"逐请求比值的平均",在语料表里取"总接受/总起草",两种聚合方式不可互换
- 对比公式写死:吞吐加速 = new / baseline,makespan 加速 = baseline / new
- 异常样本(重复、输出截断)保留在统计里并在旁边标注,不悄悄删数据
- 每次复现记录:日期、权重身份、Git 修订、硬件/工具链、样本数、运行配置
七、复现陷阱清单(新手速查)✅
- KV 类型不匹配:Qwen3.8 用
--kv-dtype fp8,Qwen3.6 用int8,runner 会校验并记录实际 KV 表示 - 随机续写:同 prompt + 种子在不同权重/后端下仍可能产生不同 token 总量,报告时把 token 总数和速率一起贴出来
- 别用旧 corpus 片段拼新结果:并发点报告不可断点续传,跨进程拼接会破坏 makespan 与稳态区间的定义
- 预热与启动不算成绩:官方画像中它们永远在计时窗口之外
- 换硬件请重测:固定参考带宽(如 RTX 5090 的 1792 GB/s DRAM)写进了 Op 层报告,换卡后百分比全部作废
八、延伸阅读
- 测量与发布总纲:docs/performance/methodology.md
- 各模型实测结果页:docs/performance.md
- Runner 用法与报告文件说明:tools/bench/README.md
- 全部 Op 基准契约:bench/README.md
- 困惑度(离线因果打分)方法论:docs/perplexity.md
按这套方法跑一遍,你得到的不只是几个 tok/s 数字,而是一份别人可以逐行复核的性能证据——这正是 NInfer 官方数据的底气所在。
【免费下载链接】ninferHigh-performance single-GPU inference for selected model checkpoints and GPUs.项目地址: https://gitcode.com/gh_mirrors/ni/ninfer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考