🔧 vllm bench latency 参数详解
🎯 这是 vLLM 的纯引擎延迟测试工具 ,直接在 GPU 上跑模型推理,不经过 HTTP 服务层,测的是"模型本身能跑多快"。
🆚 和
bench serve的区别:
bench latency→ 实验室测发动机马力(纯推理性能)bench serve→ 上路测整车性能(含网络/调度/并发)
📋 参数分类速览
🔹 基础测试:--input-len / --output-len / --batch-size / --n
🔹 结果稳定:--num-iters / --num-iters-warmup
🔹 保存结果:--output-json / --profile
🔹 模型配置:--model / --dtype / --quantization / --max-model-len
🔹 多卡加速:-tp / -pp / -dp
🔹 显存优化:--gpu-memory-utilization / --kv-cache-dtype / --block-size
🔹 高级功能:--enable-lora / --compilation-config
🧪 一、基础测试参数
🔹 核心参数表
| 参数 | 默认值 | 解释 | 典型取值 |
|---|---|---|---|
--input-len |
32 |
用户问题有多长(token 数) | 20(短句)/ 100(段落)/ 512(长文) |
--output-len |
128 |
模型回复有多长(token 数) | 50(简短回答)/ 200(详细解释)/ 512(长文生成) |
--batch-size |
8 |
一次同时处理几个请求 | 1(单用户)/ 8(小并发)/ 32(高并发) |
--n |
1 |
同一个问题生成几个不同答案 | 1(普通聊天)/ 4(多候选排序) |
--use-beam-search |
False |
用"精挑细选"模式生成(更准但更慢) | 写代码/数学题时开启 |
🔹 场景示例 1:测"用户问一句,模型回一句"的延迟
🎯 业务场景:客服机器人,用户问"订单怎么查?",模型回复操作步骤
bash
# 🧪 直接复制运行:
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 20 \ # "订单怎么查?" ≈ 20个token
--output-len 80 \ # 回复步骤 ≈ 80个token
--batch-size 1 # 一次只服务1个用户(模拟真实对话)
📊 你会看到:
平均延迟: 850 毫秒/请求 ← 用户等0.85秒看到完整回复
吞吐量: 94 tokens/秒 ← 服务器每秒能生成94个token
P99延迟: 1.1 秒 ← 99%的请求1.1秒内完成
💡 决策:如果延迟 > 2 秒,用户会觉得"卡",需要优化
🔹 场景示例 2:测"批量处理"能提升多少效率
🎯 业务场景:后台批量生成商品描述,100 个商品要写简介,是一次处理 1 个快,还是打包一起处理快?
bash
# 🧪 测试 batch=1(逐个处理)
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 50 \ # 商品名称+关键词 ≈ 50 token
--output-len 100 \ # 商品简介 ≈ 100 token
--batch-size 1 \
--output-json results/batch1.json
# 🧪 测试 batch=16(打包处理)
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 50 \
--output-len 100 \
--batch-size 16 \
--output-json results/batch16.json
📊 对比结果(示例):
batch-size 平均延迟/请求 吞吐量(总) 适合场景 1 900ms 111 tokens/s 实时聊天,用户不能等 16 2.1s 762 tokens/s 后台批量任务,追求总效率
💡 关键结论 :batch 越大,单个请求变慢 ,但总吞吐量提升!
✅ 实时对话 → 用小 batch(1~4)
✅ 批量生成 → 用大 batch(16~32)
🔁 二、结果稳定参数
🔹 参数表
| 参数 | 默认值 | 解释 | 建议取值 |
|---|---|---|---|
--num-iters-warmup |
10 |
先空跑几次"热身",不计入结果 | 10(小模型)/ 20(大模型) |
--num-iters |
30 |
正式跑几次取平均,减少波动 | 30(快速测试)/ 50(精确对比) |
🔹 场景示例:为什么需要"预热"?
🎯 业务场景:第一次跑模型要加载权重、编译 CUDA 图,很慢;预热后才是"真实水平"
bash
# ❌ 错误示范:不预热,结果偏慢
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 100 \
--output-len 100 \
--num-iters-warmup 0 \ # ⚠️ 没预热!
--num-iters 5 # ⚠️ 只测5次,波动大
# 输出:平均延迟 2.3 秒 ← 包含了加载模型的开销
# ✅ 正确示范:预热+多次测试
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 100 \
--output-len 100 \
--num-iters-warmup 10 \ # ✅ 先热身10次
--num-iters 30 # ✅ 再测30次取平均
# 输出:平均延迟 1.1 秒 ← 这才是稳态性能!
💡 记忆口诀:
🔥 "第一次都慢,预热才准"
📊 "测得越多,结果越稳"
💾 三、结果输出参数
🔹 参数表
| 参数 | 默认值 | 解释 | 使用场景 |
|---|---|---|---|
--output-json |
- | 把结果存成文件,方便后续对比 | 做 A/B 测试、写报告 |
--disable-log-stats |
False |
不打印控制台日志,只存文件 | 自动化脚本中用 |
--profile |
False |
生成性能分析文件,看哪步最耗时 | 优化模型时用 |
🔹 场景示例:保存结果做对比报告
🎯 业务场景:老板问"量化后速度提升多少?",你需要数据支撑
bash
# 1️⃣ 测原始模型
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 100 \
--output-len 100 \
--batch-size 8 \
--output-json results/original.json
# 2️⃣ 测 AWQ 量化版本
vllm bench latency \
--model meta-llama/Llama-3-8b-AWQ \
--input-len 100 \
--output-len 100 \
--batch-size 8 \
--output-json results/awq.json
# 3️⃣ 用 Python 快速对比(保存为 compare.py)
python3 << 'EOF'
import json
orig = json.load(open("results/original.json"))
awq = json.load(open("results/awq.json"))
print(f"📊 量化加速比: {orig['avg_latency_ms']/awq['avg_latency_ms']:.2f}x")
print(f" 原始延迟: {orig['avg_latency_ms']:.1f}ms")
print(f" AWQ延迟: {awq['avg_latency_ms']:.1f}ms")
EOF
📊 输出示例:
📊 量化加速比: 1.85x
原始延迟: 1120.5ms
AWQ延迟: 605.3ms
💡 结论:AWQ 量化后速度提升 85%,显存占用减少 40% → ✅ 推荐上线!
⚙️ 四、模型配置参数
🔹 核心参数表
| 参数 | 默认值 | 解释 | 典型取值 |
|---|---|---|---|
--model |
Qwen/Qwen3-0.6B |
模型名字或本地路径 | meta-llama/Llama-3-8b / ./models/my-model |
--dtype |
auto |
用哪种精度跑:float16 / bfloat16 / float32 | bfloat16(A100 推荐)/ float16(V100 推荐) |
--quantization, -q |
- | 用哪种量化:awq / gptq / fp8 | -q awq(4bit 量化,速度快) |
--max-model-len |
模型默认 | 最大支持多长的上下文 | 4096(短对话)/ 32768(长文档) |
--seed |
0 |
随机种子,保证结果可复现 | --seed 42(方便调试) |
🔹 场景示例 1:在消费级显卡上跑大模型
🎯 业务场景:只有 1 张 RTX 4090(24GB 显存),想跑 Llama-3-8B,怎么配置不爆显存?
bash
vllm bench latency \
--model meta-llama/Llama-3-8b \
--dtype float16 \ # ✅ 4090 不支持 bfloat16,用 float16
--quantization awq \ # ✅ 4bit 量化,显存占用减半
--max-model-len 4096 \ # ✅ 限制上下文长度,省显存
--gpu-memory-utilization 0.85 \ # ✅ 留 15% 显存给系统,防崩溃
--input-len 100 \
--output-len 200 \
--batch-size 4
💡 显存估算技巧:
8B 模型 float16 ≈ 16GB
AWQ 4bit 量化 ≈ 5GB
KV cache(100+200 token, batch=4)≈ 1GB
✅ 总计 ≈ 6GB < 24GB → 安全!
🔹 场景示例 2:支持长文档总结
🎯 业务场景:用户上传 1 万字文档,让模型总结,需要支持长上下文
bash
vllm bench latency \
--model meta-llama/Llama-3-8b-Instruct \
--max-model-len 32768 \ # ✅ 支持 32K 上下文
--input-len 2000 \ # 📄 模拟 1 万字文档 ≈ 2000 token
--output-len 500 \ # 📝 总结 ≈ 500 token
--batch-size 1 \ # 🎯 长文本通常单用户请求
--gpu-memory-utilization 0.9 \
--kv-cache-dtype fp8 # ✅ KV cache 用 fp8,省 50% 显存
⚠️ 注意:长上下文 + 大 batch = 显存爆炸!
✅ 长文本场景建议:
batch-size=1+kv-cache-dtype=fp8
🚀 五、多卡加速参数
🔹 参数表
| 参数 | 缩写 | 解释 | 典型取值 |
|---|---|---|---|
--tensor-parallel-size |
-tp |
把模型切到多张卡上算(适合大模型) | -tp 2(2 卡)/ -tp 4(4 卡) |
--pipeline-parallel-size |
-pp |
把模型分层,不同卡算不同层(适合超大模型) | -pp 2(80B+ 模型) |
--data-parallel-size |
-dp |
复制多份模型,同时处理不同请求(适合高并发) | -dp 4(4 副本) |
🔹 场景示例:用 2 张卡加速 70B 大模型
🎯 业务场景:Llama-3-70B 单卡跑不动,用 2 张 A100(80GB)张量并行
bash
vllm bench latency \
--model meta-llama/Llama-3-70b \
-tp 2 \ # ✅ 2 卡张量并行
--input-len 100 \
--output-len 200 \
--batch-size 1 \ # 大模型通常 batch=1
--dtype bfloat16 \
--gpu-memory-utilization 0.9
📊 效果对比(示例):
配置 显存占用/卡 平均延迟 是否可行 单卡 80GB 75GB ❌ OOM 崩溃 ❌ 不可行 2 卡 TP 40GB/卡 3.2 秒 ✅ 可上线 4 卡 TP 22GB/卡 1.8 秒 ✅ 更优(如果资源够)
💡 选择建议:
- 模型 ≤ 13B → 单卡足够
- 模型 30~70B → 2~4 卡 TP
- 模型 ≥ 100B → TP+PP 组合
🧠 六、显存优化参数
🔹 参数表
| 参数 | 默认值 | 解释 | 优化效果 |
|---|---|---|---|
--gpu-memory-utilization |
0.9 |
用多少比例显存给模型(留点给系统) | 0.85(稳)/ 0.95(极限) |
--block-size |
自动 | KV cache 分块大小,影响显存碎片 | 16(省显存)/ 32(平衡)/ 64(快) |
--kv-cache-dtype |
auto |
KV cache 用啥精度 | fp8(省 50% 显存)/ bfloat16(准) |
--swap-space |
4 |
CPU 交换空间大小(显存不够时借用) | 8~16(大模型建议调大) |
--enable-prefix-caching |
False |
相同开头的问题,复用已算的 KV | 多轮对话场景提速 30%+ |
🔹 场景示例:多轮对话场景优化
🎯 业务场景:用户连续问"北京天气?""那上海呢?""广州呢?",每轮只改城市名
bash
# ❌ 不开前缀缓存:每轮都重算"北京/上海/广州"前面的部分
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 200 \ # "请告诉我[城市]的天气,包括温度、湿度、..."
--output-len 150 \
--batch-size 1
# ✅ 开启前缀缓存:第一轮算完,后两轮复用"请告诉我...的天气,包括..."的 KV
vllm bench latency \
--model meta-llama/Llama-3-8b \
--input-len 200 \
--output-len 150 \
--batch-size 1 \
--enable-prefix-caching \ # ✅ 关键参数!
--block-size 16 # ✅ 小 block 更适合缓存复用
📊 效果(示例):
轮次 无前缀缓存延迟 有前缀缓存延迟 加速比 第 1 轮 1.2 秒 1.2 秒 1.0x 第 2 轮 1.2 秒 0.4 秒 3.0x 🔥 第 3 轮 1.2 秒 0.3 秒 4.0x 🔥
💡 适用场景:
✅ 多轮对话 / 代码补全 / 文档续写
❌ 每个请求完全独立(如批量翻译)
🎨 七、高级功能参数
🔹 LoRA 适配测试
🎯 场景:主模型 + 多个行业 LoRA(医疗/法律/金融),测切换不同 LoRA 的延迟
bash
vllm bench latency \
--model meta-llama/Llama-3-8b \
--enable-lora \
--max-loras 4 \ # 同时加载 4 个 LoRA
--max-lora-rank 64 \ # LoRA 的 rank
--input-len 100 \
--output-len 200 \
--batch-size 8
🔹 编译优化(加速推理)
🎯 场景:追求极致性能,启用 torch.compile + CUDA Graph
bash
vllm bench latency \
--model meta-llama/Llama-3-8b \
--optimization-level 3 \ # ✅ 最高优化级别
-cc '{"mode": 3, "cudagraph_capture_sizes": [1,2,4,8,16]}' \ # ✅ 自定义 CUDA 图
--input-len 100 \
--output-len 200
⚠️ 注意:编译首次运行会慢(编译开销),但后续推理更快 → 适合长期服务
📊 八、输出指标解读(测试完看什么?)
执行成功后,控制台输出示例:
========= Serving Benchmark Result =========
Successful requests: 30
Total time: 34.2 s
Total tokens: 9000
Throughput: 263.16 tokens/s
Avg latency: 1140.5 ms
P50 latency: 1120.3 ms
P99 latency: 1350.8 ms
============================================
| 指标 | 解释 | 优化方向 |
|---|---|---|
| Throughput | 每秒能生成多少个 token(总产能) | 增大 batch / 量化 / 多卡 |
| Avg latency | 平均每个请求等多久 | 减小 input/output / 降低精度 |
| P50 latency | 一半请求的延迟(中位数) | 看"典型用户体验" |
| P99 latency | 最慢的 1% 请求延迟 | ⚠️ 生产环境重点关注!避免长尾卡顿 |
💡 关键原则:
🔹 聊天机器人 → 优先优化 P99 latency(用户不能等)
🔹 批量任务 → 优先优化 Throughput(总效率第一)
🚀 完整实战工作流
🎯 目标:为"智能客服"选择最优配置
bash
# 1️⃣ 基线测试:单用户、短对话
vllm bench latency \
--model meta-llama/Llama-3-8b-Instruct \
--input-len 50 \
--output-len 100 \
--batch-size 1 \
--num-iters-warmup 10 \
--num-iters 30 \
--output-json results/base.json
# 2️⃣ 扫描 batch size:找吞吐峰值
for BATCH in 1 2 4 8 16; do
vllm bench latency \
--model meta-llama/Llama-3-8b-Instruct \
--input-len 50 \
--output-len 100 \
--batch-size $BATCH \
--output-json "results/batch_$BATCH.json" \
--disable-log-stats
done
# 3️⃣ 尝试量化:提速 + 省显存
vllm bench latency \
--model meta-llama/Llama-3-8b-Instruct \
--quantization awq \
--input-len 50 \
--output-len 100 \
--batch-size 4 \
--output-json results/awq.json
# 4️⃣ 多轮对话优化:开启前缀缓存
vllm bench latency \
--model meta-llama/Llama-3-8b-Instruct \
--enable-prefix-caching \
--input-len 200 \
--output-len 150 \
--batch-size 1 \
--output-json results/prefix_cache.json
# 5️⃣ 决策:对比结果(Python 脚本)
python3 << 'EOF'
import json, glob
print("📊 配置对比(延迟越低越好,吞吐越高越好)")
print(f"{'配置':<20} {'延迟(ms)':>10} {'吞吐(tokens/s)':>15}")
print("-" * 45)
for f in sorted(glob.glob("results/*.json")):
name = f.split("/")[-1].replace(".json", "")
data = json.load(open(f))
print(f"{name:<20} {data['avg_latency_ms']:>10.1f} {data['total_throughput']:>15.1f}")
EOF
📋 预期输出:
📊 配置对比(延迟越低越好,吞吐越高越好)
配置 延迟(ms) 吞吐(tokens/s)
---------------------------------------------
awq 605.3 528.7
base 1140.5 263.2
batch_1 1140.5 263.2
batch_16 2850.1 842.3 ← 吞吐最高,但单请求慢
batch_4 890.2 448.9 ← ✅ 平衡点!
batch_8 1320.7 609.1
prefix_cache 420.8 713.5 ← ✅ 多轮对话首选
✅ 最终决策:
- 单轮问答 → 用
batch_4 + AWQ(延迟 605ms,吞吐 528 tokens/s)- 多轮对话 → 用
prefix_cache + AWQ(延迟 420ms,复用缓存)- 后台批量 → 用
batch_16(吞吐 842 tokens/s,用户可等待)
⚠️ 常见问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
❌ CUDA out of memory |
batch 太大 / 模型太长 / 精度太高 | ↓ batch-size / ↓ max-model-len / 用 --dtype float16 / 加 -q awq |
| 🐢 首次运行极慢 | 模型加载 + CUDA 图编译 | 正常!预热后会变快;或加 --num-iters-warmup 20 |
| 📉 结果波动大 | 迭代次数太少 / 没预热 | ↑ --num-iters 到 50 / ↑ --num-iters-warmup 到 20 |
| 🖥️ 多卡没加速 | 没设 -tp / NCCL 配置问题 |
确认 nvidia-smi 能看到多卡 + 加 -tp 2 重试 |
| 🔁 量化模型报错 | 量化格式不匹配 / 缺依赖 | 确认模型支持该量化 + pip install autoawq bitsandbytes |
🎁 最后 Checklist:
- ✅ 加
--num-iters-warmup 10+--num-iters 30→ 结果更稳- ✅ 小模型先测
batch=1,再逐步增大找峰值- ✅ 长文本场景必加
--enable-prefix-caching- ✅ 显存紧张时优先试
--kv-cache-dtype fp8- ✅ 对比配置时用
--output-json+ 简单 Python 脚本