GKE Inference Gateway の構成をカスタマイズする


このページでは、GKE Inference Gateway のデプロイをカスタマイズする方法について説明します。

このページは、GKE インフラストラクチャの管理を担当するネットワーク スペシャリストと、AI ワークロードを管理するプラットフォーム管理者を対象としています。

推論ワークロードを管理して最適化するには、GKE Inference Gateway の高度な機能を構成します。

次の高度な機能について理解し、構成してください。

AI セキュリティと安全性チェックを構成する

GKE Inference Gateway は Model Armor と統合されており、大規模言語モデル(LLM)を使用するアプリケーションのプロンプトとレスポンスを安全性チェックします。この統合により、アプリケーション レベルの安全対策を補完する、インフラストラクチャ レベルの安全性強化レイヤが追加されます。これにより、すべての LLM トラフィックにポリシーを一元的に適用できます。

次の図は、GKE クラスタの GKE Inference Gateway と Model Armor の統合を示したものです。

GKE クラスタ上での Google Cloud Model Armor の統合
図: GKE クラスタ上での Model Armor の統合

AI 安全性チェックを構成する手順は次のとおりです。

  1. 次の前提条件を満たしていることを確認します。

    1. Trusted Cloud by S3NS プロジェクトで Model Armor サービスを有効にします
    2. Model Armor コンソール、Google Cloud CLI、または API を使用して Model Armor テンプレートを作成します。
  2. my-model-armor-template-name-id という名前の Model Armor テンプレートが作成されていることを確認します。

  3. GCPTrafficExtension を構成する手順は次のとおりです。

    1. 次のサンプル マニフェストを gcp-traffic-extension.yaml として保存します。

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-model-armor-extension
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: my-model-armor-chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.startsWith("/")
          extensions:
          - name: my-model-armor-service
            supportedEvents:
            - RequestHeaders
            timeout: 1s
            googleAPIServiceName: "modelarmor.us-central1.rep.googleapis.com"
            metadata:
              'extensionPolicy': MODEL_ARMOR_TEMPLATE_NAME
              'sanitizeUserPrompt': 'true'
              'sanitizeUserResponse': 'true'
      

      次のように置き換えます。

      • GATEWAY_NAME: Gatewayの名前
      • MODEL_ARMOR_TEMPLATE_NAME: Model Armor テンプレートの名前。

      gcp-traffic-extension.yaml ファイルには次の設定が含まれます。

      • targetRefs: この拡張機能が適用される Gateway を指定します。
      • extensionChains: トラフィックに適用する一連の拡張機能を定義します。
      • matchCondition: 拡張機能が適用される条件を定義します。
      • extensions: 適用する拡張機能を定義します。
      • supportedEvents: 拡張機能が呼び出されるイベントを指定します。
      • timeout: 拡張機能のタイムアウトを指定します。
      • googleAPIServiceName: 拡張機能のサービス名を指定します。
      • metadata: extensionPolicy やプロンプトまたはレスポンスのサニタイズ設定など、拡張機能のメタデータを指定します。
    2. マニフェストをクラスタに適用します。

      kubectl apply -f `gcp-traffic-extension.yaml`
      

AI 安全性チェックを構成して Gateway と統合すると、Model Armor は定義されたルールに基づいてプロンプトとレスポンスを自動的にフィルタします。

オブザーバビリティを構成する

GKE Inference Gateway は、推論ワークロードの健全性、パフォーマンス、動作に関する分析情報を提供します。これは、問題を特定して解決し、リソース使用率を最適化し、アプリケーションの信頼性を保証する上で役立ちます。

