すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:推定モードでのプレフィックスキャッシュ対応ルーティング機能の使用

最終更新日:Nov 09, 2025

推論拡張機能付きゲートウェイコンポーネントを使用すると、さまざまな生成 AI シナリオで推論サービスルーティングに異なる負荷分散ポリシーを指定できます。このトピックでは、推論拡張機能付きゲートウェイコンポーネントを使用して、推定モードでプレフィックスキャッシュ対応ルーティングを実装する方法について説明します。

重要
  • 開始する前に、InferencePool と InferenceModel の概念を理解していることを確認してください。

  • このトピックでは、バージョン 1.4.0 以降推論拡張機能付きゲートウェイコンポーネントが必要です。

背景情報

vLLM での自動プレフィックスキャッシュ

vLLM は自動プレフィックスキャッシュ (APC) をサポートしています。APC は、vLLM が以前のリクエストで計算したキー値 (KV) 状態をキャッシュします。新しいリクエストが以前のリクエストとプレフィックスを共有する場合、既存の KV キャッシュを再利用できます。これにより、新しいリクエストは共有プレフィックスの KV キャッシュ計算をスキップできます。このプロセスにより、大規模言語モデル (LLM) 推論リクエストの処理が高速化されます。

推定モードでのプレフィックスキャッシュ対応ルーティング

推定モードでのプレフィックスキャッシュ対応ルーティングは、同じプレフィックスを共有するリクエストを可能な限り同じ推論サーバー Pod に送信する負荷分散ポリシーです。推論拡張機能付きゲートウェイコンポーネントは、各推論サーバーにルーティングされたリクエストを追跡します。その後、各サーバーのプレフィックスキャッシュステータスを推定して、推論エンジンのキャッシュヒット率を向上させます。

モデルサーバーで APC 機能が有効になっている場合、推定モードでのプレフィックスキャッシュ対応ルーティングポリシーは、キャッシュヒット率を最大化し、リクエストの応答時間を短縮できます。このポリシーは、プレフィックスを共有するリクエストが多いシナリオに最適です。ビジネスニーズに基づいてその適合性を評価する必要があります。

一般的なシナリオは次のとおりです。

  • 長文ドキュメントのクエリ: ユーザーは、ソフトウェアマニュアルや年次報告書などの同じ長文ドキュメントに対して、異なるクエリで繰り返しクエリを実行します。

  • マルチターン対話: ユーザーは、同じチャットセッションでアプリケーションと複数回対話する場合があります。

前提条件

説明

このトピックで説明されているイメージについては、ACK クラスターには A10 カードを、Alibaba Cloud Container Compute Service (ACS) GPU 計算能力には L20(GN8IS) カードを使用することをお勧めします。

LLM イメージのサイズが大きいため、事前に Container Registry に転送し、内部ネットワークアドレスを使用してプルすることをお勧めします。パブリックネットワークからのプル速度は、クラスターの Elastic IP アドレス (EIP) の帯域幅構成に依存するため、待機時間が長くなる可能性があります。

手順

ステップ 1: サンプル推論サービスをデプロイする

  1. vllm-service.yaml という名前のファイルを作成します。

    クリックして YAML コンテンツを表示

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: qwen
      name: qwen
    spec:
      replicas: 5
      selector:
        matchLabels:
          app: qwen
      template:
        metadata:
          annotations:
            prometheus.io/path: /metrics
            prometheus.io/port: "8000"
            prometheus.io/scrape: "true"
          labels:
            app: qwen
        spec:
          containers:
          - command:
            - sh
            - -c
            - vllm serve /models/Qwen-2.5-7B-Instruct --port 8000 --enable_prefix_caching --trust-remote-code --served-model-name /model/qwen --max-model-len 8192 --gpu-memory-utilization 0.95 --enforce-eager --enable-lora --max-loras 2 --max-cpu-loras 4 --lora-modules travel-helper-v1=/models/Qwen-TravelHelper-Lora travel-helper-v2=/models/Qwen-TravelHelper-Lora-v2
            image: registry-cn-hangzhou.ack.aliyuncs.com/dev/qwen-2.5-7b-instruct-lora:v0.1
            imagePullPolicy: IfNotPresent
            name: custom-serving
            ports:
            - containerPort: 8000
              name: http
              protocol: TCP
            readinessProbe:
              failureThreshold: 3
              initialDelaySeconds: 30
              periodSeconds: 30
              successThreshold: 1
              tcpSocket:
                port: 8000
              timeoutSeconds: 1
            resources:
              limits:
                nvidia.com/gpu: "1"
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /dev/shm
              name: dshm
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
          volumes:
          - emptyDir:
              medium: Memory
              sizeLimit: 30Gi
            name: dshm
    ---
    apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: qwen
      name: qwen
    spec:
      ports:
      - name: http-serving
        port: 8000
        protocol: TCP
        targetPort: 8000
      selector:
        app: qwen
  2. サンプル推論サービスをデプロイします。

    kubectl apply -f vllm-service.yaml

ステップ 2: 推論ルートをデプロイする

このステップでは、InferencePool リソースと InferenceModel リソースを作成できます。

  1. 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: 100

    InferencePool リソースに、inference.networking.x-k8s.io/routing-strategy: "PREFIX_CACHE" アノテーションを追加します。これにより、InferencePool 内の Pod に対して推定モードでのプレフィックスキャッシュ対応ルーティングが有効になります。

  2. 推論ルートをデプロイします。

    kubectl apply -f inference-pool.yaml

ステップ 3: ゲートウェイとゲートウェイルーティングルールをデプロイする

このステップでは、ポート 8080 と 8081 でリッスンするゲートウェイを作成できます。ポート 8081 では、HTTPRoute リソースが推論拡張機能によって提供される InferencePool をバックエンドとして指定します。推論リクエストは、InferencePool で定義された Pod コレクションにルーティングされます。ポート 8080 では、別の HTTPRoute リソースがサービスをバックエンドとして指定します。推論リクエストは、標準の HTTP 最小リクエスト負荷分散ポリシーを使用して同じ Pod コレクションにルーティングされます。

  1. 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
  2. ゲートウェイをデプロイします。

    kubectl apply -f inference-gateway.yaml

ステップ 4: ルーティングルールを検証する

  1. 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.txt

    round2.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
  2. ゲートウェイのパブリック IP アドレスを取得します。

    export GATEWAY_IP=$(kubectl get gateway/qwen-inference-gateway -o jsonpath='{.status.addresses[0].value}')
  3. 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
  4. ログをチェックして、推定モードでのプレフィックスキャッシュ対応ルーティングが機能していることを確認します。

    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 ルーティングのパフォーマンスと、プレフィックスキャッシュ対応の推論ルーティングのパフォーマンスを比較することです。

  1. 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
  2. ゲートウェイの内部 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}')
  3. ストレステストを実行します。

    重要

    以下の結果はテスト環境のものです。実際の結果は異なる場合があります。

    標準 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 ルーティングよりも大幅に低いことを示しています。