課題
Vertex AIは強力な機能とGoogle Cloudエコシステムとのシームレスな統合を備えており、単にVM上にエンドポイントを立ててモデルをデプロイするだけでは得られないメリットを求めて、多くの組織が導入を検討しています。一方で、コスト面の負担が大きな壁となり、より効率的でコストパフォーマンスの高い方法が求められています。
問題の核心は、Vertex AIにモデルをデプロイした際のコストが、実際のリソース利用状況にかかわらず時間ベースで発生することにあります。料金ドキュメントには次のように記載されています。
AI Platform Predictionは、複数の仮想マシン(「ノード」)を稼働させてモデルからの予測を提供します。
各ノードがモデルのために稼働している時間に対して課金され、対象には次の状態が含まれます。
1. ノードがオンライン予測リクエストを処理しているとき。
2. ノードがオンライン予測を提供できるレディ状態にあるとき。
1ノードが1時間稼働するコストを「ノード時間」と呼びます。ノード時間とは、仮想マシンが予測ジョブを実行している時間、もしくは予測・説明リクエストに応えるためにアクティブな状態(1つ以上のモデルがデプロイされたエンドポイント)で待機している時間を指します。
1日や1週間のうち決まった時間帯にしかオンライン予測を行わない場合、アイドル時間中にゼロまでスケールダウンできないことが大きな悩みになります。GPUベースのモデルではコストが一気に膨らむため、この問題はさらに深刻になります。
お客様が直面したジレンマ
本事例のお客様は、Stable Diffusion基盤モデル(GPU必須)のオンライン予測にVertex AIを使いたいと考えていました。利用するのは平日の通常業務時間帯、具体的には週5日、午前7時から午後7時までです。
720ノード時間ぶんを支払うのではなく、実利用ぶんの240ノード時間(30%)だけ課金されるようにしたい、というのがご要望でした。
提案するソリューション
この課題を解決するために、Cloud Run jobsを活用します。
Cloud Run jobsを使えば、長時間かけて最後まで実行するスクリプトを、すべてサーバーレス環境で動かせます。
処理を行ってから停止するコード(スクリプトはまさにその典型)であれば、Cloud Run jobで実行できます。gcloud CLIを使ってコマンドラインから実行することも、定期実行のジョブをスケジュールすることも可能です。
実装は次の3ステップで進めます。
- モデルをVertex AIのオンライン予測エンドポイントにデプロイする
- Vertex AI Prediction Endpointsへのデプロイ・アンデプロイを行うCloud Run jobsを作成する
- ジョブの実行スケジュールを設定する
予測エンドポイントへのモデルデプロイ
まずVertex AI Model Gardenから、お客様の用途に合う事前学習済みモデルを探しました。要件に合致したのはstable-diffusion-2–1です。コンソールで「Deploy」を選択すると、モデルアーティファクトがVertex AI Model Registryにアップロードされ、続いてオンライン予測エンドポイントへデプロイされます。
その後、動作確認を行い、手動でアンデプロイしました。

Model Gardenにおけるモデルバージョンの詳細

Model Registryにインポートされたモデル