Trusted Cloud by S3NS では、GKE Inference Gateway の推論オブザーバビリティを提供する次の Cloud Monitoring ダッシュボードをご覧いただけます。

  • GKE Inference Gateway ダッシュボード: LLM 処理に関するゴールデン指標(InferencePool に対するリクエストとトークンのスループット、レイテンシ、エラー、キャッシュ使用率など)を確認できます。使用可能な GKE Inference Gateway の指標の一覧については、公開されている指標をご覧ください。
  • モデルサーバー ダッシュボード: モデルサーバーのゴールデン シグナルのダッシュボードです。このダッシュボードでは、KVCache UtilizationQueue length などのモデルサーバーの負荷とパフォーマンスをモニタリングできます。このダッシュボードでは、モデルサーバーの負荷とパフォーマンスをモニタリングできます。
  • ロードバランサ ダッシュボード: ロードバランサの指標(1 秒あたりのリクエスト数、エンド ツー エンドのリクエスト処理レイテンシ、リクエスト / レスポンスのステータス コードなど)をレポートします。これらの指標は、エンド ツー エンドのリクエスト処理のパフォーマンスを把握し、エラーを特定するのに役立ちます。
  • Data Center GPU Manager(DCGM)指標: NVIDIA GPU のパフォーマンスや使用率など、NVIDIA GPU の指標を確認できます。NVIDIA Data Center GPU Manager(DCGM)指標は、Cloud Monitoring で構成できます。詳細については、DCGM 指標を収集して表示するをご覧ください。

GKE Inference Gateway ダッシュボードを表示する

GKE Inference Gateway ダッシュボードを表示する手順は次のとおりです。

  1. Trusted Cloud コンソールで、[モニタリング] ページに移動します。

    [モニタリング] に移動

  2. ナビゲーション パネルで [ダッシュボード] を選択します。

  3. [統合] セクションで [GMP] を選択します。

  4. [Cloud Monitoring ダッシュボード テンプレート] ページで、[ゲートウェイ] を検索します。

  5. GKE Inference Gateway ダッシュボードを表示します。

または、モニタリング ダッシュボードの手順に沿って操作することもできます。

モデルサーバーのオブザーバビリティ ダッシュボードを構成する

各モデルサーバーからゴールデン シグナルを収集し、GKE Inference Gateway のパフォーマンスに影響を与えている要因を把握するには、モデルサーバーの自動モニタリングを構成します。これには、次のようなモデルサーバーが含まれます。

統合ダッシュボードを表示する手順は次のとおりです。

  1. モデルサーバーから指標を収集します。
  2. Trusted Cloud コンソールで、[モニタリング] ページに移動します。

    [モニタリング] に移動

  3. ナビゲーション パネルで [ダッシュボード] を選択します。

  4. [統合] で [GMP] を選択します。該当する統合ダッシュボードが表示されます。

    統合ダッシュボードのビュー
    図: 統合ダッシュボード

詳細については、アプリケーションのモニタリングをカスタマイズするをご覧ください。

Cloud Monitoring アラートを構成する

GKE Inference Gateway の Cloud Monitoring アラートを構成する手順は次のとおりです。

  1. アラートのしきい値を変更します。次のサンプル マニフェストを alerts.yaml として保存します。

    groups:
    - name: gateway-api-inference-extension
      rules:
      - alert: HighInferenceRequestLatencyP99
        annotations:
          title: 'High latency (P99) for model {{ $labels.model_name }}'
          description: 'The 99th percentile request duration for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 10.0 seconds for 5 minutes.'
        expr: histogram_quantile(0.99, rate(inference_model_request_duration_seconds_bucket[5m])) > 10.0
        for: 5m
        labels:
          severity: 'warning'
      - alert: HighInferenceErrorRate
        annotations:
          title: 'High error rate for model {{ $labels.model_name }}'
          description: 'The error rate for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 5% for 5 minutes.'
        expr: sum by (model_name) (rate(inference_model_request_error_total[5m])) / sum by (model_name) (rate(inference_model_request_total[5m])) > 0.05
        for: 5m
        labels:
          severity: 'critical'
          impact: 'availability'
      - alert: HighInferencePoolAvgQueueSize
        annotations:
          title: 'High average queue size for inference pool {{ $labels.name }}'
          description: 'The average number of requests pending in the queue for inference pool {{ $labels.name }} has been consistently above 50 for 5 minutes.'
        expr: inference_pool_average_queue_size > 50
        for: 5m
        labels:
          severity: 'critical'
          impact: 'performance'
      - alert: HighInferencePoolAvgKVCacheUtilization
        annotations:
          title: 'High KV cache utilization for inference pool {{ $labels.name }}'
          description: 'The average KV cache utilization for inference pool {{ $labels.name }} has been consistently above 90% for 5 minutes, indicating potential resource exhaustion.'
        expr: inference_pool_average_kv_cache_utilization > 0.9
        for: 5m
        labels:
          severity: 'critical'
          impact: 'resource_exhaustion'
    
  2. アラート ポリシーを作成するには、次のコマンドを実行します。

    gcloud alpha monitoring policies migrate --policies-from-prometheus-alert-rules-yaml=alerts.yaml
    

    [アラート] ページに新しいアラート ポリシーが表示されます。

