推論拡張機能付きゲートウェイ コンポーネントを使用すると、生成 AI 推論サービスで、基盤モデルの置き換え、更新、または複数の Low-Rank Adaptation(LoRA)モデルのカナリア更新を実装できます。これにより、サービス中断時間が最小限に抑えられます。このトピックでは、推論拡張機能付きゲートウェイ コンポーネントを使用して、生成 AI 推論サービスのカナリアリリースを実装する方法について説明します。
このトピックを読む前に、InferencePool と InferenceModel の概念を理解していることを確認してください。
前提条件
GPU ノードプールを持つ ACK マネージドクラスター が作成されていること。また、ACS GPU 計算能力を使用するために、ACK マネージドクラスターに ACK Virtual Node コンポーネントをインストールすることもできます。
推論拡張機能付きゲートウェイ がインストールされており、クラスターの作成時に [ゲートウェイ API 推論拡張を有効にする] が選択されている。詳細については、「手順 2:推論拡張機能付きゲートウェイ コンポーネントをインストールする」をご参照ください。
準備
推論サービスの段階的なカナリアリリースを実行する前に、モデルをデプロイして検証する必要があります。
Qwen-2.5-7B-Instruct モデルから推論サービスをデプロイします。
InferencePool と InferenceModel をデプロイします。
kubectl apply -f- <<EOF apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferencePool metadata: name: mymodel-pool-v1 namespace: default spec: extensionRef: group: "" kind: Service name: mymodel-v1-ext-proc selector: app: custom-serving release: qwen targetPortNumber: 8000 --- apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceModel metadata: name: mymodel-v1 spec: criticality: Critical modelName: mymodel poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: mymodel-pool-v1 targetModels: - name: mymodel weight: 100 EOF
ゲートウェイをデプロイし、ゲートウェイルーティングルールを構成します。
kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: inference-gateway spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: inference-gateway spec: gatewayClassName: inference-gateway listeners: - name: llm-gw protocol: HTTP port: 8080 --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: inference-route spec: parentRefs: - group: gateway.networking.k8s.io kind: Gateway name: inference-gateway sectionName: llm-gw rules: - backendRefs: - group: inference.networking.x-k8s.io kind: InferencePool name: mymodel-pool-v1 weight: 1 matches: - path: type: PathPrefix value: /v1/completions - path: type: PathPrefix value: /v1/chat/completions --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: name: client-buffer-limit spec: connection: bufferLimit: 20Mi targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: inference-gateway --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: BackendTrafficPolicy metadata: name: backend-timeout spec: timeout: http: requestTimeout: 24h targetRef: group: gateway.networking.k8s.io kind: Gateway name: inference-gateway EOF
ゲートウェイの IP アドレスを取得します。
export GATEWAY_IP=$(kubectl get gateway/inference-gateway -o jsonpath='{.status.addresses[0].value}')
推論サービスを確認します。
curl -X POST ${GATEWAY_IP}:8080/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "mymodel", "temperature": 0, "messages": [ { "role": "user", "content": "Who are you?" } ] }'
期待される出力:
期待される出力は、推論拡張機能付きゲートウェイ を使用して、推論サービスが外部に正常にサービスを提供していることを示しています。
シナリオ 1:InferencePool の更新によるインフラストラクチャと基盤モデルのカナリアリリース
実際のシナリオでは、InferencePool を更新することで、モデルサービスのカナリアリリースを実装できます。たとえば、同じ InferenceModel 定義とモデル名を持ち、異なる計算構成、GPU ノード、または基盤モデルで実行される 2 つの InferencePool を構成できます。次のシナリオが適しています。
インフラストラクチャのカナリア更新:新しい InferencePool を作成し、新しい GPU ノードタイプまたは新しいモデル構成を使用し、カナリアリリースを通じてワークロードを徐々に移行します。推論リクエストトラフィックを中断することなく、ノード ハードウェアのアップグレード、ドライバーの更新、またはセキュリティ問題の解決を完了します。
基盤モデルのカナリア更新:新しい InferencePool を作成し、新しいモデルアーキテクチャまたは微調整されたモデルの重みをロードし、カナリアリリースを通じて新しい推論モデルを徐々に公開して、推論サービスのパフォーマンスを向上させたり、基盤モデル関連の問題を解決したりします。
次の図は、カナリアリリースの手順を示しています。
新しい基盤モデル用に新しい InferencePool を作成し、HTTPRoute を構成して異なる InferencePool 間にトラフィック比率を割り当てることにより、トラフィックを新しい InferencePool によって表される新しい推論サービスに徐々に移行できます。このようにして、基盤モデルを中断することなく更新できます。次の手順では、デプロイ済みの Qwen-2.5-7B-Instruct 基盤モデルサービスを DeepSeek-R1-Distill-Qwen-7B に徐々に更新する方法について説明します。 HTTPRoute のトラフィック比率を更新することで、基盤モデルの完全な切り替えを体験できます。
DeepSeek-R1-Distill-Qwen-7B 基盤モデルに基づいて推論サービスをデプロイします。
新しい推論サービス用に InferencePool と InferenceModel を構成します。 InferencePool
mymodel-pool-v2
は、新しいラベルを通じて DeepSeek-R1-Distill-Qwen-7B 基盤モデルに基づく推論サービスを選択し、同じモデル名mymodel
を持つ InferenceModel を宣言します。kubectl apply -f- <<EOF apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferencePool metadata: name: mymodel-pool-v2 namespace: default spec: extensionRef: group: "" kind: Service name: mymodel-v2-ext-proc selector: app: custom-serving release: deepseek-r1 targetPortNumber: 8000 --- apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceModel metadata: name: mymodel-v2 spec: criticality: Critical modelName: mymodel poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: mymodel-pool-v2 targetModels: - name: mymodel weight: 100 EOF
トラフィックカナリア戦略を構成します。
既存の InferencePool(
mymodel-pool-v1
)と新しい InferencePool(mymodel-pool-v2
)の間にトラフィックを分散するように HTTPRoute を構成します。backendRefs
weight フィールドは、各 InferencePool に割り当てられるトラフィックの割合を制御します。次の例では、モデルのトラフィックの重みを 9:1 に構成しています。これは、トラフィックの 10% がmymodel-pool-v2
に対応する DeepSeek-R1-Distill-Qwen-7B 基盤サービスに転送されることを示しています。kubectl apply -f- <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: inference-route spec: parentRefs: - group: gateway.networking.k8s.io kind: Gateway name: inference-gateway sectionName: llm-gw rules: - backendRefs: - group: inference.networking.x-k8s.io kind: InferencePool name: mymodel-pool-v1 port: 8000 weight: 90 - group: inference.networking.x-k8s.io kind: InferencePool name: mymodel-pool-v2 weight: 10 matches: - path: type: PathPrefix value: / EOF
カナリアリリースを確認します。
次のコマンドを繰り返し実行して、モデル出力を通じて基盤モデルのカナリア効果を確認します。
curl -X POST ${GATEWAY_IP}:8080/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "mymodel", "temperature": 0, "messages": [ { "role": "user", "content": "Who are you?" } ] }'
ほとんどのリクエストで期待される出力:
{"id":"chatcmpl-6bd37f84-55e0-4278-8f16-7b7bf04c6513","object":"chat.completion","created":1744364930,"model":"mymodel","choices":[{"index":0,"message":{"role":"assistant","reasoning_content":null,"content":"I am Qwen, a large language model created by Alibaba Cloud. I am designed to assist with a wide range of tasks, from answering questions and providing information to helping with creative projects and more. How can I assist you today?","tool_calls":[]},"logprobs":null,"finish_reason":"stop","stop_reason":null}],"usage":{"prompt_tokens":32,"total_tokens":74,"completion_tokens":42,"prompt_tokens_details":null},"prompt_logprobs":null}
約 10% のリクエストで期待される出力:
{"id":"chatcmpl-9e3cda6e-b284-43a9-9625-2e8fcd1fe0c7","object":"chat.completion","created":1744601333,"model":"mymodel","choices":[{"index":0,"message":{"role":"assistant","reasoning_content":null,"content":"Hello! I'm an AI assistant created by DeepSeek, here to help with information, answer questions, and provide suggestions. I can assist you with learning, advice, or even just casual conversation. How can I help you today?","tool_calls":[]},"logprobs":null,"finish_reason":"stop","stop_reason":null}],"usage":{"prompt_tokens":8,"total_tokens":81,"completion_tokens":73,"prompt_tokens_details":null},"prompt_logprobs":null}
ご覧のとおり、ほとんどの推論リクエストは引き続き古い Qwen-2.5-7B-Instruct 基盤モデルによって処理され、少数のリクエストは新しい DeepSeek-R1-Distill-Qwen-7B 基盤モデルによって処理されます。
シナリオ 2:InferenceModel の構成による LoRA モデルのカナリアリリース
Multi-LoRA シナリオでは、推論拡張機能付きゲートウェイ を使用すると、同じ基盤大規模モデルに複数のバージョンの LoRA モデルを同時にデプロイできます。カナリアテスト用にトラフィックを柔軟に割り当て、各バージョンのパフォーマンスの最適化、バグ修正、または機能の反復に対する効果を確認できます。
次の例では、Qwen-2.5-7B-Instruct から微調整された 2 つの LoRA バージョンを使用して、InferenceModel を使用して LoRA モデルのカナリアリリースを実装する方法を示します。
LoRA モデルのカナリアリリースの前に、LoRA モデルの新しいバージョンから推論サービスがデプロイされていることを確認してください。この例では、基本サービスには 2 つの LoRA モデルtravel-helper-v1
とtravel-helper-v2
が事前にマウントされています。
InferenceModel の異なる LoRA モデル間のトラフィック比率を更新することで、新しいバージョンの LoRA モデルのトラフィックの重みを徐々に増やし、トラフィックを中断することなく新しい LoRA モデルに徐々に更新できます。
InferenceModel 構成をデプロイし、複数のバージョンの LoRA モデルを定義し、LoRA モデル間のトラフィック比率を指定します。構成後、travelhelper モデルをリクエストすると、バックエンドの異なるバージョンの LoRA モデル間のトラフィック比率は、この例では 90:10 に設定されます。つまり、トラフィックの 90% は
travel-helper-v1
モデルに送られ、10% はtravel-helper-v2
モデルに送られます。kubectl apply -f- <<EOF apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceModel metadata: name: loramodel spec: criticality: Critical modelName: travelhelper poolRef: group: inference.networking.x-k8s.io kind: InferencePool name: mymodel-pool-v1 targetModels: - name: travel-helper-v1 weight: 90 - name: travel-helper-v2 weight: 10 EOF
カナリア効果を確認します。
次のコマンドを繰り返し実行して、モデル出力を通じて LoRA モデルのカナリア効果を確認します。
curl -X POST ${GATEWAY_IP}:8080/v1/chat/completions -H 'Content-Type: application/json' -d '{ "model": "travelhelper", "temperature": 0, "messages": [ { "role": "user", "content": "I just arrived in Beijing, please recommend a tourist attraction" } ] }'
ほとんどのリクエストで期待される出力:
{"id":"chatcmpl-2343f2ec-b03f-4882-a601-aca9e88d45ef","object":"chat.completion","created":1744602234,"model":"travel-helper-v1","choices":[{"index":0,"message":{"role":"assistant","reasoning_content":null,"content":"Sure, I'd be happy to recommend a place for you. If you're new to Beijing and want to experience its rich history and culture, I highly suggest visiting the Forbidden City (also known as the Palace Museum). It's one of the most iconic landmarks in Beijing and was once the home of emperors during the Ming and Qing dynasties. The architecture is magnificent and it houses an extensive collection of ancient Chinese art and artifacts. You'll definitely get a sense of China's imperial past by visiting there. Enjoy your trip!","tool_calls":[]},"logprobs":null,"finish_reason":"stop","stop_reason":null}],"usage":{"prompt_tokens":38,"total_tokens":288,"completion_tokens":250,"prompt_tokens_details":null},"prompt_logprobs":null}
約 10% のリクエストで期待される出力:
{"id":"chatcmpl-c6df57e9-ff95-41d6-8b35-19978f40525f","object":"chat.completion","created":1744602223,"model":"travel-helper-v2","choices":[{"index":0,"message":{"role":"assistant","reasoning_content":null,"content":"Welcome to Beijing! One of the must-visit attractions in Beijing is the Forbidden City, also known as the Imperial Palace. It was the imperial court of the Ming and Qing dynasties and is one of the largest and best-preserved ancient palaces in the world. The architecture, history, and cultural significance make it a fantastic place to explore. I recommend visiting early in the morning to avoid the crowds, and make sure to book your tickets in advance, especially during peak seasons. Enjoy your trip!","tool_calls":[]},"logprobs":null,"finish_reason":"stop","stop_reason":null}],"usage":{"prompt_tokens":38,"total_tokens":244,"completion_tokens":206,"prompt_tokens_details":null},"prompt_logprobs":null}
ご覧のとおり、ほとんどの推論リクエストは
travel-helper-v1
LoRA モデルによって処理され、少数のリクエストはtravel-helper-v2
LoRA モデルによって処理されます。