Skip to content

vLLM 性能调优指南

vLLM 的性能受调度、KV Cache、并行策略、量化、CUDA Graph 等多种因素影响。本文将从核心调度与缓存优化、并行策略、其他性能增强技术、内存优化与关键参数总结等方面,系统介绍 vLLM 的性能调优方法。

1. 核心调度与缓存优化

1.1 任务抢占(Preemption)

由于 Transformer 的自回归特性,当并发请求较高时,系统可能面临 KV Cache 空间不足的挑战。此时 vLLM 会触发抢占机制,暂停部分请求以释放 KV Cache,并在资源满足后对这些请求进行重计算(Recompute)

发生抢占时,日志会输出类似以下警告:

text
WARNING 05-09 00:49:33 scheduler.py:1057 Sequence group 0 is preempted by PreemptionMode.RECOMPUTE mode because there is not enough KV cache space. This can affect the end-to-end performance. Increase gpu_memory_utilization or tensor_parallel_size to provide more KV cache memory. total_cumulative_preemption_cnt=1

抢占机制提升了系统鲁棒性(Robustness),但重计算会增加端到端延迟。若频繁发生抢占,可采取以下措施:

  • 提高 gpu_memory_utilization:为 KV Cache 预分配更多显存。
  • 降低并发限制:减少 max_num_seqsmax_num_batched_tokens
  • 增加 tensor_parallel_size:将模型权重分片到更多 GPU,单卡为 KV Cache 腾出更多空间,但会引入跨卡同步开销。
  • 增加 pipeline_parallel_size:将模型层分布到多卡,减少单卡权重占用,但会增加流水线气泡(Pipeline Bubble)。

可通过 Prometheus 指标监控抢占次数,并设置 disable_log_stats=False 记录累计抢占计数。

在 vLLM V1 中,默认抢占模式为 RECOMPUTE;V0 中默认使用 SWAP(交换到主机内存)。

1.2 前缀缓存(Prefix Caching)

自动前缀缓存(Automatic Prefix Caching,APC) 缓存已处理查询的 KV Cache。当新请求与历史查询共享相同前缀时,可直接复用对应 KV Cache,跳过共享部分的重复计算。

APC 能显著降低 TTFT,特别适用于多轮对话与长 System Prompt 场景。

python
from vllm import LLM

llm = LLM(
    model="lmsys/longchat-13b-16k",
    enable_prefix_caching=True,
)

1.3 分块预填充(Chunked Prefill)

当输入 Prompt 较长时,Prefill 阶段计算负担显著增加,带来以下挑战:

  • TTFT 变长:Prefill 涉及大量输入 Token 计算。
  • 显存瞬时占用高:长序列可能导致 OOM。

分块预填充(Chunked Prefill) 将较大的 Prefill 请求拆分为多个小块,并允许这些块与 Decode 请求在同一批次中并行处理,从而在计算密集型 Prefill 与内存密集型 Decode 之间取得更优平衡。

默认情况下,vLLM 倾向于优先处理 Prefill 请求。启用 Chunked Prefill 后,调度器会优先处理 Decode 请求,再填充 Prefill 块:

  • 显著降低单个长 Prefill 的计算负载。
  • 减少瞬时显存占用,降低 OOM 风险。
  • 改善 TTFT 与整体推理效率。

在 vLLM V1 中,分块预填充默认启用。

python
from vllm import LLM

llm = LLM(
    model="lmsys/longchat-13b-16k",
    enable_chunked_prefill=True,
)

可根据业务需求调整 max_num_batched_tokens

  • 较小值(如 2048):适合低延迟场景,减少 Prefill 块对 Decode 的阻塞。
  • 较大值(如 > 8096):适合吞吐优先场景,尤其在大显存 GPU 上运行小模型时。
python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    max_num_batched_tokens=16384,
)

2. 并行策略

2.1 张量并行(Tensor Parallelism,TP)

将模型参数在每一层内部切分到多个 GPU,是单节点超大模型推理最常用的方式。

适用场景:

  • 模型尺寸过大,单张 GPU 无法容纳。
  • 旨在减少每张 GPU 的显存压力,为 KV Cache 预留更多空间。
python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.3-70B-Instruct",
    tensor_parallel_size=4,
)

2.2 流水线并行(Pipeline Parallelism,PP)

将模型的不同层分配到不同 GPU,形成处理流水线。