アラートを変更する

使用可能な最新の指標の完全なリストは、kubernetes-sigs/gateway-api-inference-extension GitHub リポジトリで確認できます。また、他の指標を使用して、新しいアラートをマニフェストに追加することもできます。

サンプル アラートを変更するには、次のアラートを例として使用します。

  - alert: HighInferenceRequestLatencyP99
    annotations:
      title: 'High latency (P99) for model {{ $labels.model_name }}'
      description: 'The 99th percentile request duration for model {{ $labels.model_name }} and target model {{ $labels.target_model_name }} has been consistently above 10.0 seconds for 5 minutes.'
    expr: histogram_quantile(0.99, rate(inference_model_request_duration_seconds_bucket[5m])) > 10.0
    for: 5m
    labels:
      severity: 'warning'

5 分間のリクエスト時間の 99 パーセンタイルが 10 秒を超えると、アラートが作動します。要件に合わせてしきい値を調整するために、アラートの expr セクションを変更できます。

GKE Inference Gateway のロギングを構成する

GKE Inference Gateway のロギングを構成して、リクエストとレスポンスの詳細情報を確認しましょう。これは、トラブルシューティング、監査、パフォーマンス分析に役立ちます。HTTP アクセス ログには、ヘッダー、ステータス コード、タイムスタンプなど、すべてのリクエストとレスポンスが記録されます。このレベルの詳細は、問題の特定、エラーの検出、推論ワークロードの動作の把握に役立ちます。

GKE Inference Gateway のロギングを構成するには、各 InferencePool オブジェクトの HTTP アクセス ロギングを有効にします。

  1. 次のサンプル マニフェストを logging-backend-policy.yaml として保存します。

    apiVersion: networking.gke.io/v1
    kind: GCPBackendPolicy
    metadata:
      name: logging-backend-policy
      namespace: NAMESPACE_NAME
    spec:
      default:
        logging:
          enabled: true
          sampleRate: 500000
      targetRef:
        group: inference.networking.x-k8s.io
        kind: InferencePool
        name: INFERENCE_POOL_NAME
    

    次のように置き換えます。

    • NAMESPACE_NAME: InferencePool がデプロイされる名前空間の名前。
    • INFERENCE_POOL_NAME: InferencePool の名前。
  2. マニフェストをクラスタに適用します。

    kubectl apply -f logging-backend-policy.yaml
    

このマニフェストを適用すると、GKE Inference Gateway は指定された InferencePool の HTTP アクセスログを有効にします。これらのログは Cloud Logging で確認できます。ログでは、各リクエストとレスポンスの詳細情報、例えば、リクエスト URL、ヘッダー、レスポンス ステータス コード、レイテンシなどを確認できます。

自動スケーリングを構成する

