使用 Vegeta 对 vLLM 大模型进行性能压测实战

使用 Vegeta 对 vLLM 大模型进行性能压测实战记录

一、测试背景与目标

在之前使用 vllm bench serve 和 Locust 压测的基础上,本次引入 Vegeta 这一轻量级 HTTP 压测工具,针对 vLLM 部署的 Qwen2.5-7B-Instruct 模型进行性能测试。

核心目标

  1. 掌握 Vegeta 在 vLLM 场景下的配置方法。
  2. 对比纯短文本、长短文本混合场景下的性能差异。
  3. 验证请求速率(RPS)对系统延迟的影响规律。
  4. 通过 Vegeta 的 HTML 可视化图表,直观定位性能瓶颈。

二、环境与工具准备

2.1 安装 Vegeta

# 下载并解压(以 v12.13.0 为例)
wget https://github.com/tsenart/vegeta/releases/download/v12.13.0/vegeta_12.13.0_linux_amd64.tar.gz
tar -zxvf vegeta_12.13.0_linux_amd64.tar.gz
sudo mv vegeta /usr/local/bin/
chmod +x /usr/local/bin/vegeta

# 验证
vegeta --version

2.2 vLLM 服务启动

source vllm_learn/bin/activate
python -m vllm.entrypoints.openai.api_server \
    --model ./Qwen2.5-7B-Instruct \
    --served-model-name qwen-7b \
    --host 0.0.0.0 --port 8000

三、Vegeta 配置核心:Targets 文件格式

3.1 踩坑记录:JSON 格式 vs HTTP 格式

