自建大模型网关压测,wrk模拟万QPS
自建大模型网关在正式上线前,通常要压一压高并发能力。
用 wrk 模拟万 QPS 时,不能只盯面板上的平均延迟,还要同步观察 CPU、GPU、连接队列和错误率。
本文从压测前检查到瓶颈定位,给出一套可直接照做的命令和判断方法,适合第一次做网关压测的读者按步骤执行。
压测前先确认网关的请求方式和资源限制
wrk 本身只是一个 HTTP 压测工具,它不关心你的网关是 OpenAI 兼容接口还是自定义协议。
压测前先确认三点:
- 网关的访问地址和端口,例如
http://127.0.0.1:8080。 - 接口是 GET 还是 POST。大模型网关通常是 POST,而且请求体里有模型名称、参数等内容。
- 当前机器 CPU 核数、内存大小,以及 GPU 型号和显存。这些数据决定了压测时观察基准。
如果网关和模型推理服务在同一台机器上,建议同时开启 CPU 和 GPU 监控;
如果分开部署,则需要在两端分别采集负载。
用 wrk 发送 POST 请求并模拟万 QPS
wrk 默认发送 GET 请求,要压 POST 接口需要写一个 Lua 脚本。
比如创建一个 post.lua,内容如下:
wrk.method = "POST"
wrk.headers["Content-Type"] = "application/json"
wrk.body = '{"model": "qwen2.5-72b", "messages": [{"role": "user", "content": "hello"}]}'
然后执行压测命令:
wrk -t16 -c400 -d60s -s post.lua --latency http://127.0.0.1:8080/v1/chat/completions
这里 -t16 表示 16 个线程,-c400 表示 400 个并发连接,-d60s 表示持续 60 秒。
想要达到万 QPS,压测机本身要足够快,否则请求还没发出去,wrk 自己就成为了瓶颈。
如果单机 wrk 无法打满,可以准备 2-3 台压测机同时跑,最后把 QPS 相加。
压测过程中实时观测 CPU 和 GPU 负载
压测时不要只等 wrk 的最终报告,要在一个终端窗口运行压测命令,另开终端同步监控资源。
CPU 侧使用 top 或 htop,重点看:
- 用户态 CPU 占用率(us)是不是接近 100%。
- 进程列表中哪些进程吃掉最多 CPU。
load average是否超过 CPU 核数。
GPU 侧使用 nvidia-smi 持续刷新:
nvidia-smi -l 1
观察 GPU-Util(利用率)和显存占用。
判断瓶颈的关键规则是:
- CPU 占用接近饱和而 GPU-Util 只有 20%-30%:说明请求进入网关后,大量时间花在 Python 处理、认证、路由、tokenize 或排队上,真正的推理后端没有被打满。
- GPU-Util 接近 100% 并且显存占用持续高位:说明瓶颈在模型推理侧,网关转发能力还有余量。
- CPU 和 GPU 都有空闲,但 wrk 报告的错误率升高或延迟变大:优先检查带宽、连接数限制和系统文件描述符上限。
常见误判和避坑说明
第一次压测时最容易出现几个判断偏差:
- wrk 显示 QPS 高不代表网关处理量大。wrk 统计的是从发出请求到收到响应,如果网关直接返回 429 或错误码,这个请求也会计入吞吐量。压测过程中要同时关注返回码。
- 并发连接数不是越大越好。连接数从 200 提升到 2000,QPS 可能先升后降,过高的并发会让 CPU 消耗在线程切换上,而非请求处理。建议从 200、400、800 三档分别测试。
- 不要把压测机和网关放在同一块网络环境。如果网关所在机器只有一张网卡,压测流量会占用同样带宽,导致结果偏离真实情况。
怎么确认瓶颈是在网关还是模型推理
想看瓶颈是在哪一层,可以做一个简单对照组。
先屏蔽模型推理,比如把网关指向一个静态响应的 mock 服务,再做一次同样参数的压测。
如果 mock 模式下 QPS 远超真实模式,那瓶颈在推理后端或模型服务;
如果 mock 模式下 QPS 也很低,那问题出在网关本身的配置或机器 CPU 上。
另一种做法是在网关层记录每个请求的处理耗时和推理耗时。
比如在日志里输出 total_ms 和 infer_ms 两个字段,当 infer_ms 占比超过 90% 时优先优化模型推理或显存容量;
当 total_ms 远大于 infer_ms 时,则要优化网关的异步处理、连接池和线程数。
完成压测后,建议把 wrk 的输出结果、监控截图和配置文件保存下来,方便后续调参时对比。
如果按本文步骤操作后仍有无法解释的异常,优先检查网关运行日志和系统 dmesg 输出,很多隐性瓶颈会在这里留下线索。