自動スケーリングは、ワークロードの変化に応じてリソース割り当てを調整し、また需要に応じて Pod を動的に追加または削除してパフォーマンスとリソース効率を維持します。GKE Inference Gateway の場合、これは各 InferencePool の Pod の水平自動スケーリングを伴います。GKE Horizontal Pod Autoscaler(HPA)は、KVCache Utilization などのモデルサーバー 指標に基づいて Pod を自動スケーリングします。これにより、推論サービスはリソース使用量を効率的に管理しながら、さまざまなワークロードとクエリ量を処理できます。

GKE Inference Gateway によって生成された指標に基づいて自動スケーリングされるように InferencePool インスタンスを構成するには、次の操作を行います。

  1. クラスタに PodMonitoring オブジェクトをデプロイして、GKE Inference Gateway によって生成された指標を収集します。詳細については、オブザーバビリティを構成するをご覧ください。

  2. Custom Metrics Stackdriver Adapterをデプロイして、HPA に指標へのアクセス権を付与します。

    1. 次のサンプル マニフェストを adapter_new_resource_model.yaml として保存します。

      apiVersion: v1
      kind: Namespace
      metadata:
        name: custom-metrics
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: custom-metrics:system:auth-delegator
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: system:auth-delegator
      subjects:
      - kind: ServiceAccount
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: custom-metrics-auth-reader
        namespace: kube-system
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: extension-apiserver-authentication-reader
      subjects:
      - kind: ServiceAccount
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: custom-metrics-resource-reader
        namespace: custom-metrics
      rules:
      - apiGroups:
        - ""
        resources:
        - pods
        - nodes
        - nodes/stats
        verbs:
        - get
        - list
        - watch
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: custom-metrics-resource-reader
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: custom-metrics-resource-reader
      subjects:
      - kind: ServiceAccount
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        run: custom-metrics-stackdriver-adapter
        k8s-app: custom-metrics-stackdriver-adapter
      spec:
        replicas: 1
        selector:
          matchLabels:
            run: custom-metrics-stackdriver-adapter
            k8s-app: custom-metrics-stackdriver-adapter
        template:
          metadata:
            labels:
              run: custom-metrics-stackdriver-adapter
              k8s-app: custom-metrics-stackdriver-adapter
              kubernetes.io/cluster-service: "true"
          spec:
            serviceAccountName: custom-metrics-stackdriver-adapter
            containers:
            - image: gcr.io/gke-release/custom-metrics-stackdriver-adapter:v0.15.2-gke.1
              imagePullPolicy: Always
              name: pod-custom-metrics-stackdriver-adapter
              command:
              - /adapter
              - --use-new-resource-model=true
              - --fallback-for-container-metrics=true
              resources:
                limits:
                  cpu: 250m
                  memory: 200Mi
                requests:
                  cpu: 250m
                  memory: 200Mi
      ---
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          run: custom-metrics-stackdriver-adapter
          k8s-app: custom-metrics-stackdriver-adapter
          kubernetes.io/cluster-service: 'true'
          kubernetes.io/name: Adapter
        name: custom-metrics-stackdriver-adapter
        namespace: custom-metrics
      spec:
        ports:
        - port: 443
          protocol: TCP
          targetPort: 443
        selector:
          run: custom-metrics-stackdriver-adapter
          k8s-app: custom-metrics-stackdriver-adapter
        type: ClusterIP
      ---
      apiVersion: apiregistration.k8s.io/v1
      kind: APIService
      metadata:
        name: v1beta1.custom.metrics.k8s.io
      spec:
        insecureSkipTLSVerify: true
        group: custom.metrics.k8s.io
        groupPriorityMinimum: 100
        versionPriority: 100
        service:
          name: custom-metrics-stackdriver-adapter
          namespace: custom-metrics
        version: v1beta1
      ---
      apiVersion: apiregistration.k8s.io/v1
      kind: APIService
      metadata:
        name: v1beta2.custom.metrics.k8s.io
      spec:
        insecureSkipTLSVerify: true
        group: custom.metrics.k8s.io
        groupPriorityMinimum: 100
        versionPriority: 200
        service:
          name: custom-metrics-stackdriver-adapter
          namespace: custom-metrics
        version: v1beta2
      ---
      apiVersion: apiregistration.k8s.io/v1
      kind: APIService
      metadata:
        name: v1beta1.external.metrics.k8s.io
      spec:
        insecureSkipTLSVerify: true
        group: external.metrics.k8s.io
        groupPriorityMinimum: 100
        versionPriority: 100
        service:
          name: custom-metrics-stackdriver-adapter
          namespace: custom-metrics
        version: v1beta1
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: external-metrics-reader
      rules:
      - apiGroups:
        - "external.metrics.k8s.io"
        resources:
        - "*"
        verbs:
        - list
        - get
        - watch
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: external-metrics-reader
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: external-metrics-reader
      subjects:
      - kind: ServiceAccount
        name: horizontal-pod-autoscaler
        namespace: kube-system
      
    2. マニフェストをクラスタに適用します。

      kubectl apply -f adapter_new_resource_model.yaml
      
  3. プロジェクトから指標を読み取る権限をアダプターに付与するには、次のコマンドを実行します。

    $ PROJECT_ID=PROJECT_ID
    $ PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)")
    $ gcloud projects add-iam-policy-binding projects/PROJECT_ID \
      --role roles/monitoring.viewer \
      --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/$PROJECT_ID.svc.id.goog/subject/ns/custom-metrics/sa/custom-metrics-stackdriver-adapter
    

    PROJECT_ID は、実際の Trusted Cloud PROJECT_ID に置き換えます。

  4. InferencePool ごとに、次のような HPA を 1 つデプロイします。

    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: INFERENCE_POOL_NAME
      namespace: INFERENCE_POOL_NAMESPACE
    spec:
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: INFERENCE_POOL_NAME
      minReplicas: MIN_REPLICAS
      maxReplicas: MAX_REPLICAS
      metrics:
      - type: External
        external:
          metric:
            name: prometheus.googleapis.com|inference_pool_average_kv_cache_utilization|gauge
            selector:
              matchLabels:
                metric.labels.name: INFERENCE_POOL_NAME
                resource.labels.cluster: CLUSTER_NAME
                resource.labels.namespace: INFERENCE_POOL_NAMESPACE
          target:
            type: AverageValue
            averageValue: TARGET_VALUE
    

    次のように置き換えます。

    • INFERENCE_POOL_NAME: InferencePool の名前。
    • INFERENCE_POOL_NAMESPACE: InferencePool の名前空間。
    • CLUSTER_NAME: クラスタの名前。
    • MIN_REPLICAS: InferencePool の最小可用性(ベースライン容量)。使用率が HPA ターゲットしきい値を下回っている場合、HPA はこのレプリカ数を維持します。高可用性ワークロードでは、Pod の中断中に可用性を維持するために、この値を 1 より大きい値に設定する必要があります。
    • MAX_REPLICAS: InferencePool でホストされているワークロードに割り当てる必要があるアクセラレータの数を制限する値。HPA は、この値を超えてレプリカ数を増やしません。トラフィックのピーク時にレプリカ数をモニタリングし、MAX_REPLICAS フィールドの値に十分なヘッドルームがあることを確認しておくことで、ワークロードをスケールアップして選択したワークロードのパフォーマンス特性を維持できるようにしておきましょう。
    • TARGET_VALUE: モデルサーバーごとに選択されたターゲット KV-Cache Utilization を表す値。これは 0 ~ 100 の数値で、モデルサーバー、モデル、アクセラレータ、受信トラフィックの特性に大きく依存します。このターゲット値は、負荷テストを実施してスループットとレイテンシのグラフをプロットすることで、実験的に決定できます。グラフから選択したスループットとレイテンシの組み合わせを選択し、対応する KV-Cache Utilization 値を HPA ターゲットとして使用します。選択した価格-パフォーマンス関係を達成するには、この値を微調整して注意深くモニタリングする必要があります。GKE Inference Recommendationsをご利用いただくと、この値を自動的に決定できます。

次のステップ