分離式預填充(實驗性)¶
本頁面將介紹 vLLM 中的分離式預填充功能。
注意
此功能為實驗性功能,可能會有所更改。
為何使用分離式預填充?¶
兩個主要原因
- 獨立調整首詞時間 (TTFT) 和詞間延遲 (ITL)。分離式預填充將 LLM 推理的預填充階段和解碼階段置於不同的 vLLM 例項中。這使您能夠靈活地為不同的並行策略(例如
tp
和pp
)分配,以在不影響 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 快取。insert
和drop_select
的語義類似於 SQL,其中insert
將 KV 快取插入到緩衝區中,drop_select
則返回與給定條件匹配的 KV 快取並將其從緩衝區中刪除。 - 管道:一個用於張量傳輸的單向 FIFO 管道。它支援
send_tensor
和recv_tensor
。
注意
insert
是非阻塞操作,而 drop_select
是阻塞操作。
下圖展示了上述 3 種抽象的組織方式
分離式預填充的工作流程如下
buffer
對應於 LookupBuffer 中的 insert
API,而 drop_select
對應於 LookupBuffer 中的 drop_select
API。
第三方貢獻¶
分離式預填充與基礎設施高度相關,因此 vLLM 依賴第三方聯結器來實現生產級別的分離式預填充(vLLM 團隊將積極審查併合並用於第三方聯結器的新 PR)。
我們推薦以下三種實現方式
- 完全定製的聯結器:實現您自己的
Connector
,並呼叫第三方庫來發送和接收 KV 快取,以及更多功能(例如修改 vLLM 的模型輸入以執行定製的預填充等)。這種方法提供了最大的控制權,但存在與未來 vLLM 版本不相容的風險。 - 資料庫式聯結器:實現您自己的
LookupBuffer
,並像 SQL 一樣支援insert
和drop_select
API。 - 分散式 P2P 聯結器:實現您自己的
Pipe
,並像torch.distributed
一樣支援send_tensor
和recv_tensor
API。