跳至内容

优化与调优

本指南涵盖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}
)
优云智算