概要
このドキュメントは、ソリューション リファレンス実装(SRI)ガイドとして、Distributed Cloud ソフトウェアのみのオープンモデル サービング ソリューションのデプロイ、サービング、検証に必要な具体的な手順について説明します。
このガイドでは、物理 NVIDIA GPU リソース(RTX PRO 6000 など)を利用して、Distributed Cloud ソフトウェアのみのエッジ デプロイを対象とした単一ノード クラスタ構成で Gemma 4(google/gemma-4-31B-it)を実行する最適化された vLLM サービング エンジンのデプロイを実装します。
このチュートリアルは、Distributed Cloud ソフトウェアのみのクラスタに対する kubectl アクセス権を持つ CLI ターミナル クライアントから実行するように設計されています。
目標
このソリューション リファレンス実装を完了すると、次のことができるようになります。
- ローカル
.envファイルを使用して、サービング環境パラメータを構成します。 local-sharedストレージ クラスを使用して、モデルの重みを永続化する Persistent Volume Claim(PVC)をデプロイします。- Vertex AI 認定コンテナを利用して、最適化された vLLM サービング エンジンをデプロイし、物理
nvidia.com/gpuリソースをマッピングします。 - Gradio ウェブ UI をデプロイして、インタラクティブなチャット インターフェースを提供します。
- ローカル ポート転送トンネルを確立して、API とウェブ UI を介してサービングの応答性を検証します。
- Cloud Logging と Cloud Monitoring へのログと指標(GPU テレメトリーを含む)の取り込みを確認して、オブザーバビリティ統合を確認します。
始める前に
前提条件(クラスタ設定)
このガイドでは、GPU サポートが構成された Distributed Cloud ソフトウェアのみのクラスタが実行されていることを前提としています。クラスタのインストールについては、ベアメタル用 Distributed Cloud ソフトウェアのみの公式ドキュメントをご覧ください。GPU 構成は、NVIDIA GPU を設定して使用するの公式 Google Cloudドキュメントに準拠している必要があります。
クライアント ワークステーションの前提条件
ローカル ターミナル環境に次のツールがインストールされ、構成されていることを確認します。
- gcloud CLI: プロジェクトの構成とログのクエリに必要です。認証(
gcloud auth login)され、Distributed Cloud ソフトウェアのみのクラスタが登録されているアクティブなGoogle Cloud プロジェクトに構成されている必要があります。 - kubectl: クラスタ リソースの管理に必要です。ターゲットの Distributed Cloud ソフトウェアのみのクラスタにアクセスするための適切なコンテキスト(接続ゲートウェイやローカル ネットワークへの直接アクセスなど)で構成する必要があります。
- curl: サービング エンドポイントにテスト リクエストを送信するために必要です。
- jq: サービング エンドポイントからの JSON 出力を解析するために必要です。
Hugging Face モデルへのアクセス
Gemma 4 モデルをダウンロードしてデプロイするには、Hugging Face リポジトリへのアクセス権が必要です。
- Hugging Face アカウント: Hugging Face に登録済みのアカウントがあることを確認します。
- モデルのライセンスに同意する: Gemma 4 31B IT モデルページに移動し、ライセンス条項に同意して、ゲート付きモデルの重みにアクセスします。
- アクセス トークンを生成する: Hugging Face アカウント設定([Settings] -> [Access Tokens])から、読み取り権限を持つユーザー アクセス トークンを生成します。このトークンは、構成で
HF_TOKENとして使用されます。
中央リファレンス構成
すべてのデプロイ パラメータは、<local-config-dir>/.env にある中央の .env ファイルで管理されます。このファイルが存在し、特定のパラメータ(Hugging Face トークン、名前空間、モデル名など)が含まれていることを確認します。
.env 構造の例:
# GDCso Cluster Namespace
NAMESPACE_NAME="your-custom-namespace"
# Hugging Face Token (Required to download gated Gemma models)
HF_TOKEN="your-hf-token-here"
# Model Sizing Parameters
MODEL_NAME="google/gemma-4-31B-it"
SAFE_MODEL_NAME="google-gemma-4-31B-it"
# Hyperparameters
MAX_MODEL_LEN=8192
GPU_MEMORY_UTILIZATION=0.95
MAX_NUM_SEQS=512
MAX_NUM_BATCHED_TOKENS=4096
DTYPE="bfloat16"
# Pod Sizing Requests
CPU_REQUEST="4"
MEMORY_REQUEST="80"
環境と認証情報を設定する
Namespace と Hugging Face Secret を作成する
デプロイする前に、Namespace と Hugging Face トークン シークレットを作成する必要があります。
# Navigate to your project root
cd <local-working-dir>
# Sourced from your local .env file
source <local-config-dir>/.env
# Create namespace
kubectl create namespace ${NAMESPACE_NAME} --dry-run=client -o yaml | kubectl apply -f -
# Create Hugging Face token secret
kubectl create secret generic hf-token-secret \
--from-literal=token="${HF_TOKEN}" \
-n "${NAMESPACE_NAME}" --dry-run=client -o yaml | kubectl apply -f -
Kubernetes での vLLM のデプロイ
このデプロイは、PVC、Service、Deployment の 3 つの主要なマニフェストで構成されています。これらのテンプレートは、デプロイ時に置き換えられる環境変数を使用します。
Persistent Volume Claim(PVC)
PVC は、Distributed Cloud ソフトウェアの local-shared ストレージ クラスのみを使用して、Pod の再起動後もモデルの重みを保持します。
次の内容で vllm-pvc.yaml という名前のファイルを作成します。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: model-cache-pvc
namespace: ${NAMESPACE_NAME}
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-shared
resources:
requests:
storage: 100Gi
サービス
vLLM API サーバーをポート 8000 で内部的に公開します。
次の内容で vllm-service.yaml という名前のファイルを作成します。
apiVersion: v1
kind: Service
metadata:
name: vllm-service
namespace: ${NAMESPACE_NAME}
labels:
app: vllm
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "8000"
spec:
ports:
- name: http
port: 8000
targetPort: 8000
selector:
app: vllm
type: ClusterIP
デプロイ
vLLM コンテナを実行し、モデル キャッシュ ボリュームをマウントして、物理 GPU リソースをリクエストします。96 GB の VRAM は量子化されていない BF16 重み(約 62 GB)に適合しますが、このリファレンス実装では、Blackwell FP8 量子化(--quantization=fp8、約 31 GB の重み)を有効にして、KV キャッシュを 56.53 GiB(61,728 トークン)に拡張し、同時スループットを向上させます。
次の内容で vllm-deployment.yaml という名前のファイルを作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-deployment
namespace: ${NAMESPACE_NAME}
labels:
app: vllm
ai.gke.io/inference-server: vllm
ai.gke.io/model: ${SAFE_MODEL_NAME}
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: vllm
template:
metadata:
labels:
app: vllm
examples.ai.gke.io/source: user-guide
ai.gke.io/inference-server: vllm
ai.gke.io/model: ${SAFE_MODEL_NAME}
spec:
runtimeClassName: nvidia
containers:
- name: vllm-container
image: us-docker.pkg.dev/vertex-ai/vertex-vision-model-garden-dockers/pytorch-vllm-serve:gemma4
imagePullPolicy: IfNotPresent
command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
args:
- --model=$(MODEL_ID)
- --host=0.0.0.0
- --port=8000
- --tensor-parallel-size=1
- --enable-log-requests
- --max-model-len=${MAX_MODEL_LEN}
- --gpu-memory-utilization=${GPU_MEMORY_UTILIZATION}
- --max-num-seqs=${MAX_NUM_SEQS}
- --max-num-batched-tokens=${MAX_NUM_BATCHED_TOKENS}
- --dtype=${DTYPE}
- --trust-remote-code
- --enable-prefix-caching
- --enable-chunked-prefill
- --quantization=fp8
env:
- name: MODEL_ID
value: ${MODEL_NAME}
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token-secret
key: token
- name: LD_LIBRARY_PATH
value: "/usr/local/nvidia/lib64"
ports:
- name: http
containerPort: 8000
resources:
requests:
cpu: ${CPU_REQUEST}
memory: "${MEMORY_REQUEST}Gi"
nvidia.com/gpu: "1"
limits:
cpu: ${CPU_REQUEST}
memory: "${MEMORY_REQUEST}Gi"
nvidia.com/gpu: "1"
volumeMounts:
- mountPath: /root/.cache/huggingface
name: cache-volume
- mountPath: /dev/shm
name: dshm
volumes:
- name: cache-volume
persistentVolumeClaim:
claimName: model-cache-pvc
- name: dshm
emptyDir:
medium: Memory
sizeLimit: 16Gi
Gradio UI のデプロイ
Gradio UI は、モデルとチャットするためのインタラクティブなウェブ インターフェースを提供します。クラスタ内にデプロイされ、内部 Kubernetes ネットワークを介して vLLM サービスに接続します。
Gradio のデプロイ
次の内容で gradio-deployment.yaml という名前のファイルを作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: gradio-deployment
namespace: ${NAMESPACE_NAME}
labels:
app: gradio
spec:
replicas: 1
selector:
matchLabels:
app: gradio
template:
metadata:
labels:
app: gradio
spec:
containers:
- name: gradio
image: us-docker.pkg.dev/google-samples/containers/gke/gradio-app:v1.0.4
resources:
requests:
cpu: "250m"
memory: "512Mi"
limits:
cpu: "500m"
memory: "512Mi"
env:
- name: CONTEXT_PATH
value: "/v1/chat/completions"
- name: HOST
value: "http://vllm-service:8000"
- name: MODEL_ID
value: "${MODEL_NAME}"
ports:
- containerPort: 7860
Gradio サービス
次の内容で gradio-service.yaml という名前のファイルを作成します。
apiVersion: v1
kind: Service
metadata:
name: gradio-service
namespace: ${NAMESPACE_NAME}
spec:
selector:
app: gradio
ports:
- protocol: TCP
port: 8080
targetPort: 7860
type: ClusterIP
オブザーバビリティの構成
アプリケーションのロギングとモニタリングの構成の詳細については、公式の アプリケーションのロギングとモニタリングのガイドをご覧ください。
vLLM モニタリング
Google Cloud Managed Service for Prometheus(GMP)による vLLM 指標のスクレイピングを有効にするには、vLLM Pod をターゲットとする PodMonitoring リソースをデプロイします。
次の内容で vllm-pod-monitoring.yaml という名前のファイルを作成します。
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: vllm-pod-monitoring
namespace: ${NAMESPACE_NAME}
spec:
selector:
matchLabels:
app: vllm
endpoints:
- port: http
interval: 30s
GPU モニタリング
Google Cloud Managed Service for Prometheus(GMP)による NVIDIA DCGM エクスポータからの GPU 指標のスクレイピングを有効にするには、gpu-operator Namespace に PodMonitoring リソースをデプロイします。詳細については、GPU 指標を Cloud Monitoring に送信するをご覧ください。
次の内容で gpu-pod-monitoring.yaml という名前のファイルを作成します。
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: dcgm-gmp
namespace: gpu-operator
spec:
selector:
matchLabels:
app: nvidia-dcgm-exporter
endpoints:
- port: metrics
interval: 30s
実行のステップ
マニフェストのデプロイ
マニフェストをクラスタに適用します。YAML ファイルには環境変数プレースホルダが含まれているため、適用する前に envsubst を使用して .env ファイルの変数を置き換えます。
YAML ファイルを含む作業ディレクトリに移動します。
cd <local-working-dir>環境変数を取得します。
source <local-config-dir>/.envマニフェストを順番に適用します。
# Apply core serving manifests envsubst < vllm-pvc.yaml | kubectl apply -f - envsubst < vllm-service.yaml | kubectl apply -f - envsubst < vllm-deployment.yaml | kubectl apply -f - # Apply observability manifests envsubst < vllm-pod-monitoring.yaml | kubectl apply -f - kubectl apply -f gpu-pod-monitoring.yaml # Apply Gradio UI manifests envsubst < gradio-deployment.yaml | kubectl apply -f - envsubst < gradio-service.yaml | kubectl apply -f -
検証
Pod の起動シーケンスをモニタリングする
コンテナログをストリーミングして、起動シーケンスを追跡します。
# 1. Check pod status (wait until it is Running)
kubectl get pods -n ${NAMESPACE_NAME} -l app=vllm
# 2. Stream logs to verify model loading
kubectl logs -f -l app=vllm -n ${NAMESPACE_NAME}
ログにアクティブなサービングの準備完了シグナルが表示されるまで待ちます。
INFO: Application startup complete.
ポート転送トンネルを確立する
エンドポイントをローカルでテストするには、サービスポート 8000 を転送します。
kubectl port-forward service/vllm-service 8000:8000 -n ${NAMESPACE_NAME}
このターミナルは開いたままにするか、バックグラウンドで実行します。
クエリ サービング エンドポイント
別のターミナルから、API の応答性をテストします。
1. クエリモデルのリスト
curl -s http://localhost:8000/v1/models | jq
2. チャット補完をクエリする
curl -s http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "'"${MODEL_NAME}"'",
"messages": [
{"role": "user", "content": "What is AGI in 100 words"}
],
"max_tokens": 150
}' | jq
GPU と VRAM の割り当てを確認する
モデルがハードウェアを効率的に使用し、メモリ フットプリントが正しいことを確認するには、GPU 監査を実行します。
Pod 内の nvidia-smi を介して GPU を監査する
アクティブな vLLM Pod の名前を取得し、コンテナ内で nvidia-smi を実行します。
# Dynamically get the pod name
export VLLM_POD_NAME=$(kubectl get pods -n ${NAMESPACE_NAME} -l app=vllm -o jsonpath='{.items[0].metadata.name}')
# Run nvidia-smi inside the container
kubectl exec ${VLLM_POD_NAME} -n ${NAMESPACE_NAME} -- nvidia-smi
想定される出力: 出力は、GPU_MEMORY_UTILIZATION パラメータと一致する物理 VRAM 使用率を報告します。たとえば、GPU_MEMORY_UTILIZATION=0.95 で google/gemma-4-31B-it を実行する NVIDIA RTX PRO 6000(約 96 GB VRAM)を搭載したワークステーションでは、VLLM::EngineCore に割り当てられた約 95,800 MiB が表示されます。
+-----------------------------------------------------------------------------------------+
| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|=========================================+========================+======================|
| 0 NVIDIA RTX PRO 6000 Blac... On | 00000000:05:00.0 Off | 0 |
| N/A 36C P0 85W / 600W | 95805MiB / 97887MiB | 0% Default |
+-----------------------------------------+------------------------+----------------------+
ログで KV キャッシュの割り当てを確認する
vLLM の内部割り当てログを調べて、KV キャッシュのサイズとトークンの同時実行性を確認することもできます。
kubectl logs ${VLLM_POD_NAME} -n ${NAMESPACE_NAME} | grep -E "Available KV cache|GPU KV cache size"
予想される出力:
(EngineCore pid=362) INFO 06-18 15:03:43 [gpu_worker.py:456] Available KV cache memory: 56.53 GiB
(EngineCore pid=362) INFO 06-18 15:03:43 [kv_cache_utils.py:1316] GPU KV cache size: 61,728 tokens
これにより、56.53 GiB の VRAM がコンテキスト KV キャッシュ用に予約され、大量の同時実行トークンが可能になります。
Gradio UI のデプロイを確認する
Gradio Pod が実行されたら、ポート転送トンネルを確立して UI にアクセスできます。
Gradio Pod のステータスをモニタリングする
Gradio Pod が実行されていることを確認します。
kubectl get pods -n ${NAMESPACE_NAME} -l app=gradio
予想される出力:
NAME READY STATUS RESTARTS AGE
gradio-deployment-yyyyyyyy-yyyyy 1/1 Running 0 1m
Gradio へのポート転送トンネルを確立する
Gradio サービスのポート 8080 をローカルポート 7860 に転送します。
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME}
このターミナルを開いたままにするか、バックグラウンドで実行します。
kubectl port-forward service/gradio-service 7860:8080 -n ${NAMESPACE_NAME} > pf_gradio.log 2>&1 & sleep 3
ウェブ UI にアクセスする
- ローカル ワークステーションで実行している場合: ブラウザを開き、
http://localhost:7860に直接移動します。 - Cloud Shell 内で実行している場合: [ウェブでプレビュー] ボタンを使用して、[ポートを変更] を選択し、
7860と入力して、[変更してプレビュー] をクリックします。
Gradio のチャットボット インターフェースが表示されます。メッセージを入力して Gemma モデルを操作できます。Gradio Pod は、リクエストを内部的に vllm-service エンドポイントに転送します。
トンネルをクリーンアップする
ポート転送トンネルを停止するには:
pkill -f "port-forward service/gradio-service"
モニタリングの確認
vLLM がデプロイされ、PodMonitoring リソースが適用されると、指標が Cloud Monitoring に取り込まれていることを確認できます。
PodMonitoring のステータスを確認する
PodMonitoring リソースが作成され、アクティブであることを確認します。
kubectl get podmonitoring -n ${NAMESPACE_NAME}
Google Cloud コンソールを使用して指標の取り込みを確認する
指標が取り込まれていることを確認するには、 Google Cloud コンソール(Metrics Explorer)を使用します。
- Google Cloud コンソールで [Metrics Explorer] を開きます。
https://console.cloud.google.com/monitoring/metrics-explorerに移動します(プロジェクト${GCP_PROJECT_ID}を選択してください)。
- [指標を選択] プルダウンで、次の指標を検索して選択します。
prometheus.googleapis.com/vllm:num_requests_running/gaugeを使用して vLLM 指標を確認します。prometheus.googleapis.com/DCGM_FI_DEV_GPU_UTIL/gaugeを使用して GPU 使用率指標を確認します。
- グラフを観察して、データポイントがアクティブにプロットされていることを確認します。
ロギングの検証
ワークロードが実行されたら、ログが Cloud Logging にエクスポートされていることを確認できます。
vLLM ログの取り込みを確認する
vLLM コンテナログが Cloud Logging にエクスポートされていることを確認します。
project_id=$(gcloud config get-value project)
gcloud logging read "resource.type=\"k8s_container\" AND resource.labels.namespace_name=\"${NAMESPACE_NAME}\" AND resource.labels.container_name=\"vllm-container\"" --limit=10 --project=${project_id}
GPU エクスポータのログの取り込みを確認する
GPU エクスポータ コンテナログが Cloud Logging にエクスポートされていることを確認します。
project_id=$(gcloud config get-value project)
gcloud logging read "resource.type=\"k8s_container\" AND resource.labels.namespace_name=\"gpu-operator\" AND resource.labels.container_name=\"nvidia-dcgm-exporter\"" --limit=10 --project=${project_id}
Google Cloud コンソール(ログ エクスプローラ)を使用してログを確認する
Google Cloud コンソールを使用してログの取り込みを確認することもできます。
- Google Cloud コンソールでログ エクスプローラを開きます。
https://console.cloud.google.com/logs/queryに移動します(プロジェクト${GCP_PROJECT_ID}を選択してください)。
[クエリ] ボックスに次のクエリを入力して、vLLM ログを表示します。
resource.type="k8s_container" resource.labels.namespace_name="<NAMESPACE_NAME>" resource.labels.container_name="vllm-container"(
<NAMESPACE_NAME>は実際の Namespace(your-custom-namespaceなど)に置き換えます)。[クエリを実行] をクリックします。vLLM コンテナのログエントリが表示されます。
GPU エクスポータのログを確認するには、次のクエリを実行します。
resource.type="k8s_container" resource.labels.namespace_name="gpu-operator" resource.labels.container_name="nvidia-dcgm-exporter"