vLLM プッシュベース NIXL KV コネクタ: 分離推論における TTFT が最大 3 倍向上

vLLM は、プリフィル・デコード(P-D)分離推論向けにプッシュベースの NIXL KV コネクタを追加しました。これにより、転送の調整とセットアップがファーストトークンまでのクリティカルパスから外れます。AWS EFA で接続された Amazon EC2 P5en インスタンスを使用した 1P1D デプロイメントでの Qwen3-32B ベンチマークでは、プッシュモードはデフォルトのプルモードと比較して、タイム・トゥ・ファーストトークン(TTFT)が最大 3 倍、タイム・パー・アウトプットトークン(TPOT)が最大 30% 向上しました。

プッシュコネクタが解決する問題

プリフィル・デコード分離は、プリフィルとデコードを別々のエンジンインスタンスで実行するため、各フェーズを独立してスケールおよび最適化でき、リソース利用率、スループット、負荷時のレイテンシが向上します。その代償として、KV キャッシュはトークン生成が開始される前にプリフィルインスタンスからデコードインスタンスに転送する必要があり、KV 転送が TTFT のクリティカルパスに直接乗ることになります。

vLLM は、NVIDIA Inference Xfer Library(NIXL)コネクタを介してこの転送を実行します。NIXL は、AWS Elastic Fabric Adapter(EFA)などの RDMA 対応インターコネクトを介して KV ブロックを移動します。サポートされているインスタンスタイプでは、EFA は GPUDirect RDMA と Neuron Direct RDMA をサポートしているため、NIXL は KV ブロックを GPU または Trainium デバイスメモリ間で直接転送でき、ホストメモリを経由する必要はありません。

デフォルトの NIXL コネクタモードはプルベースです。プリフィルインスタンスがプロンプト KV キャッシュの計算を完了すると、ルーターはプリフィルブロック ID を含むソースメタデータをデコードインスタンスに中継します。次にデコードインスタンスは宛先ブロックを割り当て、NIXL 転送を準備し、NIXL READ を開始してプリフィルインスタンスから KV ブロックをプルします。これらの調整とセットアップ手順はプリフィル後、デコード前に順次実行されるため、TTFT のクリティカルパスが延長されます。

プッシュベース KV 転送の仕組み

プッシュベース転送が TTFT とデコードスループットを改善する理由は、vLLM の投稿によると次の 2 つです。

  1. プルモデルの直列化を排除し、プロデューサーとコンシューマーの処理をオーバーラップさせます。デコードインスタンスはプロデューサーが KV を計算している間にターゲットブロックを事前に登録します。転送はプロデューサーのブロックが準備でき次第開始され、コンシューマー側の識別子探索ラウンドトリップを待つ必要がないため、そのラウンドトリップがファーストトークンまでの経路から排除されます。
  2. 転送セットアップ時間をデコードインスタンスから外します。 NIXL ディスクリプタの準備と転送の送信はプリフィル側とバックグラウンドスレッドで実行されるため、デコードインスタンスはレイテンシクリティカルなトークン生成フェーズでそのサイクルを消費しません。

正味の効果は、デコードインスタンスでの TTFT の低下と出力トークンスループットの向上です。

プッシュコネクタは、ターゲットブロックを事前に登録するデコードインスタンス、各リクエストを照合して転送を発行するプリフィルインスタンス、KV 書き込みをエンジンのフォワードパスループから切り離す専用のバックグラウンドスレッドの 3 つのアクターを調整します。

3 ステップのプロトコル

1. 登録(デコード側)。 デコードインスタンスがリモートプリフィルを必要とするリクエスト用にローカルブロックを割り当てると、プリフィルインスタンスが KV を書き込む場所を示す登録を準備します。つまり、自身の ID と予約したばかりのブロック位置です。同じエンジンステップ内で、ワーカーはこの登録を NIXL 通知としてプリフィルインスタンスに送信します。登録は割り当て時に行われるため、プリフィルインスタンスがプリフィルを完了する前にコネクタは宛先ブロックを認識します。

