性能优化
本章介绍如何通过量化、并行和配置调优来提升 vLLM 的推理性能。
量化技术
量化通过降低模型权重和计算的精度来减少显存占用和加速推理。
量化类型对比
| 量化类型 | 精度 | 显存节省 | 速度提升 | 精度损失 | 适用场景 |
|---|---|---|---|---|---|
| FP16 | 16-bit | - | 基准 | 无 | 通用 |
| BF16 | 16-bit | 0% | 基准 | 无 | 推荐 |
| INT8 | 8-bit | ~50% | 1.5-2x | 较小 | 通用 |
| FP8 | 8-bit | ~50% | 1.5-2x | 较小 | Hopper GPU |
| AWQ | 4-bit | ~65% | 2-3x | 中等 | 显存受限 |
| GPTQ | 4-bit | ~65% | 2-3x | 中等 | 显存受限 |
INT8 量化
INT8 是最通用的量化方案,兼容性好:
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
quantization="awq", # 使用 AWQ 量化
)
或者使用 bitsandbytes:
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
load_format="bitsandbytes", # 使用 bitsandbytes 加载
)
FP8 量化
FP8 需要 NVIDIA Hopper 架构 GPU(H100、H200 等):
vllm serve meta-llama/Llama-2-7b-chat-hf \
--quantization fp8
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
quantization="fp8"
)
GPTQ 量化
GPTQ 是一种后训练量化方法,精度较高:
from vllm import LLM
# 自动检测量化模型
llm = LLM(
model="TheBloke/Llama-2-7B-Chat-GPTQ", # 量化后的模型
)
手动指定:
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
quantization="gptq",
gpu_memory_utilization=0.95
)
AWQ 量化
AWQ(Activation-Aware Weight Quantization)考虑激活分布:
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
quantization="awq"
)
并行策略
张量并行(Tensor Parallelism)
张量并行将模型权重沿维度分割到多个 GPU:
vllm serve meta-llama/Llama-2-70b-chat-hf \
--tensor-parallel-size 4
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-2-70b-chat-hf",
tensor_parallel_size=4
)
适用场景:
- 单个 GPU 无法容纳模型
- 需要最大化吞吐量
流水线并行(Pipeline Parallelism)
流水线并行将模型层分割到不同 GPU:
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-2-70b-chat-hf",
pipeline_parallel_size=4, # 4 个 GPU 流水并行
tensor_parallel_size=2 # 每个流水线阶段内部 2 卡张量并行
)
数据并行(Data Parallelism)
数据并行用于扩展服务能力:
# 启动多个实例
vllm serve meta-llama/Llama-2-7b-chat-hf --port 8000 &
vllm serve meta-llama/Llama-2-7b-chat-hf --port 8001 &
# 使用负载均衡器分发请求
关键参数调优
显存利用率
from vllm import LLM
# 默认 0.9,保守值 0.8
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
gpu_memory_utilization=0.85, # 留出更多显存给其他任务
max_model_len=4096
)
最大序列长度
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
max_model_len=8192, # 根据实际需求设置
max_num_seqs=256 # 最大并发数
)
批处理参数
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
max_num_seqs=256, # 最大并发序列数
max_num_batched_tokens=8192, # 单批次最大 token 数
max_model_len=4096
)
性能基准测试
使用 benchmark 脚本
# 安装 benchmark 工具
pip install vllm[benchmark]
# 运行吞吐量测试
python -m vllm benchmark throughput \
--model meta-llama/Llama-2-7b-chat-hf \
--num-prompts 1000 \
--input-len 512 \
--output-len 128
自定义性能测试
import time
from vllm import LLM, SamplingParams
llm = LLM(model="meta-llama/Llama-2-7b-chat-hf")
sampling_params = SamplingParams(temperature=0.7, max_tokens=100)
prompts = ["测试提示词"] * 100
# 预热
llm.generate(prompts[:10], sampling_params)
# 正式测试
start = time.time()
outputs = llm.generate(prompts, sampling_params)
end = time.time()
total_tokens = sum(len(o.outputs[0].token_ids) for o in outputs)
throughput = total_tokens / (end - start)
print(f"总耗时: {end - start:.2f}s")
print(f"总 token 数: {total_tokens}")
print(f"吞吐量: {throughput:.2f} tokens/s")
常见性能问题
延迟过高
检查项:
- 确认 GPU 利用率
- 检查 batch size 是否合适
- 启用 Chunked Prefill
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
enable_chunked_prefill=True,
max_num_batched_tokens=2048
)
显存不足(OOM)
解决方案:
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
gpu_memory_utilization=0.7, # 降低显存使用
max_model_len=2048, # 限制最大序列长度
quantization="fp8" # 启用量化
)
吞吐量低
优化方向:
llm = LLM(
model="meta-llama/Llama-2-7b-chat-hf",
max_num_seqs=512, # 提高并发数
max_num_batched_tokens=16384, # 增加批次大小
enable_chunked_prefill=True
)
小结
性能优化需要根据实际场景选择合适的策略:
- 量化:首选 FP8(Hopper)或 AWQ,减少显存占用
- 并行:根据模型大小和 GPU 数量选择合适的并行策略
- 参数调优:调整 max_model_len 和批处理参数找到最优配置
- 测试验证:使用 benchmark 工具验证优化效果