Google Cloudがllm-d 1.0を紹介、KV cacheを考慮したルーティングが可能
公開:
llm-d 1.0は、vLLMやSGLangのような単体の推論エンジンを、クラスタ全体で連携する提供基盤に変える分散推論の制御基盤です。一方、標準のingressコントローラは、LLMの連続するターンを別々のレプリカへ散らし、KV cacheを作り直し続けます。[1]
この記事では、llm-d 1.0でできることやGKE Inference Gatewayとの連携、同Gatewayの料金を解説します。KubeRayによるRayクラスタの管理やgVisorを使ったAIエージェントの隔離も対象です。[1][2][3]
llm-d 1.0でできること
llm-d 1.0の中核機能には、リクエストの送り先の選択やKV cacheの退避、処理段階の分離、非同期処理の優先制御などがあります。llm-d 1.0のコンポーネントは組み合わせて使う設計で、推論エンジンやモデル、クラスタはそのままに、必要なコンポーネントと設定だけを採用できます。[1][2][3]
Endpoint Pickerの振り分け
Endpoint Pickerは、ワーカーPodごとのKV cacheの保持状況をリアルタイムに評価し、リクエストの送り先を選びます。Prefix-cache-aware routingを担う機能で、Kubernetes Gateway API Inference Extensionに組み込まれています。
Google Cloudは、Endpoint Pickerの本番導入で、複数ターンのエージェント処理のKV cacheヒット率が35%から70%に倍増したと公表しました。最初のトークンが返るまでの時間(TTFT)の中央値も、70〜85%短くなったとしています。
KV cacheの3層オフロード
3-Tier KV cache offloadは、長い文脈のやり取りでHBM(アクセラレータの高帯域メモリ)が上限に近づくと働きます。llm-dは、KV cacheのブロックをHBMからホストのCPU RAMへ移し、その先の層へ順に移します。
3層目の移動先は、ローカルNVMe SSDやGoogle Cloud Managed Lustre、Cloud Storageです。このオフロードは、高コストな文脈の再計算を防ぎます。
EPDの3段階の分離
EPD Disaggregationは、EncodingやPrefill、Decodeの3段階を、高速な接続でつながった専用ハードウェアのプールへ分けて置きます。Prefillは計算負荷が高く、Decodeはメモリに制約される処理です。
DisaggregatedSetは、複数ホストでの推論向けのKubernetes APIであるLeaderWorkerSet(LWS)を基盤にしています。各段階を独立して水平スケールでき、停止時間なしのローリングアップグレードを協調して行えます。
非同期処理の優先制御
llm-d-async-processorは、遅延を許容できるバックグラウンド処理を、Pub/SubやRedisからクラスタの空き容量へ取り込みます。バックグラウンド処理が対話型の利用者体験を損なわないよう、トラフィックに厳格な優先順位を付ける仕組みです。
TorchTPUによるTPU対応
TorchTPUを通じて、PyTorchモデルはupstreamのvLLMやSGLangの中で、Google Cloud TPU上でネイティブに動きます。TPU v5eやv6e、v7xでもNVIDIA GPUと並んで初日から同等に使え、独自の分岐版の保守やパイプラインの書き直しは不要です。
Prismでの性能の確認
Prismは、llm-dのオープンソースのベンチマークと性能のダッシュボードです。フリートの観測として、クラスタ全体のスループットやトークン間の遅延(ITL)、TTFT、キャッシュヒット率を追跡できます。
GKEで動かすllm-d 1.0
GKEでは、GKE Inference GatewayがEndpoint Pickerをネイティブに管理します。GKE Inference Gatewayは、Gateway Modeで動くllm-d routerで、利用者自身によるプロキシの運用は不要です。[1][2][3]
GKEへの導入の進め方
Google Cloudは、既存のvLLMデプロイメントの前にprefix-aware routingを置いて始める進め方を勧めています。その後で加えるのが、flow controlやKV cache offload、disaggregationです。
InferencePool設定例
InferencePoolでPrefixCacheAwareを指定する設定例は、以下の通りです。
apiVersion: inference.networking.x-k8s.io/v1alpha1
kind: InferencePool
metadata:
name: gemma-serving-pool
namespace: ai-serving
spec:
targetRef:
group: apps
kind: Deployment
name: vllm-gemma-27b
scheduling:
# Routes multi-turn requests to replicas holding matching KV context
strategy: PrefixCacheAware
fallback: LeastQueueDepth
observability:
kvCacheSyncInterval: "50ms"
公式資料からの抜粋:The open AI-native stack on Kubernetes: From open models to distributed inference and agents(Distributed inference at scale with llm-d 1.0)。対象版・範囲:公式のInferencePool設定例(inference.networking.x-k8s.io/v1alpha1)。
上記のコードでは、vllm-gemma-27bというDeploymentを対象に、strategyをPrefixCacheAwareにしています。複数ターンのリクエストを一致するKVの文脈を持つレプリカへ送る設定で、fallbackはLeastQueueDepthです。
KubeRayによるRayクラスタの管理
推論とRLループは専用のランタイムが担う一方、分散データ準備や埋め込み生成、PyTorchの分散学習はRayに大きく依存しています。KubeRayは、RayClusterやRayJob、RayServiceのライフサイクル全体を管理する、オープンソースのKubernetesネイティブなオペレーターです。[1]
宣言的なライフサイクル管理では、臨時の学習用に自己修復する一時的なRayクラスタを必要なときに起動でき、バッチ処理用のクラスタを長期間動かせます。KubeRayはKueueと直接連携してキューイングに対応し、共有のGPUとTPUの容量でマルチテナントの公平な共有や優先度による割り込み、割り当て量を管理します。
KubeRayは、実行中のRayタスクやアクターの配置に応じてワーカーPodを増減し、遊休資源の消費を防ぐ仕組みです。RayJobの設定例は、以下の通りです。
apiVersion: ray.io/v1
kind: RayJob
metadata:
name: gemma-fine-tune-job
namespace: ai-workloads
labels:
kueue.x-k8s.io/queue-name: ml-team-queue
spec:
shutdownAfterJobFinishes: true
ttlSecondsAfterFinished: 60
entrypoint: python fine_tune_gemma.py --model-id google/gemma-2-27b-it
公式資料からの抜粋:The open AI-native stack on Kubernetes: From open models to distributed inference and agents(Distributed Python & ML orchestration with KubeRay)。対象版・範囲:公式のRayJob設定例(ray.io/v1) / 公式のRayJob設定例。
上記のコードでは、google/gemma-2-27b-itを微調整するRayJobを定義しています。メタデータのラベルは、kueue.x-k8s.io/queue-name: ml-team-queueです。
AIエージェント向けのサンドボックス
AIエージェントがコードの生成やシェルコマンドの実行、外部APIの操作を担うと、共有クラスタで信頼できないコードを動かすことに深刻なセキュリティ上のリスクが生じます。Google Cloudは、CNCF SandboxでAgent Substrateをコントリビュートし、gVisorへの貢献も続けています。[1]
gVisorは、システムコールを横取りして仮想化する、ユーザー空間のカーネルです。信頼できないエージェントのコードが、ホストのカーネルを侵害したり、隣のテナントのワークロードにアクセスしたりするのを防ぐのに役立ちます。
Agent SubstrateとgVisorのサンドボックスは、エージェントのターンごとにミリ秒単位で起動します。隔離された実行環境の用途は、OpenRLでの強化学習(RL)のロールアウト生成と、本番で動くエージェントのワークフローの両方です。[1][3]
GKEでllm-d 1.0を使う前の確認点
llm-d 1.0は、発表時点でCNCF Sandboxのプロジェクトです。GKE Inference Gatewayは追加料金なしで利用でき、課金されるのは使用した基盤のGoogle Cloudリソースだけです。[1][2][3]
llm-d 1.0が土台とする構成要素
llm-d 1.0は、すでに運用しているかもしれないKubernetesの構成要素を土台にしています。構成要素は、以下の通りです。
Priorityとストリーミング
GKE Inference Gatewayでは、InferenceObjectiveのPriorityが0未満のリクエストが、負荷時に最初に破棄され、429エラーが返ります。Priorityの既定値は0で、破棄の対象になるのは0未満を明示的に設定した場合だけです。
ストリーミング応答の途中でエラーが起きると、ストリーミングは終了し、クライアントにエラーメッセージが送られます。GKE Inference Gatewayは、ストリーミング応答を再試行しません。
マルチポートのNEG上限
マルチポートのInferencePoolでは、各ゾーンの各ポートに専用のNEG(ネットワークエンドポイントグループ)が作られます。NEGの上限はGoogle Cloudのバックエンドサービスごとに50個で、3ゾーンで8ポートのInferencePoolが作るNEGは24個です。
マルチポートのInferencePoolをマルチクラスタGatewayで集約する場合は、クラスタごとのNEGを足し合わせ、50個に収まるかを確かめます。3ゾーンで8ポートの例では、集約できるのは最大2クラスタ(48個)までです。
出典
- ^ Google Cloud. 「The open AI-native stack on Kubernetes: From open models to distributed inference and agents」. https://cloud.google.com/blog/topics/developers-practitioners/the-open-ai-native-stack-on-kubernetes-from-open-models-to-distributed-inference-and-agents, (参照 26-11-10).
- ^ Google Cloud. 「llm-d を搭載した GKE Inference Gateway について」. https://docs.cloud.google.com/kubernetes-engine/docs/concepts/about-gke-inference-gateway?hl=ja, (参照 26-11-10).
- ^ Google Cloud. 「Announcing llm-d 1.0: Open distributed inference for agents on Google Cloud TPUs and GPUs」. https://cloud.google.com/blog/topics/ai-infrastructure/llm-d-1-0-an-open-source-stack-for-distributed-inference?hl=en, (参照 26-11-10).
※本記事は公式の一次情報を基に編集しています。内容はAIで確認していますが、誤りや最新情報との差異がある場合は、以下フォームよりご報告ください。
修正・削除・掲載などの依頼はこちら

