2. ランデブー(プリフィル側)。 デコーダーからの登録とプロデューサー側のプリフィル完了はどちらが先に到着してもかまいません。コネクタは両方の順序を処理します。登録が先に到着した場合、プロデューサーは自身のプリフィルが完了するまでそれを保持します。プリフィルが先に完了した場合、プロデューサーは登録が到着するまでリクエストのブロックを保持します。2 番目に発生したイベントが転送をトリガーします。コネクタは識別子でリクエストをペアリングし、照合は再発行されたリクエストも考慮し、プリエンプトまたは再試行されたリクエストを正しく関連付けます。

3. 転送(プリフィル側)。 リクエストが照合されると、プロデューサーはデコードインスタンスへの接続を確立し(既存の接続がない場合)、NIXL WRITE を発行して KV ブロックをデコーダーの登録済みメモリに直接コピーし、各宛先テンソル並列ランクにアドレス指定します。プロデューサーとコンシューマーは異なる内部ブロックレイアウトを使用できます。各側は転送時にブロック位置を自身の物理レイアウトにマッピングするため、各側で異なるブロックサイズが可能です。各 WRITE には完了通知が含まれており、データが到着すると NIXL がデコードインスタンスに配信します。デコーダーはこれらの通知を、自身に書き込むプロデューサーランクごとに 1 つずつカウントし、期待されるすべての通知が到着した場合にのみ KV を受信したと見なします。その後、リクエストはデコードに進みます。

スレッドモデル

プッシュコネクタは、各プリフィルワーカーに専用のバックグラウンド転送スレッドを使用して、モデル実行と KV 転送準備を分離します。リクエストの開始時に、デコードのメインループは宛先 KV ブロックを割り当ててプリフィルインスタンスに登録し、プリフィルメインループはプロンプト KV キャッシュを計算します。宛先登録とプロンプト KV の両方が準備できた後、プリフィルメインループは KV ブロックをバックグラウンドスレッドに渡し、すぐにモデル実行に戻ります。

バックグラウンドスレッドは NIXL 接続を確立または再利用し、リクエストの KV ブロック ID をメモリディスクリプタにマッピングし、連続するブロックをより大きな転送領域にマージし、NIXL WRITE をデコードインスタンスに送信します。NIXL が転送を完了すると、完了通知をデコードインスタンスに送信し、デコードインスタンスはトークン生成を開始します。ディスクリプタの準備と転送の送信をレイテンシクリティカルなメインループから外すことで、このリクエストごとの処理がモデル実行を遅延させるのを防ぎます。

プル vs プッシュ: ルーティングのトレードオフ

両モードは同じ NIXL と EFA/RDMA データパスを使用します。プルはプリフィル後にメタデータ中継とデコード側セットアップを実行しますが、プッシュはデコード側セットアップをプリフィルとオーバーラップさせ、これらの操作をプリフィル後のクリティカルパスから除外するため、デコードをより早く開始できます。

また、2 つのモードにはルーティングのトレードオフもあります。プルモードではルーターはプリフィル完了後にデコードインスタンスを選択できるため、負荷対応ルーティングと QoS 管理の柔軟性が高まります。プッシュモードはデコードインスタンスを早期に選択するため、宛先セットアップをプリフィルとオーバーラップさせることができます。その代わり、同等の負荷では、プロンプト KV と宛先登録の両方が準備でき次第転送が開始されるため、プリフィルインスタンスは KV ブロックをより早く解放できます。

パフォーマンスデータ

評価では、EFA で接続された Amazon EC2 P5en インスタンスを使用した 1P1D デプロイメントで Qwen3-32B モデルを使用しました。P→D 転送パフォーマンスを分離するために、ベンチマークはプレフィックスキャッシュを --no-enable-prefix-caching で無効化し、デコードノードがすべてのリクエストでプリフィルノードから完全な KV キャッシュを取得するようにしました。この設定がないと、重複するプロンプトがデコードノードのローカルキャッシュを再利用して転送をバイパスし、誤解を招く比較結果になる可能性があります。

