vLLM v0.32.0 GLM-5.3 サービング: 16基のH200上でのPCP、DCP、およびハイブリッドHiSparse

16基のH200上で長いエージェントコンテキストを持つGLM-5.3をサービスするには、標準のテンソル並列処理とデータ並列処理では提供できない2つのメカニズムが必要です。プレフィルコンテキスト並列処理(PCP)は各プロンプトをトークン単位でGPU間で分割し、デコードコンテキスト並列処理(DCP)はKVキャッシュをシャーディングして100万トークンのコンテキストが収まるようにします。ハイブリッドHiSparseデコードと組み合わせることで、このvLLMデプロイメント(vLLM v0.32.0以降)は、AgentXベンチマークで同じスループットでデータ並列デプロイメントの1.7〜3.2倍のユーザーあたりのインタラクティブ性を実現し、著者がテストした構成の中で100万トークンのリクエストを処理できる唯一の構成です。

これはvLLMのGLM-5.3最適化シリーズのパート2です。パート1では、単一の8x H200ノードでの集約デプロイメントにおけるハイブリッドHiSparseを扱いました。パート2では、2つの8x H200ノードにわたるプレフィル/デコード分離を扱います。

発表内容

vLLMは、16基のH200を1つのプレフィルノードと1つのデコードノードに分割してGLM-5.3の長コンテキストエージェントワークロードをサービスする方法を説明する技術文書を公開しました。この記事では3つの構成要素を紹介し、それらがどのように組み合わさるかを示しています。

  • プレフィルコンテキスト並列処理(PCP) は、各プロンプトをアテンションヘッドではなくトークン単位でGPU間で分割します。これはGLM-5.3のスパースアテンションにテンソル並列処理よりも適しています。
  • デコードコンテキスト並列処理(DCP) は、プレフィルエンジンのKVキャッシュをトークン単位でシャーディングするため、100万トークンのコンテキストがプレフィルノードに収まります。
  • ハイブリッドHiSparse により、デコードエンジンはKVをホストメモリに保持できるため、100万トークンのリクエストがデコード側に収まります。

SemiAnalysis AgentXベンチマークでは、PCP8とDCP8のプレフィルとハイブリッドHiSparseデコードの組み合わせにより、同じスループットでデータ並列(DP8)デプロイメントの1.7〜3.2倍のユーザーあたりの速度を実現し、最初のトークンまでの時間(TTFT)の中央値を1.5〜5.2秒から0.8〜0.9秒に短縮しました。

長いエージェントコンテキストがH200上の標準並列処理を壊す理由

エージェントワークロードは、ターンごとに成長する長いコンテキストを持ち、GPUメモリとプレフィルスループットの両方に圧力をかけます。H200では、GLM-5.3の重みが各GPUのメモリの大部分を消費するため、長いコンテキストのKVキャッシュ用のスペースがほとんど残りません。毎ターン、ツール出力とファイル内容がプレフィルに追加されるため、負荷がかかるとプレフィルエンジンがデプロイメント全体のボトルネックになる可能性があります。プレフィル/デコード分離だけではこれを解決できません。

DP8とTP8が不十分な理由

8x H200ノードでGLM-5.3プレフィルを実行する標準的な2つの方法は、データ並列(DP8)とテンソル並列(TP8)ですが、両方とも異なる理由で失敗します。

  • DP8 は各プロンプトを単一のGPUに割り当てるため、そのアテンションは他の7つを使用できません。これにより、長いプロンプトの最初のトークンまでの時間が制限され、プロンプトのKVキャッシュがその1つのGPUのメモリに収まる必要があります。
  • TP8 はアテンションヘッドをGPU間で分割します。MLAの潜在KVは64個すべてのヘッドで共有されるため、各GPUは完全なキャッシュを保存しますが、8個のヘッドにサービスするためだけにそれを読み取ります。スパースMLAがアテンションする2,048トークンを選択するために以前のすべてのトークンをスコアリングするインデクサーはまったく分割されないため、その2次コストが各GPUで繰り返されます。

