跳至内容

优化与调优

本指南涵盖vLLM V1的优化策略与性能调优方法。

抢占

Due to the auto-regressive nature of transformer architecture, there are times when KV cache space is insufficient to handle all batched requests. In such cases, vLLM can preempt requests to free up KV cache space for other requests. Preempted requests are recomputed when sufficient KV cache space becomes available again. When this occurs, you may see the following warning:

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

虽然这种机制确保了系统的健壮性,但抢占和重新计算可能会对端到端延迟产生不利影响。 如果您经常遇到抢占情况,请考虑以下措施:

  • 增加 gpu_memory_utilization。vLLM 会使用该内存百分比预分配 GPU 缓存。通过提高利用率,您可以提供更多的键值缓存空间。
  • 减少 max_num_seqsmax_num_batched_tokens。这会减少批次中的并发请求数量,从而需要更少的KV缓存空间。
  • 增加 tensor_parallel_size。该参数会将模型权重分片到多个GPU上,使每个GPU能为KV缓存分配更多内存。但增加此值可能导致过高的同步开销。
  • 增加 pipeline_parallel_size。这会将模型层分布到多个GPU上,减少每个GPU上模型权重所需的内存,间接为KV缓存释放更多内存。但增加此值可能会导致延迟增加。

您可以通过vLLM暴露的Prometheus指标监控抢占请求的数量。此外,您可以通过设置disable_log_stats=False来记录抢占请求的累计数量。

在vLLM V1中,默认的抢占模式是RECOMPUTE而非SWAP,因为在V1架构中重新计算的开销更低。

分块预填充

分块预填充功能允许vLLM将大型预填充任务拆分为更小的块处理,并与解码请求进行批量处理。该特性通过更好地平衡计算密集型(预填充)和内存密集型(解码)操作,有助于同时提升吞吐量和降低延迟。

在vLLM V1版本中,默认始终启用分块预填充功能。这与vLLM V0版本不同,后者会根据模型特性有条件地启用该功能。

启用分块预填充后,调度策略会优先处理解码请求。它会将所有待处理的解码请求批量处理,然后再调度任何预填充操作。当max_num_batched_tokens预算中有可用令牌时,它会调度待处理的预填充请求。如果待处理的预填充请求无法放入max_num_batched_tokens,则会自动将其分块处理。

该政策有两个好处:

  • 由于解码请求被优先处理,它提升了ITL和生成解码的性能。
  • 它通过将计算密集型(预填充)和内存密集型(解码)请求定位到同一批次,有助于实现更好的GPU利用率。

使用分块预填充进行性能调优

您可以通过调整max_num_batched_tokens来优化性能:

  • 较小的值(例如2048)可以实现更好的令牌间延迟(ITL),因为较少的预填充会降低解码速度。
  • 数值越高,首令牌时间(TTFT)表现越好,因为可以批量处理更多预填充令牌。
  • 为了获得最佳吞吐量,我们建议将max_num_batched_tokens > 8096,特别是对于大型GPU上的较小模型。
  • 如果max_num_batched_tokensmax_model_len相同,那几乎等同于V0版本的默认调度策略(唯一的区别是它仍然会优先处理解码请求)。
from vllm import LLM

# Set max_num_batched_tokens to tune performance
llm = LLM(model="meta-llama/Llama-3.1-8B-Instruct", max_num_batched_tokens=16384)

更多详情请参阅相关论文 (https://arxiv.org/pdf/2401.08671https://arxiv.org/pdf/2308.16369).

并行策略

vLLM支持多种并行策略,可以组合使用以优化不同硬件配置下的性能。

张量并行 (TP)

张量并行将模型参数在每个模型层的多个GPU之间进行分片。这是单节点内大模型推理最常用的策略。

使用场景:

  • 当模型过大无法适配单个GPU时
  • 当您需要降低每个GPU的内存压力,以便为更高的吞吐量预留更多KV缓存空间时
from vllm import LLM

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

对于过大而无法适配单个GPU的模型(如700亿参数模型),张量并行技术至关重要。

流水线并行 (PP)

流水线并行将模型层分布到多个GPU上。每个GPU按顺序处理模型的不同部分。

使用场景:

  • 当你已经充分利用了高效的张量并行但仍需要进一步跨节点分发模型时
  • 对于层分布比张量分片更高效的极深且窄的模型

对于超大规模模型,流水线并行可以与张量并行结合使用:

from vllm import LLM

# Combine pipeline and tensor parallelism
llm = LLM(
    model="meta-llama/Llama-3.3-70B-Instruct,
    tensor_parallel_size=4,
    pipeline_parallel_size=2
)

专家并行 (EP)

专家并行是针对混合专家(MoE)模型的一种特殊并行形式,其中不同的专家网络分布在多个GPU上。

使用场景:

  • 特别针对MoE模型(如DeepSeekV3、Qwen3MoE、Llama-4)
  • 当您需要在多个GPU之间平衡专家计算负载时

通过设置enable_expert_parallel=True可启用专家并行,该设置将使MoE层使用专家并行而非张量并行。它将使用与张量并行相同的并行度。

数据并行(DP)

数据并行将整个模型复制到多个GPU组上,并行处理不同批次的请求。

使用场景:

  • 当您拥有足够的GPU来复制整个模型时
  • 当您需要扩展吞吐量而非模型规模时
  • 在需要隔离请求批次的多用户环境中

数据并行可以与其他并行策略结合使用,通过data_parallel_size=N进行设置。 请注意,MoE层将根据张量并行大小和数据并行大小的乘积进行分片。

降低内存使用量

If you encounter out-of-memory issues, consider these strategies:

上下文长度与批量大小

您可以通过限制上下文长度和批次大小来减少内存使用:

from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    max_model_len=2048,  # Limit context window
    max_num_seqs=4       # Limit batch size
)

调整CUDA图编译

V1版本中的CUDA图编译比V0版本占用更多内存。您可以通过调整编译级别来减少内存使用:

from vllm import LLM
from vllm.config import CompilationConfig, CompilationLevel

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    compilation_config=CompilationConfig(
        level=CompilationLevel.PIECEWISE,
        cudagraph_capture_sizes=[1, 2, 4, 8]  # Capture fewer batch sizes
    )
)

或者,如果您不关心延迟或整体性能,可以通过设置enforce_eager=True完全禁用CUDA图编译:

from vllm import LLM

llm = LLM(
    model="meta-llama/Llama-3.1-8B-Instruct",
    enforce_eager=True  # Disable CUDA graph compilation
)

多模态模型

对于多模态模型,您可以通过限制每个请求中的图像/视频数量来降低内存使用:

from vllm import LLM

# Accept up to 2 images per prompt
llm = LLM(
    model="Qwen/Qwen2.5-VL-3B-Instruct",
    limit_mm_per_prompt={"image": 2}
)