最佳化與調優¶
本指南涵蓋了 vLLM V1 的最佳化策略和效能調優。
搶佔¶
由於 Transformer 架構的自迴歸特性,有時 KV 快取空間不足以處理所有批處理請求。在這種情況下,vLLM 可以搶佔請求以釋放 KV 快取空間供其他請求使用。被搶佔的請求在有足夠的 KV 快取空間時會重新計算。當這種情況發生時,您可能會看到以下警告:
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 快取。透過提高利用率,您可以提供更多的 KV 快取空間。 - 減少
max_num_seqs
或max_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 不同,V0 中是根據模型特性有條件地啟用。
啟用分塊預填充後,排程策略會優先處理解碼請求。它會在排程任何預填充操作之前,批處理所有待處理的解碼請求。當 max_num_batched_tokens
預算中有可用 token 時,它會排程待處理的預填充。如果待處理的預填充請求無法適應 max_num_batched_tokens
,它會自動將其分塊。
此策略有兩個優點:
- 由於解碼請求被優先處理,它改善了 ITL(內部 Token 延遲)和生成解碼。
- 它透過將計算密集型(預填充)和記憶體密集型(解碼)請求放在同一個批次中,有助於實現更好的 GPU 利用率。
使用分塊預填充進行效能調優¶
您可以透過調整 max_num_batched_tokens
來調整效能:
- 較小的值(例如 2048)可以實現更好的內部 Token 延遲(ITL),因為預填充較少,不會減慢解碼速度。
- 較大的值可以實現更好的首個 Token 生成時間(TTFT),因為您可以在一個批次中處理更多的預填充 token。
- 為了獲得最佳吞吐量,我們建議將
max_num_batched_tokens > 8096
,特別是對於大型 GPU 上的小型模型。 - 如果
max_num_batched_tokens
與max_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.08671 或 https://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 的模型(如 70B 引數模型),張量並行是必不可少的。
流水線並行 (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 層將根據張量並行大小和資料並行大小的乘積進行分片。
減少記憶體使用¶
如果您遇到記憶體不足問題,請考慮以下策略:
上下文長度和批處理大小¶
您可以透過限制上下文長度和批處理大小來減少記憶體使用。
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 Graph 編譯¶
V1 中的 CUDA graph 編譯比 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 graph 編譯。
from vllm import LLM
llm = LLM(
model="meta-llama/Llama-3.1-8B-Instruct",
enforce_eager=True # Disable CUDA graph compilation
)
多模態模型¶
對於多模態模型,您可以透過限制每個請求的影像/影片數量來減少記憶體使用。