どちらの方式も、1つの長いプロンプトのアテンション作業を8つのGPUに分散させながら、それをサービスする各GPUにKVキャッシュ全体を保持することはありません。PCPはクエリ側に対処し、DCPはKV側に対処します。

PCP: ヘッドではなくトークンを分割

プレフィルコンテキスト並列処理は、各プロンプトを8つのGPUにトークン単位で分割します。各GPUは、64個すべてのヘッドを使用して、プロンプトの8分の1のクエリを計算します。因果アテンションではトークンがその前のすべてのトークンにアテンションするため、プロンプトの終わりを保持するGPUは始めを保持するGPUよりもはるかに多くの作業を行うため、単純な分割は不均衡になります。PCPは代わりにプロンプトを16のチャンクに分割してペアにするため、GPU gは前からチャンクgと後ろからチャンク15 - gを受け取り、各GPUに同じ割合の安価なトークンと高価なトークンを与えます。これは論文「Context Parallelism for Scalable Million-Token Inference」(arXiv 2411.01783)の負荷分散シャーディングです。各GPUの新しいKVはその後オールギャザーされ、すべてのクエリが完全なコンテキストにアテンションできるようにします。

演算強度への効果が注目すべき数字です。PCPでは各GPUは自分のトークンのみをインデックスするため、各GPUはインデクサー作業の8分の1を行い、すべてを複製するわけではありません。また、メモリから読み取られる各KV行は8ヘッドではなく64ヘッドすべてにサービスするため、スパースMLAは移動バイトあたり約26から約191 FLOPsに向上します。H200のBF16リッジポイントは206 FLOPs/バイトであるため、PCPはスパースMLAを計算バウンドに近づけます。

インデクサーを複製しないことは、長いプレフィルで最も重要です。インデクサーのコストはプロンプト長の2乗で増加しますが、スパースMLAは各クエリが固定の2,048トークンにアテンションするため線形にしか増加しません。スクラッチからのプレフィルのFLOPsを数えると、TP8ではプロンプトが約32Kトークンに達するとインデクサーがスパースMLAを追い越します。PCP8では、どのGPUもそれを複製しないため、クロスオーバーは約256Kトークンに移動します。

PCPには残りの2つのコストがあります。各GPUはすべてのアテンション重みを保持する必要がありますが、MoEエキスパートはEP8で8つのGPUに分割されたままです。また、新しいKVは毎層オールギャザーされるため、各GPUは結局完全なKVキャッシュを保存することになります。コンテキスト長を制限するのは、計算ではなく、この複製されたキャッシュです。そして、それを取り除くのがDCPです。

DCP: KVキャッシュもシャーディング

デコードコンテキスト並列処理はKVキャッシュ自体を分割します。100万トークンのGLM-5.3リクエストには53.4 GiBのFP8 KVが必要ですが、各GPUには約15 GiBしか収まりません。DCPはトークンを8つのGPUにラウンドロビンで分配するため、各GPUは8番目ごとのトークンを保存し、同じリクエストはGPUあたりわずか6.7 GiB(53.4 / 8)で済みます。

名前は歴史的なもので、現在のデプロイメントを説明するものではありません。DCPはデコード用に構築され、各リクエストが単一のクエリトークンを持ち、KVキャッシュが分割する価値のある唯一のものでした。PCPはプレフィル用に構築され、プロンプトの多数のクエリトークンが作業です。このデプロイメントでは、PCPがクエリを分割しDCPがKVを分割するプレフィルエンジン内で両方を実行します。

DCPがキャッシュをシャーディングするため、各GPUのクエリが必要とするKVのほとんどは他のGPUに存在します。デコードでは、DCPはクエリをKVに送信します。各GPUは自分のシャードにアテンションし、部分結果はログサム指数でマージされます。このプレフィルエンジンでは方向が逆です。毎層、各GPUはシャードを一時的な完全コンテキストコピーにオールギャザーし、自分のクエリにアテンションし、コピーを解放します。永続キャッシュのみが8で分割されます。

