このチュートリアルでは、GKE 推論 Gateway を使用して Google Kubernetes Engine(GKE)に大規模言語モデル(LLM)をデプロイする方法について説明します。このチュートリアルでは、クラスタの設定、モデルのデプロイ、GKE Inference Gateway の構成、LLM リクエストの処理の手順について説明します。
このチュートリアルは、GKE Inference Gateway を使用して GKE で LLM を使用して LLM アプリケーションをデプロイおよび管理する機械学習(ML)エンジニア、プラットフォーム管理者とオペレーター、データおよび AI のスペシャリストを対象としています。
このページを読む前に、次の内容を理解しておいてください。
- GKE でのモデル推論について
- GKE Inference Quickstart レシピを使用してベスト プラクティスの推論を実行する
- Autopilot モードと Standard モード
- GKE の GPU
背景
このセクションでは、このチュートリアルで使用されている重要なテクノロジーについて説明します。モデル サービングのコンセプトと用語、GKE の生成 AI 機能を使用してモデル サービングのパフォーマンスを強化してサポートする方法の詳細については、GKE でのモデル推論についてをご覧ください。
vLLM
vLLM は、GPU のサービング スループットを向上させる、高度に最適化されたオープンソースの LLM サービング フレームワークであり、次のような機能を備えています。
- PagedAttention による Transformer の実装の最適化
- サービング スループットを全体的に向上させる連続的なバッチ処理
- 複数の GPU でのテンソル並列処理と分散サービング
詳細については、vLLM のドキュメントをご覧ください。
GKE Inference Gateway
GKE Inference Gateway は、LLM を提供する GKE の機能を強化します。推論ワークロードを最適化するために、次のような機能を使用します。
- 負荷指標に基づく推論最適化ロード バランシング。
- LoRA アダプタの密なマルチワークロード サービングをサポート。
- モデル対応ルーティングによるオペレーションの簡素化。
詳細については、GKE 推論 Gateway についてをご覧ください。
目標
始める前に
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the required API.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the required API.
-
Make sure that you have the following role or roles on the project: roles/container.admin, roles/iam.serviceAccountAdmin
Check for the roles
-
In the Google Cloud console, go to the IAM page.
Go to IAM - Select the project.
-
In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.
- For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.
Grant the roles
-
In the Google Cloud console, go to the IAM page.
[IAM] に移動 - プロジェクトを選択します。
- [ アクセスを許可] をクリックします。
-
[新しいプリンシパル] フィールドに、ユーザー ID を入力します。 これは通常、Google アカウントのメールアドレスです。
- [ロールを選択] リストでロールを選択します。
- 追加のロールを付与するには、 [別のロールを追加] をクリックして各ロールを追加します。
- [保存] をクリックします。
-
- Hugging Face アカウントを作成します(まだ作成していない場合)。
- プロジェクトに、H100 GPU に対する十分な割り当てがあることを確認します。詳細については、GPU 割り当てを計画すると割り当てをご覧ください。
モデルへのアクセス権を取得する
Llama3.1
モデルを GKE にデプロイするには、ライセンス同意契約に署名し、Hugging Face アクセス トークンを生成します。
ライセンス同意契約に署名する
Llama3.1
モデルを使用するには、同意契約に署名する必要があります。手順は次のとおりです。
- 同意ページにアクセスし、Hugging Face アカウントの使用に対する同意を確認します。
- モデルの規約に同意します。
アクセス トークンを生成する
Hugging Face からモデルにアクセスするには、Hugging Face トークンが必要です。
トークンをまだ生成していない場合は、次の手順に沿って生成します。
- [Your Profile] > [Settings] > [Access Tokens] の順にクリックします。
- [New Token] を選択します。
- 任意の名前と、少なくとも
Read
ロールを指定します。 - [Generate a token] を選択します。
- トークンをクリップボードにコピーします。
環境を準備する
このチュートリアルでは、Cloud Shell を使用してGoogle Cloudでホストされているリソースを管理します。Cloud Shell には、このチュートリアルに必要な kubectl
や
gcloud CLI などのソフトウェアがプリインストールされています。
Cloud Shell を使用して環境を設定するには、次の操作を行います。
Google Cloud コンソールで、Google Cloud コンソールの
[Cloud Shell をアクティブにする] をクリックして、Cloud Shell セッションを起動します。これにより、 Google Cloud コンソールの下部ペインでセッションが起動されます。
デフォルトの環境変数を設定します。
gcloud config set project PROJECT_ID export PROJECT_ID=$(gcloud config get project) export REGION=REGION export CLUSTER_NAME=CLUSTER_NAME export HF_TOKEN=HF_TOKEN
次の値を置き換えます。
PROJECT_ID
: Google Cloudのプロジェクト ID。REGION
: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、H100 GPU の場合はus-central1
)。CLUSTER_NAME
: クラスタの名前。HF_TOKEN
: 先ほど生成した Hugging Face トークン。
Google Cloud リソースを作成して構成する
必要なリソースを作成するには、次の手順を使用します。
GKE クラスタとノードプールを作成する
GKE Autopilot クラスタまたは GKE Standard クラスタの GPU で LLM を提供します。フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用することをおすすめします。ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。
Autopilot
Cloud Shell で、次のコマンドを実行します。
gcloud container clusters create-auto CLUSTER_NAME \
--project=PROJECT_ID \
--region=REGION \
--release-channel=rapid \
--cluster-version=1.32.3-gke.1170000
次の値を置き換えます。
PROJECT_ID
: Google Cloudのプロジェクト ID。REGION
: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、H100 GPU の場合はus-central1
)。CLUSTER_NAME
: クラスタの名前。
GKE は、デプロイされたワークロードからのリクエストに応じた CPU ノードと GPU ノードを持つ Autopilot クラスタを作成します。
Standard
Cloud Shell で、次のコマンドを実行して Standard クラスタを作成します。
gcloud container clusters create CLUSTER_NAME \ --project=PROJECT_ID \ --region=REGION \ --workload-pool=PROJECT_ID.svc.id.goog \ --release-channel=rapid \ --num-nodes=1 \ --enable-managed-prometheus \ --monitoring=SYSTEM,DCGM \ --cluster-version=1.32.3-gke.1170000
次の値を置き換えます。
PROJECT_ID
: Google Cloudのプロジェクト ID。REGION
: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、H100 GPU の場合はus-central1
)。CLUSTER_NAME
: クラスタの名前。
クラスタの作成には数分かかることもあります。
Llama-3.1-8B-Instruct
モデルの実行に適したディスクサイズのノードプールを作成するには、次のコマンドを実行します。gcloud container node-pools create gpupool \ --accelerator type=nvidia-h100-80gb,count=2,gpu-driver-version=latest \ --project=PROJECT_ID \ --location=REGION \ --node-locations=REGION-a \ --cluster=CLUSTER_NAME \ --machine-type=a3-highgpu-2g \ --num-nodes=1 \ --disk-type="pd-standard"
GKE は、H100 GPU を含む単一のノードプールを作成します。
指標をスクレイピングするための認可を設定するには、
inference-gateway-sa-metrics-reader-secret
シークレットを作成します。kubectl apply -f - <<EOF --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: inference-gateway-metrics-reader rules: - nonResourceURLs: - /metrics verbs: - get --- apiVersion: v1 kind: ServiceAccount metadata: name: inference-gateway-sa-metrics-reader namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: inference-gateway-sa-metrics-reader-role-binding namespace: default subjects: - kind: ServiceAccount name: inference-gateway-sa-metrics-reader namespace: default roleRef: kind: ClusterRole name: inference-gateway-metrics-reader apiGroup: rbac.authorization.k8s.io --- apiVersion: v1 kind: Secret metadata: name: inference-gateway-sa-metrics-reader-secret namespace: default annotations: kubernetes.io/service-account.name: inference-gateway-sa-metrics-reader type: kubernetes.io/service-account-token --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: inference-gateway-sa-metrics-reader-secret-read rules: - resources: - secrets apiGroups: [""] verbs: ["get", "list", "watch"] resourceNames: ["inference-gateway-sa-metrics-reader-secret"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: gmp-system:collector:inference-gateway-sa-metrics-reader-secret-read namespace: default roleRef: name: inference-gateway-sa-metrics-reader-secret-read kind: ClusterRole apiGroup: rbac.authorization.k8s.io subjects: - name: collector namespace: gmp-system kind: ServiceAccount EOF
Hugging Face の認証情報用の Kubernetes Secret を作成する
Cloud Shell で、次の操作を行います。
クラスタと通信するには、
kubectl
を構成します。gcloud container clusters get-credentials CLUSTER_NAME \ --location=REGION
次の値を置き換えます。
REGION
: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、H100 GPU の場合はus-central1
)。CLUSTER_NAME
: クラスタの名前。
Hugging Face トークンを含む Kubernetes Secret を作成します。
kubectl create secret generic HF_SECRET \ --from-literal=token=HF_TOKEN \ --dry-run=client -o yaml | kubectl apply -f -
次のように置き換えます。
HF_TOKEN
: 先ほど生成した Hugging Face トークン。HF_SECRET
: Kubernetes Secret の名前。例:hf-secret
InferenceModel
CRD と InferencePool
CRD をインストールする
このセクションでは、GKE 推論 Gateway に必要なカスタム リソース定義(CRD)をインストールします。
CRD は Kubernetes API を拡張します。これにより、新しいリソースタイプを定義できます。GKE Inference Gateway を使用するには、次のコマンドを実行して、GKE クラスタに InferencePool
CRD と InferenceModel
CRD をインストールします。
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/v0.3.0/manifests.yaml
モデルサーバーをデプロイする
この例では、vLLM モデルサーバーを使用して Llama3.1
モデルをデプロイします。デプロイメントには app:vllm-llama3-8b-instruct
というラベルが付けられています。このデプロイでは、Hugging Face の food-review
と cad-fabricator
という 2 つの LoRA アダプターも使用します。このデプロイメントは、独自のモデルサーバー、モデルコンテナ、サービング ポート、デプロイ名で更新できます。必要に応じて、デプロイで LoRA アダプタを構成するか、ベースモデルをデプロイします。
nvidia-h100-80gb
アクセラレータ タイプにデプロイするには、次のマニフェストをvllm-llama3-8b-instruct.yaml
として保存します。このマニフェストでは、モデルとモデルサーバーを含む Kubernetes Deployment を定義します。apiVersion: apps/v1 kind: Deployment metadata: name: vllm-llama3-8b-instruct spec: replicas: 3 selector: matchLabels: app: vllm-llama3-8b-instruct template: metadata: labels: app: vllm-llama3-8b-instruct spec: containers: - name: vllm image: "vllm/vllm-openai:latest" imagePullPolicy: Always command: ["python3", "-m", "vllm.entrypoints.openai.api_server"] args: - "--model" - "meta-llama/Llama-3.1-8B-Instruct" - "--tensor-parallel-size" - "1" - "--port" - "8000" - "--enable-lora" - "--max-loras" - "2" - "--max-cpu-loras" - "12" env: # Enabling LoRA support temporarily disables automatic v1, we want to force it on # until 0.8.3 vLLM is released. - name: VLLM_USE_V1 value: "1" - name: PORT value: "8000" - name: HUGGING_FACE_HUB_TOKEN valueFrom: secretKeyRef: name: hf-token key: token - name: VLLM_ALLOW_RUNTIME_LORA_UPDATING value: "true" ports: - containerPort: 8000 name: http protocol: TCP lifecycle: preStop: # vLLM stops accepting connections when it receives SIGTERM, so we need to sleep # to give upstream gateways a chance to take us out of rotation. The time we wait # is dependent on the time it takes for all upstreams to completely remove us from # rotation. Older or simpler load balancers might take upwards of 30s, but we expect # our deployment to run behind a modern gateway like Envoy which is designed to # probe for readiness aggressively. sleep: # Upstream gateway probers for health should be set on a low period, such as 5s, # and the shorter we can tighten that bound the faster that we release # accelerators during controlled shutdowns. However, we should expect variance, # as load balancers may have internal delays, and we don't want to drop requests # normally, so we're often aiming to set this value to a p99 propagation latency # of readiness -> load balancer taking backend out of rotation, not the average. # # This value is generally stable and must often be experimentally determined on # for a given load balancer and health check period. We set the value here to # the highest value we observe on a supported load balancer, and we recommend # tuning this value down and verifying no requests are dropped. # # If this value is updated, be sure to update terminationGracePeriodSeconds. # seconds: 30 # # IMPORTANT: preStop.sleep is beta as of Kubernetes 1.30 - for older versions # replace with this exec action. #exec: # command: # - /usr/bin/sleep # - 30 livenessProbe: httpGet: path: /health port: http scheme: HTTP # vLLM's health check is simple, so we can more aggressively probe it. Liveness # check endpoints should always be suitable for aggressive probing. periodSeconds: 1 successThreshold: 1 # vLLM has a very simple health implementation, which means that any failure is # likely significant. However, any liveness triggered restart requires the very # large core model to be reloaded, and so we should bias towards ensuring the # server is definitely unhealthy vs immediately restarting. Use 5 attempts as # evidence of a serious problem. failureThreshold: 5 timeoutSeconds: 1 readinessProbe: httpGet: path: /health port: http scheme: HTTP # vLLM's health check is simple, so we can more aggressively probe it. Readiness # check endpoints should always be suitable for aggressive probing, but may be # slightly more expensive than readiness probes. periodSeconds: 1 successThreshold: 1 # vLLM has a very simple health implementation, which means that any failure is # likely significant, failureThreshold: 1 timeoutSeconds: 1 # We set a startup probe so that we don't begin directing traffic or checking # liveness to this instance until the model is loaded. startupProbe: # Failure threshold is when we believe startup will not happen at all, and is set # to the maximum possible time we believe loading a model will take. In our # default configuration we are downloading a model from HuggingFace, which may # take a long time, then the model must load into the accelerator. We choose # 10 minutes as a reasonable maximum startup time before giving up and attempting # to restart the pod. # # IMPORTANT: If the core model takes more than 10 minutes to load, pods will crash # loop forever. Be sure to set this appropriately. failureThreshold: 3600 # Set delay to start low so that if the base model changes to something smaller # or an optimization is deployed, we don't wait unnecessarily. initialDelaySeconds: 2 # As a startup probe, this stops running and so we can more aggressively probe # even a moderately complex startup - this is a very important workload. periodSeconds: 1 httpGet: # vLLM does not start the OpenAI server (and hence make /health available) # until models are loaded. This may not be true for all model servers. path: /health port: http scheme: HTTP resources: limits: nvidia.com/gpu: 1 requests: nvidia.com/gpu: 1 volumeMounts: - mountPath: /data name: data - mountPath: /dev/shm name: shm - name: adapters mountPath: "/adapters" initContainers: - name: lora-adapter-syncer tty: true stdin: true image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/lora-syncer:main restartPolicy: Always imagePullPolicy: Always env: - name: DYNAMIC_LORA_ROLLOUT_CONFIG value: "/config/configmap.yaml" volumeMounts: # DO NOT USE subPath, dynamic configmap updates don't work on subPaths - name: config-volume mountPath: /config restartPolicy: Always # vLLM allows VLLM_PORT to be specified as an environment variable, but a user might # create a 'vllm' service in their namespace. That auto-injects VLLM_PORT in docker # compatible form as `tcp://<IP>:<PORT>` instead of the numeric value vLLM accepts # causing CrashLoopBackoff. Set service environment injection off by default. enableServiceLinks: false # Generally, the termination grace period needs to last longer than the slowest request # we expect to serve plus any extra time spent waiting for load balancers to take the # model server out of rotation. # # An easy starting point is the p99 or max request latency measured for your workload, # although LLM request latencies vary significantly if clients send longer inputs or # trigger longer outputs. Since steady state p99 will be higher than the latency # to drain a server, you may wish to slightly this value either experimentally or # via the calculation below. # # For most models you can derive an upper bound for the maximum drain latency as # follows: # # 1. Identify the maximum context length the model was trained on, or the maximum # allowed length of output tokens configured on vLLM (llama2-7b was trained to # 4k context length, while llama3-8b was trained to 128k). # 2. Output tokens are the more compute intensive to calculate and the accelerator # will have a maximum concurrency (batch size) - the time per output token at # maximum batch with no prompt tokens being processed is the slowest an output # token can be generated (for this model it would be about 100ms TPOT at a max # batch size around 50) # 3. Calculate the worst case request duration if a request starts immediately # before the server stops accepting new connections - generally when it receives # SIGTERM (for this model that is about 4096 / 10 ~ 40s) # 4. If there are any requests generating prompt tokens that will delay when those # output tokens start, and prompt token generation is roughly 6x faster than # compute-bound output token generation, so add 20% to the time from above (40s + # 16s ~ 55s) # # Thus we think it will take us at worst about 55s to complete the longest possible # request the model is likely to receive at maximum concurrency (highest latency) # once requests stop being sent. # # NOTE: This number will be lower than steady state p99 latency since we stop receiving # new requests which require continuous prompt token computation. # NOTE: The max timeout for backend connections from gateway to model servers should # be configured based on steady state p99 latency, not drain p99 latency # # 5. Add the time the pod takes in its preStop hook to allow the load balancers have # stopped sending us new requests (55s + 30s ~ 85s) # # Because the termination grace period controls when the Kubelet forcibly terminates a # stuck or hung process (a possibility due to a GPU crash), there is operational safety # in keeping the value roughly proportional to the time to finish serving. There is also # value in adding a bit of extra time to deal with unexpectedly long workloads. # # 6. Add a 50% safety buffer to this time since the operational impact should be low # (85s * 1.5 ~ 130s) # # One additional source of drain latency is that some workloads may run close to # saturation and have queued requests on each server. Since traffic in excess of the # max sustainable QPS will result in timeouts as the queues grow, we assume that failure # to drain in time due to excess queues at the time of shutdown is an expected failure # mode of server overload. If your workload occasionally experiences high queue depths # due to periodic traffic, consider increasing the safety margin above to account for # time to drain queued requests. terminationGracePeriodSeconds: 130 nodeSelector: cloud.google.com/gke-accelerator: "nvidia-h100-80gb" volumes: - name: data emptyDir: {} - name: shm emptyDir: medium: Memory - name: adapters emptyDir: {} - name: config-volume configMap: name: vllm-llama3-8b-adapters --- apiVersion: v1 kind: ConfigMap metadata: name: vllm-llama3-8b-adapters data: configmap.yaml: | vLLMLoRAConfig: name: vllm-llama3.1-8b-instruct port: 8000 defaultBaseModel: meta-llama/Llama-3.1-8B-Instruct ensureExist: models: - id: food-review source: Kawon/llama3.1-food-finetune_v14_r8 - id: cad-fabricator source: redcathode/fabricator --- kind: HealthCheckPolicy apiVersion: networking.gke.io/v1 metadata: name: health-check-policy namespace: default spec: targetRef: group: "inference.networking.x-k8s.io" kind: InferencePool name: vllm-llama3-8b-instruct default: config: type: HTTP httpHealthCheck: requestPath: /health port: 8000
マニフェストをクラスタに適用します。
kubectl apply -f vllm-llama3-8b-instruct.yaml
InferencePool
リソースを作成する
InferencePool
Kubernetes カスタム リソースは、共通のベース LLM とコンピューティング構成を持つ Pod のグループを定義します。
InferencePool
カスタム リソースには、次のキーフィールドが含まれています。
selector
: このプールに属する Pod を指定します。このセレクタのラベルは、モデルサーバー Pod に適用されるラベルと完全に一致している必要があります。targetPort
: Pod 内のモデルサーバーで使用されるポートを定義します。
InferencePool
リソースを使用すると、GKE Inference Gateway はモデルサーバー Pod にトラフィックを転送できます。
Helm を使用して InferencePool
を作成する手順は次のとおりです。
helm install vllm-llama3-8b-instruct \
--set inferencePool.modelServers.matchLabels.app=vllm-llama3-8b-instruct \
--set provider.name=gke \
--set healthCheckPolicy.create=false \
--version v0.3.0 \
oci://registry.k8s.io/gateway-api-inference-extension/charts/inferencepool
次のフィールドを Deployment に合わせて変更します。
inferencePool.modelServers.matchLabels.app
: モデルサーバー Pod の選択に使用されるラベルのキー。
このコマンドは、モデルサーバーのデプロイを論理的に表す InferencePool
オブジェクトを作成し、Selector
が選択した Pod 内のモデル エンドポイント サービスを参照します。
サービングの重要度を持つ InferenceModel
リソースを作成する
InferenceModel
Kubernetes カスタム リソースは、LoRA チューニング済みモデルなどの特定のモデルと、そのサービス提供の重要度を定義します。
InferenceModel
カスタム リソースには、次のキーフィールドが含まれています。
modelName
: ベースモデルまたは LoRA アダプタの名前を指定します。Criticality
: モデルの提供の重要度を指定します。poolRef
: モデルが提供されるInferencePool
を参照します。
InferenceModel
を使用すると、GKE Inference Gateway はモデル名と重大度に基づいてモデルサーバー Pod にトラフィックをルーティングできます。
InferenceModel
を作成するには、次の操作を行います。
次のサンプル マニフェストを
inferencemodel.yaml
として保存します。apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferenceModel metadata: name: inferencemodel-sample spec: modelName: MODEL_NAME criticality: CRITICALITY poolRef: name: INFERENCE_POOL_NAME
次のように置き換えます。
MODEL_NAME
: ベースモデルまたは LoRA アダプターの名前。例:food-review
CRITICALITY
: 選択したサービング クリティカル性。Critical
、Standard
、Sheddable
から選択します。例:Standard
INFERENCE_POOL_NAME
: 前の手順で作成したInferencePool
の名前。例:vllm-llama3-8b-instruct
サンプル マニフェストをクラスタに適用します。
kubectl apply -f inferencemodel.yaml
次の例では、Standard
サービス重大度で vllm-llama3-8b-instruct
InferencePool
に food-review
LoRA モデルを構成する InferenceModel
オブジェクトを作成します。InferenceModel
オブジェクトは、Critical
優先度レベルで提供されるようにベースモデルを構成します。
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceModel
metadata:
name: food-review
spec:
modelName: food-review
criticality: Standard
poolRef:
name: vllm-llama3-8b-instruct
targetModels:
- name: food-review
weight: 100
---
apiVersion: inference.networking.x-k8s.io/v1alpha2
kind: InferenceModel
metadata:
name: llama3-base-model
spec:
modelName: meta-llama/Llama-3.1-8B-Instruct
criticality: Critical
poolRef:
name: vllm-llama3-8b-instruct
ゲートウェイを作成する
Gateway リソースは、Kubernetes クラスタへの外部トラフィックのエントリ ポイントとして機能します。受信接続を受け入れるリスナーを定義します。
GKE Inference Gateway は、gke-l7-rilb
と gke-l7-regional-external-managed
の Gateway クラスをサポートしています。詳細については、Gateway クラスに関する GKE のドキュメントをご覧ください。
Gateway を作成するには、次の操作を行います。
次のサンプル マニフェストを
gateway.yaml
として保存します。apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: GATEWAY_NAME spec: gatewayClassName: gke-l7-regional-external-managed listeners: - protocol: HTTP # Or HTTPS for production port: 80 # Or 443 for HTTPS name: http
GATEWAY_NAME
は、Gateway リソースの一意の名前に置き換えます。例:inference-gateway
マニフェストをクラスタに適用します。
kubectl apply -f gateway.yaml
HTTPRoute
リソースを作成する
このセクションでは、HTTPRoute
リソースを作成し、Gateway が受信した HTTP リクエストを InferencePool
に転送する方法を定義します。
HTTPRoute リソースは、GKE Gateway が受信した HTTP リクエストをバックエンド サービス(InferencePool
)に転送する方法を定義します。一致ルール(ヘッダーやパスなど)と、トラフィックを転送するバックエンドを指定します。
HTTPRoute を作成するには、次の操作を行います。
次のサンプル マニフェストを
httproute.yaml
として保存します。apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: HTTPROUTE_NAME spec: parentRefs: - name: GATEWAY_NAME rules: - matches: - path: type: PathPrefix value: PATH_PREFIX backendRefs: - name: INFERENCE_POOL_NAME group: inference.networking.x-k8s.io kind: InferencePool
次のように置き換えます。
HTTPROUTE_NAME
:HTTPRoute
リソースの一意の名前。例:my-route
GATEWAY_NAME
: 作成したGateway
リソースの名前。例:inference-gateway
PATH_PREFIX
: 受信リクエストの照合に使用するパス接頭辞。たとえば、/
はすべてに一致します。INFERENCE_POOL_NAME
: トラフィックを転送するInferencePool
リソースの名前。例:vllm-llama3-8b-instruct
マニフェストをクラスタに適用します。
kubectl apply -f httproute.yaml
推論リクエストを送信する
GKE Inference Gateway を構成したら、デプロイされたモデルに推論リクエストを送信できます。
推論リクエストを送信する手順は次のとおりです。
- Gateway エンドポイントを取得します。
- 正しい形式の JSON リクエストを作成します。
curl
を使用して、/v1/completions
エンドポイントにリクエストを送信します。
これにより、入力プロンプトと指定したパラメータに基づいてテキストを生成できます。
Gateway エンドポイントを取得するには、次のコマンドを実行します。
IP=$(kubectl get gateway/GATEWAY_NAME -o jsonpath='{.status.addresses[0].address}') PORT=PORT_NUMBER # Use 443 for HTTPS, or 80 for HTTP
次のように置き換えます。
GATEWAY_NAME
: Gateway リソースの名前。PORT_NUMBER
: Gateway で構成したポート番号。
curl
を使用して/v1/completions
エンドポイントにリクエストを送信するには、次のコマンドを実行します。curl -i -X POST https://${IP}:${PORT}/v1/completions \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer $(gcloud auth print-access-token)' \ -d '{ "model": "MODEL_NAME", "prompt": "PROMPT_TEXT", "max_tokens": MAX_TOKENS, "temperature": "TEMPERATURE" }'
次のように置き換えます。
MODEL_NAME
: 使用するモデルまたは LoRA アダプターの名前。PROMPT_TEXT
: モデルの入力プロンプト。MAX_TOKENS
: レスポンスで生成するトークンの最大数。TEMPERATURE
: 出力のランダム性を制御します。確定的な出力の場合は値0
を使用し、より創造的な出力の場合はより大きな値を使用します。
次の動作に注意してください。
- リクエスト本文: リクエスト本文には、
stop
やtop_p
などの追加パラメータを指定できます。オプションの一覧については、OpenAI API 仕様をご覧ください。 - エラー処理: クライアント コードに適切なエラー処理を実装して、レスポンスで発生する可能性のあるエラーを処理します。たとえば、
curl
レスポンスの HTTP ステータス コードを確認します。通常、200 以外のステータス コードはエラーを示します。 - 認証と認可: 本番環境のデプロイでは、認証と認可メカニズムを使用して API エンドポイントを保護します。適切なヘッダー(
Authorization
など)をリクエストに含めます。
Inference Gateway のオブザーバビリティを構成する
GKE Inference Gateway は、推論ワークロードの健全性、パフォーマンス、動作のオブザーバビリティを提供します。これにより、問題を特定して解決し、リソース使用率を最適化し、アプリケーションの信頼性を保証できます。これらのオブザーバビリティ指標は、Cloud Monitoring の Metrics Explorer で確認できます。
GKE Inference Gateway のオブザーバビリティを構成するには、オブザーバビリティを構成するをご覧ください。
デプロイされたリソースを削除する
このガイドで作成したリソースについて Google Cloud アカウントに課金されないようにするには、次のコマンドを実行します。
gcloud container clusters delete CLUSTER_NAME \
--region=REGION
次の値を置き換えます。
REGION
: 使用するアクセラレータ タイプをサポートするリージョン(たとえば、H100 GPU の場合はus-central1
)。CLUSTER_NAME
: クラスタの名前。
次のステップ
- GKE Inference Gateway について確認する。
- GKE Inference Gateway のデプロイを確認する。