オンライン予測エンドポイントにデプロイされたモデルコンテナ
Cloud Runでモデルのデプロイとアンデプロイを制御する
Vertex AIエンドポイントへのモデルのデプロイとアンデプロイを細かく制御するために、Cloud Run Jobを利用します。
このJobの役割はデプロイ、またはアンデプロイの実行です。予測エンドポイントへのデプロイ・アンデプロイに必要なgcloudコマンドをまとめたシェルスクリプトを動かします。
Cloud Run Jobsの作成
Cloud Run jobsの作成手順は次のとおりです。
- モデルを最初にエンドポイントへデプロイした際の値と一致するように、モデルパラメータを指定します:
MODEL_NAME,MACHINE_TYPE,ACCELERATOR_TYPE,ENDPOINT_NAME
これらのパラメータはご利用環境に合わせて書き換えてください。
2. Vertex AIエンドポイントへのデプロイ・アンデプロイを行うCloud Run Jobsを作成します。ジョブの作成にはgcloud run jobsのソースからのデプロイオプション(-source)を使い、コンテナのビルド、Artifact Registryへのアップロード、Cloud Runへのデプロイまで一括で行います。
3. gcloudのジョブスケジュール機能を使い、設定どおりにジョブを実行するスケジューラトリガーを作成します。これにより、1日や1週間のうちオンライン予測が必要な時間帯にぴったり合わせて、リソースの稼働を細かく定義できます。
vertex-ai-mng-deploy GitHubリポジトリを使えば、Vertex AIエンドポイント上のモデルに対するDEPLOYジョブとUNDEPLOYジョブをまとめて生成できます。リポジトリには次のファイルが含まれています。
1. Cloud Run job作成用のCreateCloudRunJobs.sh
2. Vertex AIエンドポイントでのモデルのデプロイ/アンデプロイ用のMngModelDeploy.sh
3. MngModelDeploy.shを含むコンテナを作るためのDockerfile
以下がCreateCloudRunJobs.shです。
#!/bin/bash -xv
#A number that will be used for the id of the model deployment
ENDPOINT_NAME="stabilityai_stable-diffusion-endpoint"
MODEL_NAME="stable-diffusion-2-1"
MACHINE_TYPE="g2-standard-8"
ACCELERATOR_TYPE="nvidia-l4"
PROJECT=$(gcloud config get-value project)
PROJECT_NUMBER=$(gcloud projects describe "$PROJECT" --format="value(projectNumber)")
REGION=us-central1
DEPLOY_JOB_NAME=deploy-model-$MODEL_NAME
UNDEPLOY_JOB_NAME=undeploy-model-$MODEL_NAME
TIME_ZONE='UTC'
DEPLOY_SCHEDULE="0 7 * * *"
UN_DEPLOY_SCHEDULE="0 19 * * *"
#create a job for model deploy
gcloud run jobs deploy $DEPLOY_JOB_NAME --region=$REGION --source vertex-ai-mng-deploy \
--task-timeout=1800 --command "./MngModelDeploy.sh" \
--args DEPLOY,$ENDPOINT_NAME,$MODEL_NAME,$MACHINE_TYPE,$ACCELERATOR_TYPE \
--set-env-vars RUN_DEBUG=true,REGION=$REGION
#describe the job created
gcloud run jobs --region=$REGION describe $DEPLOY_JOB_NAME
#create a job for model undeploy
gcloud run jobs deploy $UNDEPLOY_JOB_NAME --region=$REGION --source vertex-ai-mng-deploy \
--task-timeout=180 --command "./MngModelDeploy.sh" \
--args UNDEPLOY,$ENDPOINT_NAME,$MODEL_NAME --set-env-vars RUN_DEBUG=true,REGION=$REGION
#describe the job created
gcloud run jobs --region=$REGION describe $UNDEPLOY_JOB_NAME
ジョブのスケジューリング
Cloud Run Jobsのスケジューラトリガーは、Vertex AIエンドポイントでのデプロイとアンデプロイをスケジュール実行するうえで欠かせない仕組みです。これによって、1日や1週間のうちオンライン予測を行いたい時間帯にぴたりと合わせて、リソースの稼働を精緻にスケジュールできます。
CreateCloudRunJobs.shの末尾には、Cloud Schedulerによるスケジュールジョブの作成処理が含まれています。
#create a schedule for deploy
gcloud scheduler jobs create http scheduler-$DEPLOY_JOB_NAME \
--location $REGION \
--schedule="$DEPLOY_SCHEDULE" --time-zone=$TIME_ZONE \
--uri="https://$REGION-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/$PROJECT/jobs/$DEPLOY_JOB_NAME:run" \
--http-method POST \
--oauth-service-account-email "$PROJECT_NUMBER"[email protected]
#create a schedule for undeploy
gcloud scheduler jobs create http scheduler-$DEPLOY_JOB_NAME \
--location $REGION \
--schedule="$UN_DEPLOY_SCHEDULE" --time-zone=$TIME_ZONE \
--uri="https://$REGION-run.googleapis.com/apis/run.googleapis.com/v1/namespaces/$PROJECT/jobs/$DEPLOY_JOB_NAME:run" \
--http-method POST \
--oauth-service-account-email "$PROJECT_NUMBER"[email protected]
モデルのデプロイとアンデプロイ
MngModelDeploy.shはJobから実行され、入力引数ACTIONの値によってデプロイを行うかアンデプロイを行うかが切り替わります。
モデルデプロイのJobとコマンド:
nadav@cloudshell:~$ gcloud run jobs describe deploy-model-stable-diffusion-2-1 --region=us-central1
✔ Job deploy-model-stable-diffusion-2-1 in region us-central1
Executed 6 times
Last executed 2024-01-30T08:06:22.875396Z with execution deploy-model-stable-diffusion-2-1-sr7kk
Image: us-central1-docker.pkg.dev/nadav/cloud-run-source-deploy/deploy-model-stable-diffusion-2-1@sha256:328c1117422af347be0906b0e4d27211ca764559e2405e8832d30d2f55158974
Tasks: 1
Command: ./MngModelDeploy.sh
Args: DEPLOY stabilityai_stable-diffusion-endpoint stable-diffusion-2-1 g2-standard-8 nvidia-l4
Memory: 512Mi
CPU: 1000m
Task Timeout: 30m
Max Retries: 3
Parallelism: No limit
Service account: [email protected]
Env vars:
REGION us-central1
RUN_DEBUG true
if [ "$ACTION" == "DEPLOY" ]; then
# Model deploy (takes time)
MODEL_ID=$(gcloud ai models list --region=$REGION \
--filter="DISPLAY_NAME:$MODEL_NAME" --format="value(MODEL_ID)")
echo "Deploying model..."
gcloud ai endpoints deploy-model "$ENDPOINT_ID" --region=$REGION \
--model="$MODEL_ID" --display-name="$MODEL_NAME"\
--machine-type="$MACHINE_TYPE" --accelerator=count=1,type="$ACCELERATOR_TYPE"
fi
モデルアンデプロイのJobとコマンド:
nadav@cloudshell$ gcloud run jobs describe undeploy-model-stable-diffusion-2-1 --region=us-central1
✔ Job undeploy-model-stable-diffusion-2-1 in region us-central1
Executed 6 times
Last executed 2024-01-30T08:04:57.205233Z with execution undeploy-model-stable-diffusion-2-1-kgrrc
Image: us-central1-docker.pkg.dev/nadav/cloud-run-source-deploy/undeploy-model-stable-diffusion-2-1@sha256:b1a8de6919205191feab7e4bed5d98fba9b40ecc9cb6cdae5a5fda550a54f612
Tasks: 1
Command: ./MngModelDeploy.sh
Args: UNDEPLOY stabilityai_stable-diffusion-endpoint stable-diffusion-2-1
Memory: 512Mi
CPU: 1000m
Task Timeout: 3m
Max Retries: 3
Parallelism: No limit
Service account: [email protected]
Env vars:
REGION us-central1
RUN_DEBUG true
if [ "$ACTION" == "UNDEPLOY" ]; then
echo "Un-deploying model..."
DEPLOY_MODEL_ID=$(gcloud ai endpoints describe "$ENDPOINT_ID" --region=$REGION \
--format=json | \
jq --arg ml_name "$MODEL_NAME" \
-r '.deployedModels[] | select(.displayName == $ml_name).id')
gcloud ai endpoints undeploy-model "$ENDPOINT_ID" --region=$REGION \
--deployed-model-id="$DEPLOY_MODEL_ID"
fi
まとめ
Vertex AIにCloud Runを組み合わせ、デプロイとスケジューリングを自動化する本アプローチは、アイドル時間の不要なリソース消費を抑え、大幅なコスト削減を実現する実践的かつ効果的な方法です。
時間ベースの課金構造に潜む課題に的確に対処することで、コスト効率を保ちながらVertex AIのポテンシャルを最大限に引き出せます。