最佳化與調優

最佳化與調優#

搶佔#

由於 Transformer 架構的自迴歸特性,有時 KV 快取空間不足以處理所有批處理請求。 vLLM 可以搶佔請求,以釋放 KV 快取空間供其他請求使用。 當 KV 快取空間再次可用時,被搶佔的請求將被重新計算。 發生這種情況時,將列印以下警告

WARNING 05-09 00:49:33 scheduler.py:1057 Sequence group 0 is preempted by PreemptionMode.SWAP 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

雖然此機制確保了系統的魯棒性,但搶佔和重新計算可能會對端到端延遲產生不利影響。 如果您經常遇到來自 vLLM 引擎的搶佔,請考慮以下操作

  • 增加 gpu_memory_utilization。 vLLM 透過使用 gpu_memory_utilization% 的記憶體來預分配 GPU 快取。 透過增加此利用率,您可以提供更多的 KV 快取空間。

  • 減少 max_num_seqsmax_num_batched_tokens。 這可以減少批處理中併發請求的數量,從而減少所需的 KV 快取空間。

  • 增加 tensor_parallel_size。 這種方法對模型權重進行分片,因此每個 GPU 都有更多記憶體可用於 KV 快取。

  • 增加 pipeline_parallel_size。 這種方法跨 GPU 分佈模型層,減少了每個 GPU 上模型權重所需的記憶體,從而間接留出更多記憶體用於 KV 快取。

您還可以透過 vLLM 公開的 Prometheus 指標來監控搶佔請求的數量。 此外,您可以透過設定 disable_log_stats=False 來記錄搶佔請求的累積數量。

分塊預填充#

vLLM 支援一項實驗性功能:分塊預填充。 分塊預填充允許將大型預填充分塊為更小的塊,並將它們與解碼請求批次處理在一起。

您可以透過在命令列中指定 --enable-chunked-prefill 或在 LLM 建構函式中設定 enable_chunked_prefill=True 來啟用此功能。

from vllm import LLM

llm = LLM(model="meta-llama/Llama-2-7b-hf", enable_chunked_prefill=True)
# Set max_num_batched_tokens to tune performance.
# NOTE: 2048 is the default max_num_batched_tokens for chunked prefill.
# llm = LLM(model="meta-llama/Llama-2-7b-hf", enable_chunked_prefill=True, max_num_batched_tokens=2048)

預設情況下,vLLM 排程器優先處理預填充,並且不會將預填充和解碼批處理到同一批次中。 此策略優化了 TTFT(首個令牌的時間),但會導致 ITL(令牌間延遲)較慢和 GPU 利用率低下。

啟用分塊預填充後,策略將更改為優先處理解碼請求。 它會將所有待處理的解碼請求批處理到批次中,然後再排程任何預填充。 當有可用的 token_budget (max_num_batched_tokens) 時,它會排程待處理的預填充。 如果最後一個待處理的預填充請求無法容納到 max_num_batched_tokens 中,它會對其進行分塊。

此策略有兩個好處

  • 它提高了 ITL 和生成解碼,因為解碼請求被優先處理。

  • 它透過將計算密集型(預填充)和記憶體密集型(解碼)請求定位到同一批次,幫助實現更好的 GPU 利用率。

您可以透過更改 max_num_batched_tokens 來調整效能。 預設情況下,它設定為 2048。 較小的 max_num_batched_tokens 可以實現更好的 ITL,因為打斷解碼的預填充較少。 較高的 max_num_batched_tokens 可以實現更好的 TTFT,因為您可以將更多的預填充放入批次中。

  • 如果 max_num_batched_tokensmax_model_len 相同,則幾乎等同於預設的排程策略(除了它仍然優先處理解碼)。

  • 請注意,max_num_batched_tokens 的預設值 (2048) 針對 ITL 進行了最佳化,並且它的吞吐量可能低於預設排程器。

我們建議您將 max_num_batched_tokens > 2048 設定為吞吐量。

有關更多詳細資訊,請參閱相關論文 (https://arxiv.org/pdf/2401.08671https://arxiv.org/pdf/2308.16369)。

請試用此功能,並透過 GitHub issue 告知我們您的反饋!