适用场景:

  • TP 方案已达瓶颈,需要进一步在更多 GPU 或跨节点间分布模型。
  • 模型深度较大但每层计算量较小(“窄深”模型)。

TP 与 PP 可组合使用:

python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.3-70B-Instruct",
    tensor_parallel_size=4,
    pipeline_parallel_size=2,
)

2.3 专家并行(Expert Parallelism,EP)

专用于稀疏专家模型(MoE),将不同专家网络分布到不同 GPU。

适用场景:

  • MoE 架构(如 DeepSeek-V3、Qwen3-MoE)。
  • 需要在多 GPU 之间均衡专家路由与计算负载。
python
from vllm import LLM

llm = LLM(
    model="Qwen/Qwen3-MoE",
    tensor_parallel_size=4,
    enable_expert_parallel=True,
)

2.4 数据并行(Data Parallelism,DP)

将完整模型副本部署到多个 GPU 或集群节点,并发处理不同 Batch。

适用场景:

  • GPU 资源充足,可重复部署模型副本。
  • 目标是提升整体吞吐量而非单个模型容量。
  • 多用户场景下需要请求隔离或独立服务。
python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.3-70B-Instruct",
    data_parallel_size=2,
)

MoE 层的总并行粒度为 TP×DP

3. 其他性能增强技术

3.1 异步分词器池(Asynchronous Tokenizer Pool)

高并发场景下,单一分词器可能成为瓶颈。tokenizer_pool_size 控制可同时运行的分词器 Worker 数量,支持多任务并行处理,减少等待时间。

python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.3-70B-Instruct",
    tokenizer_pool_size=4,
)

建议根据 CPU 核心数合理配置,并监控任务队列长度与平均等待时间。

3.2 投机解码(Speculative Decoding)

投机解码通过辅助模型或 N-gram 机制提前预测多个候选 Token,主模型在一次前向传播中并行验证,从而加速 Decode。

核心机制:

  • 若预测 Token 与主模型一致(命中),直接接受并更新 KV Cache。
  • 若不一致(未命中),从不一致处重新生成,代价较小。

关键参数:

  • num_speculative_tokens:每次并行生成的候选 Token 数。增加可提升理论效率,但会增加显存占用并可能降低命中率。
  • ngram_prompt_lookup_max:N-gram 提示查找的最大窗口大小。

示例:

python
from vllm import LLM

llm = LLM(
    model="meta-llama/Meta-Llama-3-8B-Instruct",
    speculative_model="[ngram]",
    num_speculative_tokens=5,
)

3.3 量化(Quantization)

量化通过降低权重与/或激活值精度(FP32 → INT8 / INT4 / FP8),显著减少内存占用与计算开销。

vLLM 支持多种量化方法,如 AWQ、GPTQ、GPTQ-Marlin、FP8 等:

python
from vllm import LLM

# AWQ 量化
llm = LLM(model="TheBloke/Llama-2-7b-Chat-AWQ", quantization="awq")

# GPTQ-Marlin(推荐)
llm = LLM(
    model="Qwen/Qwen2.5-7B-Instruct-GPTQ-Int4",
    quantization="gptq_marlin",
)

常见方法:

  • AWQ(Activation-aware Weight Quantization):考虑激活值分布的权重量化,精度较高。
  • GPTQ(Generalized Post-Training Quantization):针对 Decoder-only 架构的高效后训练量化。
  • GPTQ-Marlin:基于 Marlin 内核优化的 GPTQ 实现,计算效率更高。

4. 内存优化与调参建议

4.1 GPU 显存利用率(gpu_memory_utilization

控制 vLLM 允许使用的 GPU 显存占总显存的比例(01),主要用于预分配 KV Cache 与模型权重。

  • 设置过高可能导致 Host 系统 OOM。
  • 设置过低则 KV Cache 不足,引发频繁抢占,影响吞吐。
  • 建议从默认值 0.9 开始,在监控显存的同时谨慎提高到 0.95 或 0.98。
python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    gpu_memory_utilization=0.92,
)

