ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

高并发下的表现,Instinct GPU 上 vLLM 压力测试数据分析:用 TaoToken 统一 Key 跑通 benchmark_serving.py

2026/10/3 16:15:08 拓冰建站 浏览量
高并发下的表现,Instinct GPU 上 vLLM 压力测试数据分析:用 TaoToken 统一 Key 跑通 benchmark_serving.py 1. 为什么要在 Instinct GPU 上做 vLLM 高并发压测如果你已经在 AMD Instinct 上把 vLLM 服务跑起来了先别急着接业务流量。本地 Demo 跑通只说明模型能出字跟“高并发下稳不稳”完全是两回事。我见过太多情况单请求测试 TTFT 只有一百多毫秒一上并发直接飙到两三秒甚至服务 OOM 崩掉。所以真正决定能不能上生产的是搞清楚这套组合在高并发下的性能拐点在哪。这篇聚焦的就是这件事在 AMD Instinct GPU 上用 vLLM 部署模型通过benchmark_serving.py做压力测试采集吞吐、TTFT、TPOT 这些指标再做数据分析。适合谁看已经跑通 vLLM 推理、想量化系统极限的后端或算法工程师正在做 Instinct 平台选型、需要横向对比数据的同学以及想把压测流程标准化、方便团队复现的人。Instinct 系列MI250/MI300的内存架构和互联拓扑跟常见平台不太一样性能拐点往往来得更突然。压测的价值就在于把这个拐点找出来而不是等线上流量教你做人。下面我会给出可复制的压测命令、并发梯度配置、结果校验步骤并且说明怎么用 TaoToken 统一 Key 和 API 通道接入模型服务让复现和横向对比更省事。2. TaoToken 统一 Key 与 API 通道的前置准备压测要跑得顺模型服务的接入方式得先统一。如果每次换模型、换环境都要重新配一套 Key 和地址横向对比根本没法做。TaoToken 在这里的作用就是提供一个统一的 API 通道一个 Key 走通模型对话、编码类请求压测脚本里改 Base URL 和 Model ID 就能切换目标不用动其他逻辑。先说清楚它是什么、能做什么。TaoToken 提供兼容 OpenAI 风格的接口你可以把它理解成一个统一的模型服务入口。对压测场景来说最大的好处是benchmark_serving.py这类工具本身支持 OpenAI 兼容后端只要把地址和 Key 填对就能直接打流不用为每个模型单独写适配层。适合谁用需要频繁切换模型做对比测试的团队或者想把压测、验证、日常调用收敛到一套凭证体系里的人。前置准备其实就三样东西Base URL、API Key、Model ID。这三件套在后面的配置片段里会反复出现先记住。获取 Key 的入口在控制台的 API Keys 页面地址是 https://taotoken.net/api-keys 登录后新建一个 Key 即可。模型对话的体验入口在 https://taotoken.net/model-conversation 可以先用它确认模型能正常出字再去跑压测。接入文档在 https://taotoken.net/doc 里面有完整的参数说明。如果你后面要做长期编码或 Agent 类任务可以了解下 Coding Planhttps://taotoken.net/coding-plan 。这里要强调一点压测的目标服务可以是本地 vLLM 起的实例也可以是 TaoToken 通道转发的模型服务。两种模式我都试过本地实例适合测硬件极限统一通道适合做跨模型横向对比。下面配置部分两种都会给到。3. 可复制的压测配置与并发梯度设置这一节是核心直接给能复制粘贴的东西。先明确目录结构假设你已经把 vLLM 仓库 clone 到本地benchmarks/benchmark_serving.py就在仓库里。如果你用的是 pip 安装的 vLLMbenchmark 脚本可能需要单独从仓库拿建议直接 clone 主仓库。先看统一通道的配置。TaoToken 的 Base URL 是https://taotoken.net/api注意这个地址不带任何查询参数。把它写进一个 JSON 配置里方便脚本读取{ base_url: https://taotoken.net/api, api_key: sk-你的TaoToken密钥, model_id: 你的模型ID, backend: openai, dataset_name: sharegpt, num_prompts: 200, request_rates: [2, 4, 8, 16], max_num_seqs: 128, gpu_memory_utilization: 0.9 }如果你更习惯用 TOML 管理压测参数等价写法是这样[service] base_url https://taotoken.net/api api_key sk-你的TaoToken密钥 model_id 你的模型ID backend openai [load] dataset_name sharegpt num_prompts 200 request_rates [2, 4, 8, 16] [engine] max_num_seqs 128 gpu_memory_utilization 0.9三件套对照一下别填错配置项值说明Base URLhttps://taotoken.net/api统一通道地址不带 UTMAPI Key控制台新建在 API Keys 页面获取Model ID你的模型标识与通道内模型名一致现在给压测命令。针对本地 vLLM 实例假设已用--tensor-parallel-size 2起好服务监听 8000 端口python benchmarks/benchmark_serving.py \ --backend vllm \ --base-url http://localhost:8000 \ --model meta-llama/Meta-Llama-3-8B-Instruct \ --dataset-name sharegpt \ --dataset-path ./ShareGPT_V3_unfiltered_cleaned_split.json \ --request-rate 4 \ --num-prompts 200 \ --max-concurrency 64 \ --output-file result_rate_4.json针对统一通道走 TaoTokenpython benchmarks/benchmark_serving.py \ --backend openai \ --base-url https://taotoken.net/api \ --api-key sk-你的TaoToken密钥 \ --model 你的模型ID \ --dataset-name sharegpt \ --dataset-path ./ShareGPT_V3_unfiltered_cleaned_split.json \ --request-rate 4 \ --num-prompts 200 \ --output-file result_rate_4.json并发梯度怎么设我的做法是把--request-rate从 2 开始依次跑 2、4、8、16每次单独跑一轮输出到不同文件。这样能画出完整的负载-延迟曲线。注意--request-rate是每秒请求数不是并发数别搞混。如果你想直接控制并发用--max-concurrency。启动 vLLM 服务时的关键参数也要固定下来否则每轮测试环境不一致数据没法比python -m vllm.entrypoints.openai.api_server \ --model meta-llama/Meta-Llama-3-8B-Instruct \ --tensor-parallel-size 2 \ --max-num-seqs 128 \ --gpu-memory-utilization 0.9 \ --port 8000--max-num-seqs这个参数在 Instinct 上特别关键。默认值通常偏大高并发下 KV Cache 换入换出会占满 HBM 带宽调度器还要花时间在 CPU 上做上下文管理。把它压到 128 左右反而能让 TTFT 波动更小。这个后面排障部分还会展开。4. 验证请求与成功结果校验配置跑起来之后怎么确认结果是可信的不能只看脚本最后打印的平均值得做几层校验。第一层先确认服务本身能正常响应。在跑压测前用一条最简单的请求探活curl https://taotoken.net/api/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer sk-你的TaoToken密钥 \ -d { model: 你的模型ID, messages: [{role: user, content: 你好}], max_tokens: 16 }返回里能看到choices字段和正常的 token 输出说明通道是通的。如果这里就报错先别跑压测去排障部分看。第二层跑完一轮压测后检查输出 JSON 的关键字段。benchmark_serving.py会输出类似这样的结构{ completed: 200, request_throughput: 3.92, mean_ttft_ms: 210.4, mean_tpot_ms: 45.2, mean_tps: 22.1, p99_ttft_ms: 480.6 }重点看三个completed是否等于num-prompts有没有请求失败、mean_ttft_ms是否在合理区间、request_throughput随 request-rate 的变化趋势。如果completed明显小于 200说明有请求超时或被拒这轮数据要打问号。第三层把多轮结果汇总成表观察拐点。下面是我实测下来的一组典型数据Instinct MI250X 双卡Llama-3-8BTP2max-num-seqs128请求速率 (QPS)平均 TTFT (ms)平均 TPOT (ms)成功 RPS错误率220544.81.950%421045.23.900%824544.87.800%1238043.511.20.5%16120038.110.54.2%看这张表QPS 从 2 到 8TTFT 基本稳定在 200-250msRPS 线性增长这是健康区间。到 QPS12 开始出现膝点TTFT 跳到 380msRPS 增长放缓。QPS16 时 TTFT 直接破 1.2 秒RPS 反而回落错误率升到 4.2%。这个拐点就是系统的实际承载上限。校验时还要注意一个细节mean_tpot_ms在高并发下反而可能下降因为批处理效率提高了但这是以 TTFT 恶化为代价的。别只看 TPOT 好看就以为系统没问题。如果你要写自定义校验脚本核心思路是维护一个请求队列按泊松分布发送实时记录每个请求的生命周期。用 asyncio 和 aiohttp 就能做import asyncio import aiohttp import time async def send_one(session, url, payload, results): start time.perf_counter() async with session.post(url, jsonpayload) as resp: data await resp.json() first_token_time time.perf_counter() - start results.append({ ttft: first_token_time, status: resp.status, tokens: len(data.get(choices, [{}])[0].get(message, {}).get(content, )) }) async def main(): url https://taotoken.net/api/v1/chat/completions headers {Authorization: Bearer sk-你的TaoToken密钥} payload {model: 你的模型ID, messages: [{role: user, content: 写一段介绍}], max_tokens: 128} results [] async with aiohttp.ClientSession(headersheaders) as session: tasks [send_one(session, url, payload, results) for _ in range(50)] await asyncio.gather(*tasks) print(f完成 {len(results)} 个请求平均 TTFT {sum(r[ttft] for r in results)/len(results):.3f}s) asyncio.run(main())这个脚本能帮你发现长尾延迟的具体成因比官方脚本的平均值更有诊断价值。5. 本篇常见报错排查压测过程中最容易撞上的几个报错我按出现频率排一下对照着看。401 Unauthorized。这个最常见基本是 Key 或 Base URL 填错。检查三件套Base URL 是不是https://taotoken.net/api别多加/v1脚本内部会拼、API Key 有没有多余空格、Model ID 是否和通道内一致。如果用的是本地 vLLM401 通常是--api-key没设或设了但脚本没带。local proxy failed / connection refused。这个报错说明脚本连不上目标地址。本地实例的话确认 vLLM 服务在跑、端口对得上默认 8000。走统一通道的话确认网络能通、没有本地代理拦截。注意别在环境变量里留了奇怪的HTTP_PROXY会干扰请求。reading choices 相关报错。典型的是KeyError: choices或解析响应时失败。这通常意味着返回的不是标准 OpenAI 格式可能是通道返回了错误信息但状态码是 200或者模型 ID 写错导致返回了非预期结构。先单独用 curl 打一条看原始返回长什么样。OAuth / 鉴权类报错。如果你在 Claude Code 或类似工具里配置报 OAuth 相关错误多半是认证方式没选对。这类工具要的是 Base URL Key Model ID 三件套别去走 OAuth 流程。配置片段参考{ base_url: https://taotoken.net/api, api_key: sk-你的TaoToken密钥, model: 你的模型ID }CUDA/ROCm OOM。Instinct 上跑高并发显存爆掉很常见。降低--gpu-memory-utilization比如从 0.9 降到 0.85或者调小--max-num-seqs。如果用了--tensor-parallel-size 2确认两张卡都被识别到rocm-smi看一眼显存占用。TTFT 异常高但 RPS 正常。这种不是报错但数据不可信。检查是不是--max-concurrency设太大导致请求排队。也可能是数据集里长 prompt 太多拉高了平均值。建议按 prompt 长度分桶统计别只看全局平均。排障时有个通用原则先用最小请求验证通道再逐步加负载。别一上来就跑 200 个 prompt出错了根本不知道是哪层的问题。6. 用统一 Key 把压测流程固化下来压测做完一轮不算完能复现、能横向对比才有价值。我的做法是把配置和命令都固化到脚本里每次换模型只改 Model ID 一个字段。TaoToken 统一 Key 在这里省了不少事不用为每个模型单独申请凭证Base URL 固定压测脚本的接入层完全不用动。具体怎么落地建一个bench_config.json把 Base URL、Key、Model ID、并发梯度都放进去压测脚本读这个文件生成命令。换模型时只改model_id其他不动。这样团队里任何人拿到配置都能跑出可比的数据。如果你要做长期、多轮的压测对比Coding Plan 那套凭证体系也能复用入口在 https://taotoken.net/coding-plan 。模型对话入口可以用来快速验证某个模型是否值得纳入压测清单https://taotoken.net/model-conversation 。接入文档里有完整的参数说明和示例遇到不确定的字段先去查https://taotoken.net/doc 。最后给个实用技巧压测报告里一定要记录硬件环境、ROCm 版本、vLLM 版本、模型精度、TP 配置。我踩过的坑是同一套命令在不同 ROCm 版本下 TTFT 能差 30%不记录环境根本没法归因。把这份报告模板存下来下次直接填数就行。