2つのレイアウトは一致しません。GPUは8番目ごとのトークンを保存しますが、チャンクgと15 - gのクエリを計算します。これがまさに毎層オールギャザーが必要な理由です。

オールギャザーのコスト

オールギャザーは無料ではありません。毎層、キャッシュされたコンテキスト全体を再送信するため、そのコストはコンテキスト長とともに増加します。同じ2Kトークンのプレフィルチャンクを1つのPCP8ノードでDCP8ありとなしで同じキャッシュコンテキストで実行して効果を分離すると、DCP8は64Kトークンのコンテキストまでステップあたり約6%追加し、248Kトークンでは15%に上昇します。これは8倍大きいKVプールの代償です。著者らは、各層のオールギャザーを前の層の計算とオーバーラップさせることでオーバーヘッドを削減できると述べており、現在その最適化に取り組んでいます。

約250Kトークンを超えると、PCP8だけではKVキャッシュを保持できないため、DCPはオーバーヘッドではなくなり、長いプロンプトを可能にするものになります。PCP8とDCP8を組み合わせることで、プレフィルエンジンに速度と容量の両方が与えられます。

デプロイメント: 16基のH200でのプレフィル/デコード分離

デプロイメントは、2つの8x H200ノード上のプレフィル/デコード(P/D)分離セットアップです。両エンジンはFP8 KVキャッシュと3つのドラフトトークンを持つMTP投機的デコード(MTP3)を使用します。

  • プレフィル: 512 GiBのCPU KVオフロードを持つ1つのPCP8 x DCP8 x EP8エンジン。これにより、後のターンがプレフィックスを再利用できます。
  • デコード: パート1からのハイブリッドHiSparseを持つ8つのDPランク(ランクあたり48 GiBのホストプールと16 GiBのオフロード)。これにより、デコードの並行性はHBMではなくホストメモリによって制限されます。

プレフィックス対応のllm-dルーターが各リクエストをプレフィルエンジンに送信し、NIXLコネクタがそのKVキャッシュをデコードランクに移動し、デコードランクがトークンをストリーミングして返します。

比較ベースラインは同じハードウェアと同じ総メモリを使用します。PCP8 x DCP8プレフィルはDP8プレフィル(それぞれ64 GiBのCPU KVオフロードを持つ8つのDPランク、合計512 GiB)と比較され、ハイブリッドHiSparseはデコードノード上のプレーンなCPU KVオフロードと比較され、どちらの場合も512 GiBのホストメモリを使用します。すべての構成は同じ16 GPU、ホストメモリ、vLLMビルドを実行します。

AgentXでの結果

ベンチマークはSemiAnalysis AgentXです。Claude Codeトレースをプレフィックス再利用で再生し、並行性ごとに新しいサーバーを使用し、1時間の実行、合成受入長を2.99に固定したMTP3を使用して、すべての構成が同じ投機的スピードアップを得るようにします。スループットは、キャッシュされたトークンを含むGPUあたりの論理トークン/秒として測定されます。入力と出力のトークン、プレフィックスキャッシュされた入力を含み、16 GPUすべてにわたります。インタラクティブ性は、AgentXのP90エンドツーエンド正規化出力トークン/秒/ユーザーです。

測定は2つのコンテキスト制限で行われました。c8からc64は142K、c8からc32は1Mです。

c32まではデプロイメントは主にプレフィルバウンドであるため、プレフィラーが大きな違いをもたらします。 両方のセットアップでHiSparseデコードを使用すると、PCP8 x DCP8プレフィルは同じスループットでDP8の1.7〜3.2倍のインタラクティブ性を提供し、TTFTの中央値を1.5〜5.2秒から0.8〜0.9秒に短縮します。この負荷ではデコーダーはほとんど違いをもたらしません。c8とc16では、2つのPCP8 x DCP8構成は互いに数パーセント以内であり、オフロードのみのデコードはc8でわずかに先行します。

c32からデプロイメントはよりデコードバウンドになり、HiSparseデコードが先行します。 c64ではスループットがほぼ2倍になり、ユーザーあたり29.6トークン/秒でGPUあたり8,340論理トークン/秒に達しますが、他のすべての構成はユーザーあたり1〜2トークン/秒に低下します。