TTFT。 ベンチマークは入力長 1k〜16k、リクエストレート 1〜8 QPS をスイープしました。低負荷で短いプロンプトでは、2 つのモードはほぼ同じパフォーマンスを示します。QPS と入力長が増加するにつれて、プルモードは急激に劣化し、8 QPS・16k 入力で約 1,744 ms に達します。プッシュモードは約 540 ms と大幅に低く、約 3 倍の削減です。この差は、プルモードが NIXL ディスクリプタをデコードワーカー上でインラインに、エンジンループ内で同期的にポストするため、その処理がトークン生成を停滞させるのに対し、プッシュモードはそれをバックグラウンドスレッドに移動してクリティカルパスから外すために生じます。

TPOT。 同じ条件下で、パターンは TTFT を反映しています。軽負荷では、プッシュとプルは約 5.6〜5.8 ms でほぼ同等です。負荷と入力長が増加すると、プルは 4〜8 QPS・16k 入力で約 10.4 ms に上昇しますが、プッシュは約 7 ms を維持します。プッシュはディスクリプタ準備と転送送信をデコードワーカーからオフロードするため、トークン生成が不足することはなく、高並行性や長いコンテキストでもトークンあたりのレイテンシは安定しています。

プッシュモードの有効化方法

プッシュモードを使用するには、プリフィルサーバーとデコードサーバーの両方を NixlConnector の代わりに NixlPushConnector を使用するように構成します。vLLM の投稿によると、この機能は AWS Trainium インスタンスクラスターで EFA に接続して構築および検証され、その後アクセラレータ非依存の機能として vLLM に貢献されました。公開された結果は EFA を備えた AWS p5en(GPU)クラスターからのもので、GPU でも利点が発揮されることを示しています。

プッシュとプルの選択基準

早期のデコードノード選択が許容でき、TTFT の低下を優先する場合は、プッシュベースコネクタを選択してください。プルベースコネクタは、双方向 KV 転送が必要なワークロードや、負荷対応ルーティングのためにプリフィル後までデコードインスタンスの選択を延期するワークロードに適しています。vLLM はプッシュベースとプルベースの両方の KV コネクタをサポートしており、ユーザーはデプロイメントに最適なアプローチを選択できます。

ベンチマークの再現

参照トポロジは、EFA が有効な 2 つの p5en GPU ノード(プリフィルは :8100、デコードは :8200)と、プロキシとベンチマーククライアントを実行する 3 つ目の小型ノードで構成されます。両 GPU ノードは p5en.48xlarge(8x NVIDIA H200)、Ubuntu 24.04.4 LTS(カーネル 6.14.0-1018-aws)、NVIDIA ドライバ 580.126.16(CUDA 13.0 ドライバ API)、CUDA ツールキット 13.0、EFA インストーラ 1.50.0(EFA カーネルモジュール 3.3.0g、libfabric 2.6.0amzn1.0、rdma-core 64.0amzn0)を使用しました。各インスタンスは 200 Gb/s の EFA インターフェイスを 16 個公開し、合計 3.2 Tb/s です。

再現ガイドのソフトウェアバージョンは vllm==0.29.0 と nixl==1.4.1 です。モードの違いは単一の構成フィールドです。プルには NixlConnector、プッシュには NixlPushConnector を使用します。デコードサーバーには --no-enable-prefix-caching を追加して、プリフィルから完全な KV フェッチを強制します。ベンチマークスクリプトは vLLM プルリクエスト #57567 にあり、投稿には起動、スイープ、ティアダウン、図の再描画用に serve_pd.sh、run_sweep.sh、cleanup.sh、plot_push_vs_pull.py が含まれています。

EFA デバイス選択について、LIBFABRIC バックエンドは efa プロバイダで 16 個すべての EFA デバイスをレールとして開き、各 GPU の KV キャッシュをその GPU の PCIe スイッチを共有する 2 つのレールにのみ登録するため、すべての転送は PCIe ローカルに保たれます。NIXL または libfabric のデバイスオーバーライドは設定されておらず、これがデフォルトの選択です。

今後の作業

vLLM は、バックグラウンド NIXL スレッドモデルをプルモードコネクタにも導入し、NIXL セットアップをクリティカルパスから外してプルモードワークロードも同じ最適化の恩恵を受けられるようにすることを検討しています。これを調査するためのプルリクエスト(#45211)が開かれています。

Sources