次のターンは、前のターンがキャッシュを残した場所へ。
エージェントは毎ターン履歴全体を送り直すので、長い会話の大部分はエンジンがすでに読んだプレフィックスです。vLLM はその処理結果をプレフィックス キャッシュ (見たことのあるプロンプトのアテンション状態) に保持し、同じプレフィックスが次に来たときには処理を省きます。ただし、それが有効なのは処理を行ったレプリカだけです。モデルの完全なコピーはそれぞれ独自のキャッシュを持っています。vLLM 自身のバランサーは各ターンをキューが最も短いレプリカに送りますが、そのレプリカは通常その会話を一度も処理していないため、履歴全体をもう一度読み込むことになります。LM Warden は、新しい会話を最も負荷の低いレプリカ (実行中のリクエスト、キャッシュの埋まり具合、保持している進行中の会話の数で判断) に配置し、Claude Code がすでに送っているセッション ID を使ってそこに留めます。リクエストを移すのは、そのレプリカがスピルしきい値を超えたときだけです。既定では、実行中のリクエストがモデルの同時シーケンス上限の四分の一を超えたときで、四枚のカードを積んだ自社マシンでは 8 です。
レプリカと、それを前提とするこのルーティングは、NVIDIA GPU を使う Linux インストールの機能です。Mac アプリ (ベータ版) にはテンソル並列もデータ並列もありません。
図 6四レプリカのモデルでの一つの会話の四ターン。vLLM のバランサーでは、各ターンが受け取ったレプリカでほぼ最初からプリフィル (プロンプトをキャッシュに読み込むこと) されます。LM Warden では会話がレプリカ 2 に留まり、新しいターンだけがプリフィルされます。仕組みの図であり、測定結果ではありません。
四枚のカードを積んだマシンでの実測:会話を固定すると、同時 4 セッションでキャッシュから提供されたプロンプト トークンの割合は 56 から 86% に上がり、最初のバイトまでの時間の中央値は 2.05 から 0.38 s に下がりました。毎分の出力トークン数は実行したすべての段階で高く、最初のバイトまでの時間の p95 (最も遅い 5%) もすべての段階で低くなりました。処理を行っているレプリカの数はほとんど変わりません (4 セッションで四つ中 2.71 対 2.83)。効果はキャッシュの再利用によるもので、働くカードが増えたからではありません。
24 と 32 セッションの段階は、小さなカード四枚に対する意図的な過負荷で、アフィニティの有無にかかわらず待ち時間は数十秒に達します。そこではトレードオフが現れます。アフィニティありのほうがテール レイテンシは依然として短いものの、中央値は長くなります。数値は以下のとおりです。
- GPU
- 4 × NVIDIA RTX A4000、各 16 GiB
- モデル
- qwen3-4b-dp4 (Qwen/Qwen3-4B-Instruct-2507)、bf16
- レイアウト
- data_parallel_size 4、tensor_parallel_size 1
- vLLM
- 0.26.0
- LM Warden
- このリリース
- 記録日
- 2026 年 10 月 4 日、両条件を連続して実行
- 負荷
- Claude Code そのものではなく、自社のテスト ハーネスによる Claude Code 風の合成セッション:約 3.5k トークンの共通システム プロンプト、セッション固有の最初のメッセージ (公称 6k、実測約 7.2k~7.5k)、続いてそれぞれ約 400 トークンを新たに加えるターンがさらに五つ。出力はターンあたり最大 256 トークン。クローズド ループで、前のターンが終わるとセッションは次のターンを始めます。各段階 3 分。
図 7同時 4~32 セッションでの最初のバイトまでの時間 (中央値と p95)。一秒未満の段階と一分近い段階を並べて読めるよう対数目盛です。アフィニティありでは 16 セッションまで中央値がはるかに低く (4 セッションで 0.38 対 2.05 s)、24 と 32 では高くなります。p95 はすべての段階で低いものの、16 での差 (24.9 対 26.2 s) は各条件一回ずつの実行のノイズの範囲内です。クライアント側で、インターネット経由、最初にストリーミングされたトークンまでを測定。
16 セッションまでは、スループット、プレフィックス キャッシュ ヒット、最初のバイトまでの時間の両方の列で、アフィニティがすべての段階で優位です。4 セッションでヒット率は 56 から 86% に、最初のバイトまでの時間の中央値は 2.05 から 0.38 s に、出力は毎分 5,886 から 6,744 トークンに (一時間あたりのセッション数は 180 から 240 に) なります。過負荷の段階である 24 と 32 セッションでは、すべてのレプリカが飽和します。出力はそれでも高く (毎分 11,178 対 9,048 トークン、16,638 対 14,760 トークン)、テール レイテンシもずっと短い (p95 で 38 対 59 s、39 対 83 s) のですが、最初のバイトまでの時間の中央値はアフィニティありのほうが悪くなります (24 セッションで 13.1 対 5.1 s、32 セッションで 27.7 対 12.3 s)。原因はまだ特定できておらず、スピルしきい値を 8 から 4 に下げても変わりませんでした。効果が最も大きいのは余裕があるときです。上限近くで動いているマシンでは両方の設定を測定してください。アフィニティはモデルごとにオフにできます。
図 8稼働中のレプリカ数 (四つ中):各ポーリング時にリクエストを実行していたレプリカの数を、段階ごとに平均したもの。GPU 使用率ではありません。アフィニティはこれをほとんど変えません。効果は図 9 に表れています。
図 9各段階のプレフィックス キャッシュ ヒット率:キャッシュから提供されたプロンプト トークン数を要求されたプロンプト トークン数で割ったもの。四つのレプリカすべてを合算し、その段階での vLLM 自身のカウンターの変化から算出。効果は余裕があるうちは続き、会話がスピルする 32 セッションでは消えます。
アフィニティ オン、スピルしきい値 8 (自動)
レプリカごとのヒット率 (vLLM 自身のカウンターから)
図 10モデルのページにある同じカウンター:レプリカごとに一行で、保持しているリクエスト、留まった会話 (sticky) とスピルで来た会話の数、実行中と待機中の数、使用中の KV キャッシュ、プレフィックス キャッシュ ヒット率を表示します。2026 年 10 月 4 日、アフィニティ オン、スピルしきい値 8 (自動) で記録:sticky 100%、レプリカ 0~3 の sticky リクエストは 38、21、19、29、プレフィックス キャッシュ ヒット率は 82.2、86.0、69.0、80.0%。カウンターは warden の再起動から集計されており、その期間のトラフィックはすべてアフィニティ オンで流れました。合成のエージェント セッションと、実際の Claude Code のターンです。画像はコンソールのカードそのもので、ベンチマーク結果ではありません。画像を横にスクロールするとすべての列が見られます。
最初にレプリカ ルーティングのきっかけとなったマシンは、それ以来このルーティングで動いています。RTX 5090 を七枚積み、27B モデルを一枚ずつ七つのレプリカとして、ヘッドレスの Claude Code エージェント群に提供しています。最初の配置ルールはセッション ID をハッシュするもので、スティッキーではあるものの負荷が見えていませんでした。それぞれ約 58k トークンのエージェント セッションが 26 あると、三つのレプリカがアイドル状態のままである一方でほかのレプリカはキャッシュを 93% まで使い、キャッシュから提供されたプロンプト トークンの割合は、再起動後の 81% から約 35 分で 28% まで落ちました。そこでエージェント群を 16 セッション (レプリカあたり約二つ) に減らしてワーキング セットがキャッシュに収まるようにし、新しい会話を最も負荷の低いレプリカに配置しました。その後の一時間は 78~79% でした。これは A/B テストではなく観察です。一つのワークロードで二つの変更を同時に行ったので、効果は配置だけによるものではありません。ここから言える経験則は、同時セッション数と典型的なコンテキスト長の積を、マシンのキャッシュ総量より小さく抑えることです。
リクエストごとにエンジンが測定
図 11GPU 七枚のマシンでの毎秒のプロンプト トークン数。各レプリカがプレフィックス キャッシュから読んだ分と計算が必要だった分に分け、直近一時間の割合 78% を示しています。キャッシュ分は完了した各リクエストについてのエンジン自身のカウントで、推定ではありません。エンジンが測定しなかったリクエストは計算分として数えます。2026 年 10 月 5 日に記録。画像を横にスクロールすると一時間全体が見られます。