跳到內容

分離式預填充(實驗性)

本頁面將介紹 vLLM 中的分離式預填充功能。

注意

此功能為實驗性功能,可能會有所更改。

為何使用分離式預填充?

兩個主要原因

  • 獨立調整首詞時間 (TTFT) 和詞間延遲 (ITL)。分離式預填充將 LLM 推理的預填充階段和解碼階段置於不同的 vLLM 例項中。這使您能夠靈活地為不同的並行策略(例如 tppp)分配,以在不影響 ITL 的情況下調整 TTFT,或在不影響 TTFT 的情況下調整 ITL。
  • 控制尾部 ITL。在沒有分離式預填充的情況下,vLLM 可能會在請求解碼期間插入一些預填充任務。這會導致更高的尾部延遲。分離式預填充有助於您解決此問題並控制尾部 ITL。使用適當分塊大小的分塊預填充也可以實現相同的目標,但在實踐中很難確定正確的塊大小值。因此,分離式預填充是控制尾部 ITL 的更可靠方法。

注意

分離式預填充並不能提高吞吐量。

使用示例

請參考 examples/online_serving/disaggregated_prefill.sh 以獲取分離式預填充的使用示例。

效能基準

請參考 benchmarks/disagg_benchmarks 以獲取分離式預填充的效能基準。

開發

我們透過執行 2 個 vLLM 例項來實現分離式預填充。一個用於預填充(我們稱之為預填充例項),另一個用於解碼(我們稱之為解碼例項),然後使用聯結器將預填充的 KV 快取和結果從預填充例項傳輸到解碼例項。

所有分離式預填充的實現都在 vllm/distributed/kv_transfer 目錄下。

分離式預填充的關鍵抽象

  • 聯結器:聯結器允許 KV 消費者KV 生產者 檢索一批請求的 KV 快取。
  • 查詢緩衝區:查詢緩衝區提供兩個 API:insert KV 快取和 drop_select KV 快取。insertdrop_select 的語義類似於 SQL,其中 insert 將 KV 快取插入到緩衝區中,drop_select 則返回與給定條件匹配的 KV 快取並將其從緩衝區中刪除。
  • 管道:一個用於張量傳輸的單向 FIFO 管道。它支援 send_tensorrecv_tensor

注意

insert 是非阻塞操作,而 drop_select 是阻塞操作。

下圖展示了上述 3 種抽象的組織方式

Disaggregated prefilling abstractions

分離式預填充的工作流程如下

Disaggregated prefilling workflow

buffer 對應於 LookupBuffer 中的 insert API,而 drop_select 對應於 LookupBuffer 中的 drop_select API。

第三方貢獻

分離式預填充與基礎設施高度相關,因此 vLLM 依賴第三方聯結器來實現生產級別的分離式預填充(vLLM 團隊將積極審查併合並用於第三方聯結器的新 PR)。

我們推薦以下三種實現方式

  • 完全定製的聯結器:實現您自己的 Connector,並呼叫第三方庫來發送和接收 KV 快取,以及更多功能(例如修改 vLLM 的模型輸入以執行定製的預填充等)。這種方法提供了最大的控制權,但存在與未來 vLLM 版本不相容的風險。
  • 資料庫式聯結器:實現您自己的 LookupBuffer,並像 SQL 一樣支援 insertdrop_select API。
  • 分散式 P2P 聯結器:實現您自己的 Pipe,並像 torch.distributed 一樣支援 send_tensorrecv_tensor API。