最初尝试使用标准 JSON 格式编写 target.json,导致报错 bad target: {。原因在于 Vegeta 要求 targets 文件必须是 JSON Lines(单行 JSON) 格式,不支持跨越多行的标准 JSON。

最终采用官方推荐的 HTTP 文本格式(最简洁、可读性最强):

target.json 内容:

# 第一个测试用例:基础文本生成
POST http://localhost:8000/v1/chat/completions
Content-Type: application/json
@./body.json

body.json 内容(短文本请求体):

{"model": "qwen-7b", "messages": [{"role": "user", "content": "你好"}], "max_tokens": 256, "stream": false}

3.2 长短文本混合配置(80% / 20%)

Vegeta 不直接支持权重比例设置,而是通过文件行数来控制概率。每行代表一个独立目标,Vegeta 每次请求时等概率随机选择一行

  • 实现 80% 短文本 + 20% 长文本:在 target.json 中写 4 行短文本目标 + 1 行长文本目标(共 5 行,4/5 = 80%)。

body_short.json(短文本,max_tokens=50):

{"model": "qwen-7b", "messages": [{"role": "user", "content": "你好,请简单介绍一下你自己。"}], "max_tokens": 50, "stream": false}

body_long.json(长文本,max_tokens=500):

{"model": "qwen-7b", "messages": [{"role": "user", "content": "请详细解释一下大语言模型中的Transformer架构..."}], "max_tokens": 500, "stream": false}

target.json(混合配置):

# 短文本请求(占4/5,约80%流量)
POST http://localhost:8000/v1/chat/completions
Content-Type: application/json
@./body_short.json

POST http://localhost:8000/v1/chat/completions
Content-Type: application/json
@./body_short.json

POST http://localhost:8000/v1/chat/completions
Content-Type: application/json
@./body_short.json

POST http://localhost:8000/v1/chat/completions
Content-Type: application/json
@./body_short.json

# 长文本请求(占1/5,约20%流量)
POST http://localhost:8000/v1/chat/completions
Content-Type: application/json
@./body_long.json

四、核心测试过程与数据分析

4.1 测试一:纯短文本,rate=10,持续 60s

vegeta attack -targets=target.json -rate=10 -duration=60s -output=results.bin
vegeta report results.bin
指标 数值
Requests 600
Throughput 9.91 req/s
Mean Latency 427 ms
P50 409 ms
P90 560 ms
P99 921 ms
Max 1.503 s
Success 100%

结论:纯短文本场景下,系统极其健康,P99 < 1秒,成功率 100%。rate=10 完全在系统处理能力之内。

4.2 测试二:混合负载(80%短+20%长),rate=10,持续 60s

指标 数值 变化
Throughput 7.80 req/s 下降
Mean Latency 5,536 ms 恶化 13 倍
P50 2,100 ms 恶化 5 倍
P90 19,931 ms 恶化 35 倍
P99 20,535 ms 恶化 22 倍
Max 20,552 ms
Success 100% 稳定

结论:仅 20% 的长文本请求就导致 P90 延迟飙升至 20 秒。长任务长时间占用 GPU 资源,导致后续短任务被迫排队,形成“队头阻塞”。

4.3 测试三:混合负载,rate=2,持续 60s

指标 数值 变化
Throughput 1.58 req/s 降 5 倍
Mean Latency 4,720 ms 几乎没变
P90 16,857 ms 仅降 3 秒
P99 17,046 ms 仅降 3.5 秒

结论:降低请求速率并未显著改善延迟。根本原因是长任务(max_tokens=500,单次耗时约20秒)的到达速度(0.4 req/s)远超系统处理能力(约0.05 req/s),队列持续堆积。

4.4 测试四:混合负载,rate=1,持续 600s(10分钟)

vegeta attack -targets=target.json -rate=1 -duration=600s -output=results.bin
vegeta report results.bin
指标 数值
Requests 600
Throughput 0.97 req/s
Mean Latency 4,684 ms
P50 1,716 ms
P90 16,633 ms
P99 16,657 ms
Max 16,667 ms
Success 100%

结论:即使速率降到 1 RPS,P90 依然稳定在 16.6 秒。这说明瓶颈不在请求速率,而在于长任务本身的生成耗时。系统达到了“稳态排队”——进出速率平衡,队列不再增长。

五、Vegeta HTML 可视化图表解读

使用以下命令生成图表:

vegeta plot results.bin > plot.html

image

图表解读(以 rate=1 的 10 分钟测试为例):

  • 横轴:时间(秒),纵轴:延迟(对数坐标)。
  • 波谷(~1.7秒):代表 80% 的短文本请求,处理迅速。
  • 规律性尖峰(~16.6秒):代表 20% 的长文本请求,每隔约 5 秒出现一次。
  • 波形特征:呈完美的“梳齿状”,尖峰高度完全一致,说明系统处于稳态,没有出现延迟累积。
  • 颜色:纯黄色(200 OK),无红色错误。

关键结论:图表直观证明了长短任务混合时的双峰延迟分布,并确认长任务排队时间稳定(16.6秒),系统未失控。

六、核心发现与生产建议

6.1 核心结论

  1. 长文本请求是性能杀手:仅 20% 的长任务(max_tokens=500)就能让 P90 延迟从 560ms 飙升至 20秒。
  2. 请求速率不是万能解药:将速率从 10 降到 1,P90 延迟仅从 20秒降至 16.6秒,改善极其有限。瓶颈在长任务的处理能力。
  3. 系统稳定性良好:所有测试中 Success 均为 100%,证明 vLLM 的 Continuous Batching 和 Chunked Prefill 机制有效避免了系统崩溃,但无法消除排队。

6.2 生产环境建议

  1. 限制单次生成长度:将 max_tokens 控制在合理范围(如 200-300),可显著降低长任务延迟。
  2. 长短任务分离部署:为长文本请求(写文章、长文档摘要)分配独立实例,避免阻塞短问答请求。
  3. 引入优先级队列:长任务走低优先级队列,短任务走快速通道。
  4. 控制客户端速率:在网关层设置合理的限流阈值,避免请求堆积。

七、工具对比:Vegeta vs vLLM Bench vs Locust

工具 优势 劣势 适用场景
Vegeta 极简、轻量、HTTP层端到端测试、图表直观 不支持流式响应、无法测 TTFT/TPOT、比例控制靠行数 接口健康度基线测试、快速验证
vLLM Bench 专业、支持 TTFT/TPOT/Goodput、数据集灵活 配置稍复杂、侧重服务端指标 深度性能评测、SLO 达标分析
Locust 灵活、支持复杂业务逻辑、可模拟多轮对话 需自行编写脚本、指标计算靠自定义 模拟真实用户行为、业务场景测试

最佳实践:先用 Vegeta 做快速基线测试,再用 vLLM Bench 做深度性能分析,最后用 Locust 做业务场景验证。


测试环境:ModelScope 免费实例,vLLM 0.29.0,Qwen2.5-7B-Instruct,Vegeta v12.13.0。

参考网站Vegeta 工具_vegeta压测工具,并发执行多个接口-CSDN博客

posted @ 2026-09-22 09:57  xzy186  阅读(4)  评论(0)    收藏  举报