100万コンテキストでは、デプロイメントは両方のメカニズムを必要とします。 DP8プレフィルランクは100万トークンのリクエストを保持できず、オフロードのみのデコードランクも保持できません。そのため、組み合わせた構成が100万トークンのコンテキストをサービスする唯一のテスト済み構成です。

機能を構成可能にする

難しいエンジニアリング作業は、PCP、DCP、ハイブリッドHiSparseなどの機能を構成可能にすることです。それぞれがKVキャッシュのレイアウト、スケジューリング、移動方法を変更し、すべての組み合わせが正確で高速である必要があるためです。

プレフィル/デコード分離では、KVは2つのエンジン間でレイアウトを変更する必要があります。プレフィルエンジンは各リクエストのKVを8つのGPUにトークン単位でシャーディングしますが、各デコードランクはMTP層のものを含む完全なKVを独自のページレイアウトで必要とします。NIXLコネクタは2つのノード間でこの再組み立てを実行し、CPUオフロードからのプレフィックス再利用はそれと並行して機能し続ける必要があります。

記事内のすべての構成は、vLLMの新しいモジュラーコアであるModel Runner V2で実行されます。これはモデル固有の状態を共通の実行パスから分離し、CPU-GPU同期なしで投機的デコードを実行します。ハイブリッドHiSparseはその上に構築されています。

再現方法と必要なフラグ

記事内のすべては、vllm/vllm-openai:v0.32.0イメージを使用してvLLM v0.32.0以降で実行されます。報告された結果は、コミット9e38b4111aのvLLM mainで測定され、再現用gistはコミット2537629eb2を固定しています。

プレフィルエンジンの主要なフラグは次のとおりです。

--prefill-context-parallel-size 8 \
--decode-context-parallel-size 8 \
--dcp-comm-backend ag_rs \
--enable-expert-parallel \
--attention-config '{"sparse_mla_force_mqa":true}'

1つのフラグについて説明が必要です。sparse_mla_force_mqaがないと、プロンプトが2,048トークンのtop-k内に収まるプレフィルバッチは高密度MHAパスを取ります。このフラグはそれらをスパースMLA(MQA)カーネルにも維持するため、すべてのKV行がすべてのヘッドにサービスします。

数字がうまくいく理由

メモリと計算に関する記事の主張を支える3つの脚注計算があります。スパースMLAは、それぞれ660バイトの2,048個の選択されたKV行(FlashMLAのfp8_ds_mla形式の656バイトのFP8 KVと4バイトのインデックス)を読み取り、クエリあたり約1.35 MBです。各ヘッドはBF16クエリと出力に2,176バイトを追加し、行あたり2,176 FLOPs(QKは576次元、PVは512次元)を実行します。したがって、8ヘッドは1.37 MBで35.7 MFLOPs、約26 FLOPs/バイト、64ヘッドは1.49 MBで285 MFLOPs、約191 FLOPs/バイトです。

H200 SXMの場合、BF16リッジポイントは4.8 TB/sの帯域幅で989の高密度BF16 TFLOP/s、つまり206 FLOPs/バイトです。データシートの1,979 TFLOP/sの数値は2:4スパーシティを想定しています。

53.4 GiBの数値はトークンあたりのKV計算から来ています。78層 x 656バイトのMLA KV、21インデクサー層 x 132バイトのインデクサーキー(128 FP8値と4バイトのスケール)、およびMTP層の788バイト、合計54,728バイトです。N = 1,048,576トークンの場合、54,728 MiB、約53.4 GiBです。

誰が作業を行ったか

この作業は、Red HatのRoberto L. Castro、Simon Veitner、Matthew Bonanni、Lucas Wilkinson、およびMistralのNicolo Lucchesiによって行われました。Red HatのMaroon AyoubとRobert Shawは、デプロイメントのストレステスト、エラーの報告、バグ修正に貢献したとされています。

Sources