跳到內容

上下文並行部署

上下文並行主要解決長上下文請求的服務問題。由於 prefill 和 decode 具有截然不同的特性和非常不同的 SLO(服務水平目標),我們需要為它們分別實現上下文並行。主要考慮因素是:

  • 對於長上下文 prefill,我們需要透過分攤 prefill 計算時間到查詢(query)tokens 來控制 TTFT(首次 token 的時間)。
  • 對於長上下文 decode,我們需要更多的 KV 快取空間來增加 batchsize(從而提高吞吐量)。

Prefill 上下文並行

在 prefill 過程中,對於一個包含 T 個新 token 的長請求,我們需要計算這些新 token 的查詢/鍵/值(query/key/value)張量。假設我們有 N 個 GPU,我們可以將請求分割成 N 塊,每個 GPU 計算其負責的查詢/鍵/值張量的其中一塊。

根據用例的不同,有兩種可能的策略:

  1. 部分查詢,完整鍵/值:如果請求 token 長度適中(我們可以負擔儲存完整的鍵/值張量),目標是加速 prefill(並分攤 prefill 計算時間到查詢 tokens),那麼我們可以從所有 GPU 收集鍵/值張量,讓每個 GPU 計算對應於其分塊的查詢 tokens 的注意力輸出。
  2. 部分查詢,部分鍵/值:如果請求 token 長度太長,我們無法負擔儲存完整的鍵/值張量,那麼我們只能為每個 GPU 計算查詢/鍵/值張量的一個分塊,並使用 ring-attention 等技術逐塊傳送/接收(send/recv)鍵/值張量。

這兩種方法都在積極開發中。

Decode 上下文並行

由於解碼的自迴歸性質,每個解碼步驟都需要計算少量查詢 token 相對於分頁 KV 快取中大量鍵/值 token 的結果。 Decode 上下文並行的核心是如何在 GPU 之間分片(shard)KV 快取。

對於一個具有 H 個 kv-head 的模型,一個上下文長度為 T 的請求需要在 KV 快取中儲存 H * T 個鍵/值張量。

  1. 如果一個 GPU 可以容納所有這些,並且效能足夠好,那麼就不需要並行化。
  2. 如果一個 GPU 無法容納所有這些,或者我們希望在 KV 快取中容納更多請求,我們可以首先沿著 H 維度對 KV 快取進行分片,這就是普通的張量並行分片。這很簡單,只需在命令列中新增 -tp <num_gpus>
  3. 由於 H 是有限的(由模型架構決定),當我們繼續增加張量並行大小(tensor parallel size)時,每個 GPU 的 KV 快取會重複 tp_size / H 次。當然,重複不利於效率。然後我們需要新增 decode 上下文並行,沿著 T 維度進一步分片 KV 快取。這很簡單,只需在命令列中新增 -dcp <size>。請注意,size 不會增加我們需要的 GPU 數量,而只是減少 KV 快取的重複。 dcp 大小應在 [1, tp_size/H] 的範圍內。 dcp 越大,KV 快取的重複次數越少,但通訊開銷會增加。

理論上,可以將 dcp 大小擴充套件到 tp_size / H 以上,以進一步分片 KV 快取並加速解碼階段。然而,由於解碼過程中查詢 token 的數量有限,對於剩餘的 dcp_size - tp_size / H 個 GPU 的非注意力層該怎麼處理尚不清楚。為了簡單起見,dcp 大小上限為 tp_size / H。如果您想進一步加速解碼階段,可以考慮先增加 tp_size,然後再增加 dcp 大小。

請注意,KV 快取會在解碼過程中增長,分片策略需要仔細實現。我們採用交錯策略(interleaving strategy)沿 T 維度分片 KV 快取,這樣未來 token 的 KV 快取就可以自然地沿 T 維度分片。這由 Moonshot 的 Chao Hong 提出,並在 這篇論文 中得到了詳細解釋。

案例研究

對於 DeepSeek-R1,當啟用 MLA 時,我們有 1 個 kv-head。典型的單節點部署 -tp 8 會導致 8 倍的 KV 快取重複。我們可以考慮新增 -dcp 8 來減少 KV 快取的重複。

對於 Kimi-K2,其架構與 DeepSeek-R1 類似,但引數更多。當以 -tp 16 部署時,KV 快取重複為 16 倍。我們可以新增 -dcp 16 來完全消除 KV 快取的重複,但這會增加通訊開銷。我們也可以新增 -dcp 8 來將 KV 快取的重複減少到 2 倍。雖然仍然會複製兩次 KV 快取,但通訊開銷較小,因為 DCP 通訊僅發生在節點內部。

對於 Qwen3-235B-A22B,我們有 4 個 kv-head。當以 -tp 8 部署時,KV 快取重複為 2 倍。然後我們可以新增 -dcp 2 來消除 KV 快取的重複。

總之,對於 decode 上下文並行,嘗試增加 -tp 大小直到獲得滿意的效能,然後新增 -dcp 來減少 KV 快取的重複。

vLLM 支援 decode 上下文並行,支援 MLA 和 GQA 模型。一些注意力後端也支援 decode 上下文並行與 MTP(多 token 預測)的組合,以進一步加速解碼階段。

技術討論

主要討論發生在 vLLM Slack#sig-context-parallel 頻道。