4.2 最大并发序列数(max_num_seqs

直接控制 vLLM 的并发水平。KV Cache 总需求近似为:

Total Cachemax_model_len×max_num_seqs×CacheBlockSize

目标是在不 OOM 的前提下将该值最大化,以保证 GPU 持续高负载。

4.3 批处理 Token 数(max_num_batched_tokens

控制每次批处理允许的最大 Token 数量,是平衡延迟与吞吐的关键:

场景推荐值效果
延迟敏感 / 实时性高较小值(256512降低单次批处理负载,加快 TTFT
吞吐优先 / 请求量大较大值(10244096提高 Prefill 批处理效率
资源约束不超过 GPU 可用显存避免 OOM

4.4 模型上下文长度(max_model_len

控制模型可处理的最大总序列长度(输入 + 输出)。该值必须小于或等于模型的 max_position_embeddings。适当减小此值是解决 OOM 的有效手段。

python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    max_model_len=2048,
)

4.5 CUDA Graph 编译配置

enforce_eager 控制是否仅使用 PyTorch Eager 模式。默认 False 时,vLLM 采用 Eager 与 CUDA Graph 混合执行。

  • 小型模型:启用 CUDA Graph(默认)通常性能更优。
  • 大型模型 / OOM 场景:设置 enforce_eager=True 禁用 CUDA Graph,可节省显存。
python
from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    enforce_eager=True,
)

4.6 CPU 卸载

显存受限时,可使用 --cpu-offload-gb 将部分 KV Cache 卸载到 CPU 内存,扩展 GPU 的“虚拟内存”,但会引入 PCIe 传输延迟。

4.7 多模态模型优化

对于 VLM 等模型,可通过 limit_mm_per_prompt 限制单个 Prompt 中图像、视频或音频的数量,避免不必要的激活内存预留。

python
from vllm import LLM

llm = LLM(
    model="Qwen/Qwen2.5-VL-3B-Instruct",
    limit_mm_per_prompt={"image": 2},
)

5. 关键参数配置总结

参数调优方向核心目的场景 / 备注
--max-model-len减小降低显存需求 / 缓解 OOM解决 OOM 的第一优先级
--gpu-memory-utilization0.850.95平衡 KV Cache 与系统显存默认 0.9;过高易 OOM,过低易抢占
--tensor-parallel-size增加部署超大模型 / 释放单卡 KV 空间提升模型容量与吞吐
--max-num-seqs最大化提升并发度与吞吐在不 OOM 前提下尽量调高
--max-num-batched-tokens场景化设置平衡延迟与吞吐延迟敏感用小值,吞吐优先用大值
--enable-chunked-prefillTrue优化长序列 PrefillvLLM V1 默认启用
--enable-prefix-cachingTrue降低 TTFT / 减少重复计算多轮对话 / 长 System Prompt
--enforce-eagerTrue / False控制 CUDA GraphTrue 省显存,False 通常性能更优
--cpu-offload-gb增加提升可扩展性显存紧张时的备选,但增加 PCIe 延迟
--disable-log-statsTrue(生产)轻微降低 CPU / IO 开销生产环境可关闭统计日志

6. 关键参数详解

6.1 tensor_parallel_size

将 LLM 层或权重分片到多个 GPU,支持单 GPU 无法容纳的模型,降低延迟并提高有效批处理大小。建议遇到 OOM 时优先增加此参数;在多 GPU 机器上,建议将其设置为实际使用的 GPU 数量。使用更高 TP 时需确保 GPU 间具备 NVLink 等高带宽互连。

6.2 gpu_memory_utilization

指定 vLLM 预分配给操作(主要是 KV Cache)的总 GPU 内存百分比。更高的值意味着更大 KV Cache,可容纳更多并发序列或更长单个序列,直接提高吞吐量。建议从 0.9 开始,若 GPU 仍有闲置内存可逐步提高到 0.95 或 0.98。

6.3 max_model_len

为单个请求设置严格的 Token 数量上限,超过此限制的输入序列将被截断。恰当设置此参数对于平衡长序列支持、显存效率与整体性能至关重要。

6.4 max_num_seqs

定义调度器在 GPU 上同时处理的最大并发序列数量。越高允许同步处理更多请求,直接提高整体吞吐量。目标是在不 OOM 的前提下最大化该值。

6.5 enforce_eager

设置为 True 时强制使用 PyTorch Eager 模式,禁用 CUDA Graph。通常会导致推理速度变慢,主要用于性能分析或 OOM 缓解。

6.6 disable_log_stats

禁用运行时统计信息日志记录。在高负载且具备外部监控的生产环境中,可轻微降低 CPU / IO 开销。

参考

Maintained by Robin