推論拡張機能付きゲートウェイコンポーネントを使用すると、さまざまな生成 AI シナリオで推論サービスルーティングに異なる負荷分散ポリシーを指定できます。このトピックでは、推論拡張機能付きゲートウェイコンポーネントを使用して、推定モードでプレフィックスキャッシュ対応ルーティングを実装する方法について説明します。
開始する前に、InferencePool と InferenceModel の概念を理解していることを確認してください。
このトピックでは、バージョン 1.4.0 以降の推論拡張機能付きゲートウェイコンポーネントが必要です。
背景情報
vLLM での自動プレフィックスキャッシュ
vLLM は自動プレフィックスキャッシュ (APC) をサポートしています。APC は、vLLM が以前のリクエストで計算したキー値 (KV) 状態をキャッシュします。新しいリクエストが以前のリクエストとプレフィックスを共有する場合、既存の KV キャッシュを再利用できます。これにより、新しいリクエストは共有プレフィックスの KV キャッシュ計算をスキップできます。このプロセスにより、大規模言語モデル (LLM) 推論リクエストの処理が高速化されます。
推定モードでのプレフィックスキャッシュ対応ルーティング
推定モードでのプレフィックスキャッシュ対応ルーティングは、同じプレフィックスを共有するリクエストを可能な限り同じ推論サーバー Pod に送信する負荷分散ポリシーです。推論拡張機能付きゲートウェイコンポーネントは、各推論サーバーにルーティングされたリクエストを追跡します。その後、各サーバーのプレフィックスキャッシュステータスを推定して、推論エンジンのキャッシュヒット率を向上させます。
モデルサーバーで APC 機能が有効になっている場合、推定モードでのプレフィックスキャッシュ対応ルーティングポリシーは、キャッシュヒット率を最大化し、リクエストの応答時間を短縮できます。このポリシーは、プレフィックスを共有するリクエストが多いシナリオに最適です。ビジネスニーズに基づいてその適合性を評価する必要があります。
一般的なシナリオは次のとおりです。
長文ドキュメントのクエリ: ユーザーは、ソフトウェアマニュアルや年次報告書などの同じ長文ドキュメントに対して、異なるクエリで繰り返しクエリを実行します。
マルチターン対話: ユーザーは、同じチャットセッションでアプリケーションと複数回対話する場合があります。
前提条件
GPU ノードプールを備えた ACK マネージドクラスター が利用可能です。ACK マネージドクラスターに ACK Virtual Node コンポーネントをインストールして、ACS GPU 計算能力 を使用することもできます。
バージョン 1.4.0 以降の推論拡張機能付きゲートウェイコンポーネントがインストールされており、[Gateway API 推論拡張を有効にする] を選択している必要があります。詳細については、「コンポーネントのインストール」をご参照ください。
このトピックで説明されているイメージについては、ACK クラスターには A10 カードを、Alibaba Cloud Container Compute Service (ACS) GPU 計算能力には L20(GN8IS) カードを使用することをお勧めします。
LLM イメージのサイズが大きいため、事前に Container Registry に転送し、内部ネットワークアドレスを使用してプルすることをお勧めします。パブリックネットワークからのプル速度は、クラスターの Elastic IP アドレス (EIP) の帯域幅構成に依存するため、待機時間が長くなる可能性があります。
手順
ステップ 1: サンプル推論サービスをデプロイする
vllm-service.yaml という名前のファイルを作成します。
サンプル推論サービスをデプロイします。
kubectl apply -f vllm-service.yaml
ステップ 2: 推論ルートをデプロイする
このステップでは、InferencePool リソースと InferenceModel リソースを作成できます。
inference-pool.yaml という名前のファイルを作成します。
apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferencePool metadata: annotations: inference.networking.x-k8s.io/routing-strategy: "PREFIX_CACHE" name: vllm-qwen-pool spec: targetPortNumber: 8000 selector: app: qwen extensionRef: name: inference-gateway-ext-proc --- apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceModel metadata: name: inferencemodel-qwen spec: modelName: /model/qwen criticality: Critical poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: vllm-qwen-pool targetModels: - name: /model/qwen weight: 100InferencePool リソースに、
inference.networking.x-k8s.io/routing-strategy: "PREFIX_CACHE"アノテーションを追加します。これにより、InferencePool 内の Pod に対して推定モードでのプレフィックスキャッシュ対応ルーティングが有効になります。推論ルートをデプロイします。
kubectl apply -f inference-pool.yaml
ステップ 3: ゲートウェイとゲートウェイルーティングルールをデプロイする
このステップでは、ポート 8080 と 8081 でリッスンするゲートウェイを作成できます。ポート 8081 では、HTTPRoute リソースが推論拡張機能によって提供される InferencePool をバックエンドとして指定します。推論リクエストは、InferencePool で定義された Pod コレクションにルーティングされます。ポート 8080 では、別の HTTPRoute リソースがサービスをバックエンドとして指定します。推論リクエストは、標準の HTTP 最小リクエスト負荷分散ポリシーを使用して同じ Pod コレクションにルーティングされます。
inference-gateway.yaml という名前のファイルを作成します。
apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: qwen-inference-gateway-class spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: qwen-inference-gateway spec: gatewayClassName: qwen-inference-gateway-class listeners: - name: http protocol: HTTP port: 8080 - name: llm-gw protocol: HTTP port: 8081 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: qwen-backend spec: parentRefs: - name: qwen-inference-gateway sectionName: llm-gw rules: - backendRefs: - group: inference.networking.x-k8s.io kind: InferencePool name: vllm-qwen-pool matches: - path: type: PathPrefix value: / --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: qwen-backend-no-inference spec: parentRefs: - group: gateway.networking.k8s.io kind: Gateway name: qwen-inference-gateway sectionName: http rules: - backendRefs: - group: "" kind: Service name: qwen port: 8000 weight: 1 matches: - path: type: PathPrefix value: / --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: name: backend-timeout spec: timeout: http: requestTimeout: 1h targetRef: group: gateway.networking.k8s.io kind: Gateway name: qwen-inference-gatewayゲートウェイをデプロイします。
kubectl apply -f inference-gateway.yaml
ステップ 4: ルーティングルールを検証する
round1.txt と round2.txt という名前のファイルを作成します。両方のファイルには、同一の
contentセクションが含まれています。round1.txt の内容、次に round2.txt の内容を LLM のリクエストボディとして使用します。その後、extensionRef のログをチェックして、推定モードでのプレフィックスキャッシュ対応ルーティングがトリガーされたことを確認します。round1.txt:
echo '{"max_tokens":24,"messages":[{"content":"Hi, here'\''s some system prompt: hi hi hi hi hi hi hi hi hi hi.For user 3, here are some other context: hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi.I would like to test your intelligence. for this purpose I would like you to play zork. you can interact with the game by typing in commands. I will forward these commands to the game and type in any response. are you ready?","role":"user"}],"model":"/model/qwen","stream":true,"stream_options":{"include_usage":true},"temperature":0}' > round1.txtround2.txt:
echo '{"max_tokens":3,"messages":[{"content":"Hi, here'\''s some system prompt: hi hi hi hi hi hi hi hi hi hi.For user 3, here are some other context: hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi hi.I would like to test your intelligence. for this purpose I would like you to play zork. you can interact with the game by typing in commands. I will forward these commands to the game and type in any response. are you ready?","role":"user"},{"content":"Hi there! It looks like you're setting up a fun test. I'm ready to play Zork! You can","role":"assistant"},{"content":"% zork\nWelcome to Dungeon. This version created 11-MAR-91.\nYou are in an open field west of a big white house with a boarded\nfront door.\nThere is a small mailbox here.\n>","role":"user"},{"content":"Great!","role":"assistant"},{"content":"Opening the mailbox reveals:\n A leaflet.\n>","role":"user"}],"model":"/model/qwen","stream":true,"stream_options":{"include_usage":true},"temperature":0}' > round2.txtゲートウェイのパブリック IP アドレスを取得します。
export GATEWAY_IP=$(kubectl get gateway/qwen-inference-gateway -o jsonpath='{.status.addresses[0].value}')2 つのセッションリクエストを送信して、マルチターン対話シナリオをシミュレートします。
curl -X POST ${GATEWAY_IP}:8081/v1/chat/completions -H 'Content-Type: application/json' -d @./round1.txt curl -X POST ${GATEWAY_IP}:8081/v1/chat/completions -H 'Content-Type: application/json' -d @./round2.txtログをチェックして、推定モードでのプレフィックスキャッシュ対応ルーティングが機能していることを確認します。
kubectl logs deploy/epp-default-inference-gateway-ext-proc -n envoy-gateway-system|grep "Do prefix"期待される出力:
2025-05-23T03:33:09Z INFO scheduling/prefixcache_filter.go:311 Do prefix-aware routing! {"request": "v68m4zx472", "matching ratio": " 0.54 > 0.50"}ログには
Do prefix-aware routing!メッセージが含まれています。これは、推定モードでのプレフィックスキャッシュ対応ルーティングが機能していることを示します。
(オプション) ステップ 5: マルチターン対話テストで推論サービスのパフォーマンスを評価する
このステップでは、ACK クラスターを例として使用し、ストレステストツールを使用してマルチターン対話テストを実行する方法を示します。目標は、標準の HTTP ルーティングのパフォーマンスと、プレフィックスキャッシュ対応の推論ルーティングのパフォーマンスを比較することです。
llm-qa-benchmark ストレステストツールをデプロイします。
kubectl apply -f- <<EOF apiVersion: apps/v1 kind: Deployment metadata: labels: app: llm-qa-benchmark name: llm-qa-benchmark spec: replicas: 1 selector: matchLabels: app: llm-qa-benchmark template: metadata: labels: app: llm-qa-benchmark spec: containers: - command: - sh - -c - sleep inf image: registry-cn-hangzhou.ack.aliyuncs.com/dev/llm-qa-benchmark:v0.1 imagePullPolicy: IfNotPresent name: llm-qa-benchmark terminationMessagePath: /dev/termination-log terminationMessagePolicy: File restartPolicy: Always EOFゲートウェイの内部 IP アドレスを取得します。
export GW_IP=$(kubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=qwen-inference-gateway -o jsonpath='{.items[0].spec.clusterIP}')ストレステストを実行します。
重要以下の結果はテスト環境のものです。実際の結果は異なる場合があります。
標準 HTTP ルーティング
kubectl exec -it deploy/llm-qa-benchmark -- env GW_IP=${GW_IP} python3 multi-round-qa.py \ --num-users 8 \ --num-rounds 15 \ --qps 0.1 \ --shared-system-prompt 100 \ --sharegpt \ --user-history-prompt 2000 \ --answer-len 100 \ --model /model/qwen \ --time 600 \ --base-url http://${GW_IP}:8080/v1期待される出力:
==================== Performance summary ====================== QPS: 0.1000 reqs/s Processing speed: 0.1080 reqs/s Requests on-the-fly: 0 Input tokens per second: 259.0703 tokens/s Output tokens per second: 4.8576 tokens/s Average generation throughput (per request): 26.6710 tokens/req/s Average TTFT: 0.3669s Time range: 1748231183.2753935 - 1748231766.4799275 (583.20s) ===============================================================推論サービスルーティング
kubectl exec -it deploy/llm-qa-benchmark -- env GW_IP=${GW_IP} python3 multi-round-qa.py \ --num-users 8 \ --num-rounds 15 \ --qps 0.1 \ --shared-system-prompt 100 \ --sharegpt \ --user-history-prompt 2000 \ --answer-len 100 \ --model /model/qwen \ --time 600 \ --base-url http://${GW_IP}:8081/v1期待される出力:
==================== Performance summary ====================== QPS: 0.1000 reqs/s Processing speed: 0.1081 reqs/s Requests on-the-fly: 0 Input tokens per second: 259.3009 tokens/s Output tokens per second: 4.8548 tokens/s Average generation throughput (per request): 26.9300 tokens/req/s Average TTFT: 0.2761s Time range: 1748231885.874972 - 1748232468.5918882 (582.72s) ===============================================================結果は、推論サービスルーティングの
Average TTFTが標準の HTTP ルーティングよりも大幅に低いことを示しています。