ARTICLE DETAIL

资讯详情

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

大模型测试方法实战:用 vLLM 与 AISBench 搭建可复现的 benchmarks.serve 评测流程

大模型测试方法实战:用 vLLM 与 AISBench 搭建可复现的 benchmarks.serve 评测流程 1. 为什么大模型推理评测总是“跑不出同一份结果”大模型测试方法这件事真正难的不是把vllm bench serve敲一遍而是让两个人、两台机器、隔一周跑出来的数字能对得上。我见过太多团队在群里甩一张截图TTFT 200ms、吞吐 3000 tok/s看起来很漂亮但没人知道当时并发是多少、输入输出长度怎么设的、有没有开 prefix caching、采样参数是不是默认值。等换个人复现数字直接差一倍于是开始怀疑硬件、怀疑驱动、怀疑模型量化最后发现只是--num-prompts和--max-concurrency不一样。这就是评测环境不一致带来的典型问题。推理服务的性能指标对配置极度敏感batch 调度策略、KV Cache 占用、请求到达速率、是否流式返回任何一个变量变了TTFT 和 TPOT 都会漂移。所以标准化测试的核心不是“跑一次”而是“把变量固定下来让任何人拿着同一份配置都能跑出同一量级的曲线”。这篇内容聚焦一个可复现的评测流程用 vLLM 部署一个 OpenAI 兼容的推理服务用 vLLM 自带的benchmarks.serve做压测再用 AISBench 做精度与性能的补充验证。适合正在做推理服务选型、模型上线前压测、或者需要给团队建立评测规范的工程师。整套流程我会给出可直接复制的启动参数、配置骨架和逐项验证动作你照着跑就能得到一份带时间戳、带参数快照的评测结果。2. 前置准备TaoToken 与评测环境的关系在讲 vLLM 启动之前先说一个容易被忽略的点评测流程里经常需要对比不同模型、不同量化版本的表现这时候如果每个模型都要本地拉权重、配环境成本会很高。我的做法是把一部分对照实验放到统一的 API 入口上跑用同一套benchmarks.serve参数去打不同的 endpoint这样变量只剩模型本身。TaoToken 在这里的角色是提供一个 OpenAI 兼容的调用入口方便你在没有本地 GPU 或者想快速做横向对照时用同一套压测脚本去请求不同模型。它的 API 地址是https://taotoken.net/api兼容/v1/chat/completions这类标准路径所以vllm bench serve的--backend openai-chat可以直接指过去。需要先拿到 API Key入口在控制台的 API Keys 页面https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapikeys 。创建之后复制出来后面配置里会用到。如果你只是想先验证模型对话效果可以走模型对话页面https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodels 。这里要强调一点TaoToken 是正常的 API 服务入口不是用来绕过任何网络限制的工具评测脚本里把它当成一个普通的 OpenAI 兼容 endpoint 即可。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc 里面有完整的请求格式说明配置前建议扫一眼。3. 用 vLLM 启动一个可复现的推理服务3.1 启动参数怎么固定可复现的第一步是服务端参数固定。下面这份启动命令是我在单机多卡上常用的骨架关键参数都写死避免默认值随版本变化vllm serve /data/models/Qwen2.5-7B-Instruct \ --served-model-name qwen-eval \ --host 0.0.0.0 \ --port 8008 \ --tensor-parallel-size 2 \ --dtype bfloat16 \ --max-model-len 8192 \ --gpu-memory-utilization 0.90 \ --max-num-seqs 64 \ --max-num-batched-tokens 8192 \ --enable-prefix-caching \ --disable-log-requests \ --trust-remote-code几个参数值得单独说。--max-num-seqs决定了并发调度上限它和压测里的--max-concurrency是两回事前者是引擎侧同时处理的序列数后者是客户端发起的并发请求数。如果客户端并发远大于引擎上限请求会在队列里排队TTFT 会被拉高这时候你测到的其实是排队延迟不是模型真实首字延迟。--max-num-batched-tokens控制单次前向的 token 预算设太小会导致吞吐上不去设太大又可能 OOM建议从 8192 起步再调。--enable-prefix-caching这个开关要特别小心。开了之后相同前缀的请求会命中缓存TTFT 会明显下降但如果你测的是“冷启动首字延迟”这个数字就失真了。所以评测报告里必须写明是否开启 prefix caching否则两组数据没有可比性。3.2 服务就绪检查启动后不要急着压测先确认服务真的 readycurl -s http://127.0.0.1:8008/v1/models | python -m json.tool返回里能看到qwen-eval这个 model id 就说明服务注册成功。再发一个最小请求验证推理链路curl -s http://127.0.0.1:8008/v1/chat/completions \ -H Content-Type: application/json \ -d { model: qwen-eval, messages: [{role: user, content: 用一句话解释什么是KV Cache}], max_tokens: 64, temperature: 0 } | python -m json.tool注意这里显式带了temperature: 0。新版 vLLM 的 bench 工具默认不再强制 greedy服务端默认采样参数可能因模型而异所以压测时要么在客户端固定要么在服务端固定否则生成 token 数会波动吞吐数字就不稳。4. benchmarks.serve 压测配置与调用示例4.1 一份可复制的压测命令vLLM 自带的benchmarks.serve是评测推理服务的主力工具下面这份命令对应 1K 输入、1K 输出、并发 26 的场景vllm bench serve \ --backend openai-chat \ --base-url http://127.0.0.1:8008 \ --endpoint /v1/chat/completions \ --model qwen-eval \ --tokenizer /data/models/Qwen2.5-7B-Instruct \ --dataset-name random \ --random-input-len 1024 \ --random-output-len 1024 \ --num-prompts 104 \ --max-concurrency 26 \ --request-rate inf \ --metric-percentiles 95,99 \ --seed 1024 \ --temperature 0 \ --ignore-eos \ --save-result \ --result-filename /workspace/bench_1k1k_c26.json--dataset-name random表示用随机 token 构造请求好处是可复现坏处是它不反映真实业务分布。如果你要测真实场景可以换成sharegpt或自定义 dataset但那样每次的输入长度分布会变对比时要固定 dataset 文件。--request-rate inf表示不限制发送速率客户端尽可能快地发请求这是测“最大吞吐”的常用设置。如果你想测不同负载下的延迟曲线可以把它设成具体数值比如--request-rate 5模拟每秒 5 个请求的到达速率。--ignore-eos这个参数很关键。不加的话模型可能提前生成 EOS 结束实际输出长度远小于 1024吞吐数字会虚高。加上之后强制生成到指定长度保证每次请求的输出 token 数一致这样不同轮次的对比才有意义。4.2 结果文件里看什么跑完之后会生成一个 JSON核心字段包括字段含义关注点request_throughput每秒完成请求数反映整体处理能力output_throughput每秒生成 token 数最常用的吞吐指标mean_ttft_ms平均首字延迟用户感知最强p99_ttft_ms首字延迟 P99决定体验下限mean_tpot_ms平均每 token 耗时影响流式输出速度mean_itl_mstoken 间延迟和 TPOT 接近看抖动实测下来TTFT 的 P99 往往比均值高出一大截尤其是在高并发下。如果你的业务对首字延迟敏感光看均值会误判必须把 P95/P99 一起拉出来看。4.3 用 AISBench 做补充验证AISBench 是由中国电子技术标准化研究院发起、多家企业共建的评测基准原生支持 vLLM 服务压测。安装和配置参考官方仓库后第一次评测可以这样跑ais_bench --models vllm_api_general_chat \ --datasets demo_gsm8k_gen_4_shot_cot_chat_prompt \ --summarizer example如果报FileExistsError: Dataset path ... is not exist说明数据集没下载。按仓库里 datasets 目录下的 README 把 gsm8k 数据准备好再重新执行即可。AISBench 的价值在于它把精度评测和性能评测放在同一套框架里适合做上线前的综合体检。5. 逐项验证与常见报错排查5.1 验证请求是否真的打到了服务压测跑完先别信数字确认请求确实到达了服务端。可以在启动 vLLM 时临时加上--enable-log-requests观察日志里是否有对应数量的请求记录。如果客户端显示成功但服务端日志为空多半是 base-url 或 endpoint 写错了。5.2 常见报错一连接被拒绝ConnectionError: HTTPConnectionPool(host127.0.0.1, port8008): Max retries exceeded先确认服务是否还在运行curl http://127.0.0.1:8008/v1/models能不能通。如果服务在容器里注意端口映射和--host 0.0.0.0是否都配了。用 TaoToken 的 API 做对照时base-url 要换成https://taotoken.net/api并且带上Authorization: Bearer 你的Key这个 header 在 bench 命令里通过--header传入。5.3 常见报错二tokenizer 路径不匹配ValueError: Tokenizer path does not exist--tokenizer必须指向本地真实存在的 tokenizer 目录不能只写模型名。如果你用的是远程 API本地没有权重可以指向一个同系列的本地 tokenizer或者用--tokenizer-mode auto让工具自己处理但这样 token 计数可能和远端不完全一致对比时要留意。5.4 常见报错三结果波动大同一份配置跑两次吞吐差了 20%通常有几个原因一是没加--ignore-eos输出长度不一致二是没固定--temperature 0采样随机性影响生成长度三是机器上有其他任务抢占 GPU。建议压测前用nvidia-smi确认没有其他进程占用显存并且每轮之间留出冷却时间。5.5 验证清单跑完一轮完整评测按这个清单逐项核对服务端参数是否记录、客户端参数是否记录、是否固定随机种子、是否固定采样温度、是否强制输出长度、是否记录 P95/P99、结果文件是否带时间戳。这七项都齐了这份评测才具备可复现性。6. 把评测流程固化下来单次跑通不难难的是让团队每个人都按同一套流程跑。我的做法是把 vLLM 启动命令、bench 命令、结果解析脚本都放进一个仓库用 Makefile 串起来每次评测自动生成带 commit hash 和时间戳的结果目录。这样过一个月回头看能清楚知道当时用的是哪个模型版本、哪份配置。如果你需要长期做编码类或 Agent 类场景的评测可以考虑用 Coding Plan 来承载对照实验的调用量https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcodingplan 。它的计费方式更适合高频、长周期的压测任务不用每次手动管理额度。最后提醒一句评测数字永远服务于决策不要为了好看的吞吐去调参数。把变量固定、把过程记录、把异常排查清楚这份 benchmarks.serve 评测流程才真正有价值。
返回列表