ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何测试首令牌时间:用 GenAI-Perf 对 Triton 推理服务做 TTFT 性能测试

如何测试首令牌时间:用 GenAI-Perf 对 Triton 推理服务做 TTFT 性能测试 1. 为什么 TTFT 值得单独测Triton 推理服务上线前的首令牌时间基准场景首令牌时间Time to First TokenTTFT指的是从客户端发出请求到收到模型返回的第一个 token 所经历的时长。它和总吞吐、端到端延迟不是一回事一个服务可能每秒能吐几千个 token但用户盯着空白屏幕等了两秒才看到第一个字体感就是「卡」。对聊天、代码补全、语音助手这类交互式场景TTFT 往往比总延迟更决定体验。Triton 推理服务本身支持 TensorRT-LLM、vLLM、Python backend 等多种后端不同后端在 batch 调度、KV Cache 管理、prefill/decode 拆分上的策略差异会直接反映在 TTFT 分布上。上线前如果不做基准测试你很难知道并发从 1 涨到 32 时TTFT 是线性恶化还是突然跳变P50 好看但 P99 是否已经爆掉prefill 阶段到底是算力瓶颈还是排队瓶颈。GenAI-Perf 是 NVIDIA 随 Triton 生态提供的一款生成式 AI 性能测试工具专门用来构造带 streaming 的并发请求并直接输出 TTFT、ITLInter-Token Latency、吞吐等指标。它比手写 requests 脚本更贴近真实负载能控制输入/输出 token 长度分布、并发数、请求速率还能把结果导出成 CSV/JSON 做对比。这篇面向的是「Triton 服务已经能跑起来但还没正式上线需要一份可复现的 TTFT 基准」这个阶段。适合做推理部署、模型服务调优、SRE 容量评估的同学。下面我会给出可复制的 GenAI-Perf 命令、Triton 侧指标导出配置以及不同并发下对比 TTFT 的完整验证步骤帮你把首令牌延迟瓶颈定位到具体环节。2. 前置准备Triton 服务、GenAI-Perf 安装与 TaoToken 接入配置在跑基准之前先把三件事准备好一个可用的 Triton 生成式模型服务、GenAI-Perf 运行环境、以及一个稳定的模型调用入口用于对照验证。前两个是测试主体第三个用于在基准之外做人工抽检确认服务返回内容正常。Triton 侧我假设你已经用 TensorRT-LLM 或 vLLM 后端起了一个模型比如 gpt2 或 llama 系列HTTP/gRPC 端口可访问。可以用下面命令确认服务活着curl -s http://localhost:8000/v2/health/ready # 返回 200 表示 ready curl -s http://localhost:8000/v2/models # 列出已加载模型GenAI-Perf 官方推荐用容器方式运行避免 Python 依赖冲突。如果你本机有 NVIDIA 容器环境直接拉镜像最省事docker run -it --rm \ --nethost \ --gpus all \ nvcr.io/nvidia/tritonserver:24.10-py3-sdk \ bash进入容器后确认 genai-perf 可用genai-perf --help如果不想用容器也可以 pip 安装但要注意和 Triton client 版本匹配pip install genai-perf genai-perf --version接下来是模型调用入口。基准测试跑完后我习惯用一个独立的 OpenAI 兼容端点做人工对照确认 TTFT 数据不是测试工具自身造成的假象。TaoToken 提供 OpenAI 兼容接口Base URL 是https://taotoken.net/api你可以在 模型对话 页面拿到可用的 Model ID在 API Keys 页面生成 Key。这个入口不参与 Triton 基准只用于「同样的 prompt人工感受首字延迟」的交叉验证。如果你后续要做编码类 Agent 的 TTFT 对比可以了解 Coding Plan需要看接口细节查 文档。这些是辅助入口核心测试仍然在本地 Triton 上完成。环境就绪后先跑一次最小请求确认 Triton 的 streaming 接口正常否则 GenAI-Perf 会报连接或解析错误curl -s http://localhost:8000/v2/models/gpt2/generate_stream \ -d {text_input:Hello,max_tokens:8,stream:true}能看到逐块返回的 token 就说明 streaming 通了。3. 可复制配置GenAI-Perf 命令行参数与 Triton 指标导出这一节是全文的核心给出可以直接粘贴运行的命令以及 Triton 侧开启 metrics 的配置。先看 GenAI-Perf 的完整命令genai-perf profile \ -m gpt2 \ --service-kind triton \ --backend tensorrtllm \ --num-prompts 200 \ --synthetic-input-tokens-mean 200 \ --synthetic-input-tokens-stddev 20 \ --output-tokens-mean 100 \ --output-tokens-stddev 10 \ --concurrency 1 \ --measurement-interval 10000 \ --streaming \ --url localhost:8001 \ --artifact-dir ./ttft_c1逐个参数说明方便你按场景改参数作用调优建议-m gpt2模型名需与 Triton 中一致换成你的模型名--service-kind triton指定 Triton 服务类型固定--backend tensorrtllm后端类型影响请求格式vLLM 用vllm--num-prompts 200总请求数基准建议 ≥200压测可上千--synthetic-input-tokens-mean 200输入 token 均值贴近真实 prompt 长度--output-tokens-mean 100输出 token 均值影响 decode 阶段--concurrency 1并发数对比实验的核心变量--measurement-interval 10000测量窗口(ms)稳态测量用 10s--streaming开启流式TTFT 才有意义必开--url localhost:8001Triton gRPC 端口HTTP 用 8000--artifact-dir结果输出目录每次实验单独目录跑完后目录里会有profile_export_genai_perf.csv和 JSONTTFT 相关字段是time_to_first_token包含 avg、p50、p90、p99。你可以用下面命令快速看column -s, -t ./ttft_c1/profile_export_genai_perf.csv | grep -i first_tokenTriton 侧要拿到更细的指标需要在启动时开启 metrics。启动命令加--metrics-porttritonserver \ --model-repository/models \ --metrics-port8002 \ --log-verbose1然后确认 metrics 端点curl -s http://localhost:8002/metrics | grep -E nv_inference_request_duration_us|nv_inference_queue_duration_us关键指标含义nv_inference_queue_duration_us是请求在队列里的等待时间nv_inference_request_duration_us是实际推理时间。TTFT 恶化时如果 queue duration 涨得比 request duration 快说明瓶颈在调度排队反之则在 prefill 计算。如果你用配置文件方式启动 Triton可以写成 TOML[server] metrics-port 8002 log-verbose 1 [model_repository] path /models保存为triton_config.toml启动时--config triton_config.toml即可。这样每次基准实验的配置可版本化方便复现。4. 验证请求与成功结果不同并发下 TTFT 对比步骤配置就绪后做一组并发梯度实验1、4、8、16、32。每次只改--concurrency和--artifact-dir其余参数保持一致这样 TTFT 变化才能归因到并发。for c in 1 4 8 16 32; do genai-perf profile \ -m gpt2 \ --service-kind triton \ --backend tensorrtllm \ --num-prompts 200 \ --synthetic-input-tokens-mean 200 \ --output-tokens-mean 100 \ --concurrency $c \ --measurement-interval 10000 \ --streaming \ --url localhost:8001 \ --artifact-dir ./ttft_c$c done跑完后把各目录的 TTFT 汇总成一张表。可以用一段 Python 快速提取import csv, glob, os rows [] for d in sorted(glob.glob(./ttft_c*)): f os.path.join(d, profile_export_genai_perf.csv) if not os.path.exists(f): continue with open(f) as fp: for r in csv.DictReader(fp): if time_to_first_token in r.get(Metric, ): rows.append((d, r[Metric], r[avg], r.get(p99, ))) for r in rows: print(r)典型成功结果长这样数值仅示意实际以你的硬件为准并发TTFT avg (ms)TTFT p99 (ms)队列等待 (ms)14560245278887013025161202608032240520190判读逻辑并发 1→8 时 TTFT 缓慢上升队列等待占比小说明 prefill 算力还有余量8→16 开始 p99 明显拉大队列等待快速上涨说明调度开始成为瓶颈16→32 时 TTFT 翻倍且队列等待占主导此时要么加 batch 调度优化要么限制并发上限。人工交叉验证用同样的 prompt 打到 TaoToken 的 模型对话 入口感受首字出现时间确认本地 Triton 的 TTFT 量级是否合理。这一步不是替代基准而是排除「测试工具本身把时间算错」的可能。curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_KEY \ -H Content-Type: application/json \ -d {model:your-model-id,stream:true,messages:[{role:user,content:写一个快速排序}]}观察第一个data:chunk 到达的时间和 GenAI-Perf 的 TTFT 做量级对照。5. 常见报错排查401、local proxy failed、OAuth 与连接超时基准测试过程中最容易卡在连接和鉴权上下面按真实报错逐条排查。401 UnauthorizedGenAI-Perf 打 Triton 一般不需要 Key但如果你的 Triton 前面挂了网关或你误把请求打到了 OpenAI 兼容端点就会 401。检查--url是否指向 Triton 的 gRPC 端口默认 8001而不是网关端口。如果用 TaoToken 做对照请求确认Authorization: Bearer头里的 Key 是从 API Keys 生成的且没有多余空格。local proxy failed / connection refused通常是 GenAI-Perf 容器和 Triton 不在同一网络。用--nethost启动容器或确认--url用的是宿主机可达 IP 而非localhost。如果 Triton 只监听了 127.0.0.1容器内访问不到启动时加--http-address 0.0.0.0 --grpc-address 0.0.0.0。OAuth / token 过期部分企业网关会在 Triton 前加一层鉴权GenAI-Perf 默认不带 OAuth 头。这种情况要么在网关侧放行测试网段要么用--extra-inputs传自定义头。注意不要把生产网关的鉴权绕过当成常规做法测试环境单独配置。TTFT 为 0 或缺失多半是没加--streaming。非流式请求下GenAI-Perf 只能测到端到端延迟TTFT 字段为空。另一个可能是后端不支持 streaming检查 Triton 模型配置里decoupled或 streaming 相关设置。结果波动大--measurement-interval太短、--num-prompts太少都会导致抖动。基准实验建议 num-prompts ≥200measurement-interval ≥10000ms并在同一硬件状态下连续跑三次取中位数。队列等待指标缺失确认 Triton 启动带了--metrics-port且curl http://localhost:8002/metrics能返回内容。如果只有nv_inference_request_duration_us没有 queue duration检查 Triton 版本老版本指标名可能不同。排查顺序建议先curl健康检查 → 再curlstreaming 接口 → 再跑单并发 GenAI-Perf → 最后上并发梯度。每一步通了再往下能快速定位是网络、鉴权还是模型配置问题。6. 把 TTFT 基准纳入上线流程从单次测试到持续对比单次跑出 TTFT 数字意义有限真正有用的是把它变成可重复、可对比的流程。我的做法是每次模型版本、Triton 配置、硬件规格变更时都跑同一组并发梯度把结果存进带时间戳的目录用脚本生成趋势对比。#!/bin/bash TS$(date %Y%m%d_%H%M) for c in 1 8 32; do genai-perf profile \ -m gpt2 --service-kind triton --backend tensorrtllm \ --num-prompts 200 --synthetic-input-tokens-mean 200 \ --output-tokens-mean 100 --concurrency $c \ --measurement-interval 10000 --streaming \ --url localhost:8001 \ --artifact-dir ./bench/$TS/c$c done这样./bench/下就是一条时间线任何一次 TTFT 回退都能追溯到具体变更。配合 Triton 的 queue duration 指标你能判断回退是来自模型本身变慢还是调度策略变化导致排队加剧。几个实用技巧输入 token 长度分布要贴近真实业务别只用默认值P99 比 avg 更值得盯交互场景用户感知的是尾部并发梯度不要只测 1 和 32中间点才能看出拐点每次实验前清空 Triton 的 metrics 或重启服务避免历史计数污染。如果你同时维护多个模型服务可以把 GenAI-Perf 的 JSON 输出统一收集用 Console 里的调用日志做人工抽检对照确认基准数据和真实调用体验一致。需要接 Claude Code 类编码 Agent 做 TTFT 对比的参考 ClaudeCodeAnthropic 的接入方式把 Agent 场景的首字延迟也纳入观测。最后一步把上面这套命令和判读表写进你的上线检查清单TTFT P99 超过阈值就阻断发布队列等待占比超过 50% 就触发调度调优。基准测试的价值不在于跑出一个漂亮数字而在于让「首令牌时间」从模糊体感变成可量化、可回归的工程指标。
返回列表