1. はじめに
概要
このラボでは、GPU アクセラレータ Gemma バックエンドを使用して、本番環境対応の Agent Development Kit(ADK)エージェントをデプロイします。このチュートリアルでは、GPU 対応の Cloud Run サービスの設定、モデル バックエンドと ADK エージェントの統合、負荷下での自動スケーリングの動作のモニタリングなど、重要なデプロイ パターンに焦点を当てます。
演習内容
このラボでは、本番環境への導入における重要な側面について学習します。
- GPU を使用して Gemma を Cloud Run にデプロイする - 高パフォーマンスの Gemma モデル バックエンドを設定する
- Gemma デプロイを ADK エージェントと統合する - エージェントを GPU アクセラレータ モデルに接続する
- ADK ウェブ インターフェースでテストする - 会話型エージェントが正しく動作することを検証します
- 負荷テストを実行する - 負荷がかかった状態で Cloud Run インスタンスが自動スケーリングされる様子を確認します。
エージェントの広範な開発ではなく、本番環境へのデプロイ パターンに重点が置かれています。
学習内容
- GPU アクセラレーションを備えた Gemma モデルを Cloud Run にデプロイして本番環境で使用する
- 外部モデルのデプロイを ADK エージェントと統合する
- 本番環境対応の AI エージェントのデプロイを構成してテストする
- 負荷がかかった状態での Cloud Run の自動スケーリングの動作を理解する
- トラフィックの急増時に複数の Cloud Run インスタンスが連携する様子を確認する
- 負荷テストを適用してパフォーマンスと自動スケーリングを検証する
2. プロジェクトの設定
- Google アカウントをまだお持ちでない場合は、Google アカウントを作成する必要があります。
- 仕事用または学校用アカウントではなく、個人アカウントを使用します。職場用アカウントと学校用アカウントには、このラボに必要な API を有効にできないようにする制限が設定されている場合があります。
- Google Cloud コンソールにログインします。
- Cloud コンソールで課金を有効にします。
- このラボを完了するのにかかる Cloud リソースの費用は 1 米ドル未満です。
- このラボの最後の手順に沿ってリソースを削除すると、それ以上の料金は発生しません。
- 新規ユーザーは、300 米ドル分の無料トライアルをご利用いただけます。
- 新しいプロジェクトを作成するか、既存のプロジェクトを再利用します。
3. Cloud Shell エディタを開く
- このリンクをクリックすると、Cloud Shell エディタに直接移動します。
- 本日、承認を求めるプロンプトが表示された場合は、[承認] をクリックして続行します。
- ターミナルが画面の下部に表示されない場合は、ターミナルを開きます。
- [表示] をクリックします。
- [ターミナル] をクリックします。
- ターミナルで、次のコマンドを使用してプロジェクトを設定します。
- 形式:
gcloud config set project [PROJECT_ID]
- 例:
gcloud config set project lab-project-id-example
- プロジェクト ID を忘れた場合:
- 次のコマンドを使用すると、すべてのプロジェクト ID を一覧表示できます。
gcloud projects list | awk '/PROJECT_ID/{print $2}'
- 次のコマンドを使用すると、すべてのプロジェクト ID を一覧表示できます。
- 形式:
- 次のようなメッセージが表示されます。
Updated property [core/project].
WARNING
が表示され、Do you want to continue (Y/n)?
と表示された場合は、プロジェクト ID が正しく入力されていない可能性があります。n
を押してEnter
を押し、gcloud config set project
コマンドを再実行します。
4. API を有効にしてデフォルトのリージョンを設定する
GPU サポートを使用して Cloud Run サービスをデプロイする前に、必要な Google Cloud API を有効にして、プロジェクト設定を構成する必要があります。
- ターミナルで API を有効にします。
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com
承認を求められたら、[承認] をクリックして続行します。
このコマンドが完了するまでには数分かかる場合がありますが、最終的には次のような成功メッセージが表示されます。
Operation "operations/acf.p2-73d90d00-47ee-447a-b600" finished successfully.
- Cloud Run のデフォルト リージョンを設定します。
gcloud config set run/region europe-west1
5. Python プロジェクトを準備する
Gemma バックエンド サービスと ADK エージェント サービスの両方の基本構造を含むスターター コードを設定しましょう。
- スターター リポジトリのクローンを作成します。
cd ~ git clone https://github.com/amitkmaraj/accelerate-ai-lab3-starter.git cd accelerate-ai-lab3-starter
- プロジェクトの構造を確認します。
次のようなスターター構造が表示されます。ls -R
accelerate-ai-lab3-starter/ ├── README.md # Project overview ├── ollama-backend/ # Ollama backend (separate deployment) │ └── Dockerfile # Backend container (🚧 to implement) └── adk-agent/ # ADK agent (separate deployment) ├── pyproject.toml # Python dependencies (✅ completed) ├── server.py # FastAPI server (🚧 to implement) ├── Dockerfile # Container config (🚧 to implement) ├── load_test.py # Load testing (🚧 to implement) └── production_agent/ # Agent implementation ├── __init__.py # Package init (✅ completed) └── agent.py # Agent logic (🚧 to implement)
6. アーキテクチャの概要
実装する前に、2 つのサービス アーキテクチャについて理解しましょう。
重要な分析情報: ロードテスト中に、両方のサービスが独立してスケーリングされることがわかります。GPU バックエンド(ボトルネック サービス)は推論負荷に対して 1 ~ 3 個のインスタンスにスケーリングされますが、ADK エージェントはリクエスト処理に対して 1 個のインスタンスのままです。
7. GPU を使用して Gemma Backend を Cloud Run にデプロイする
最初の重要なステップは、GPU アクセラレーション Gemma モデルをデプロイすることです。このモデルは ADK エージェントの頭脳として機能します。分離されたデプロイ済み LLM は、個別のファインチューニング済みモデルが必要なアーキテクチャや、分離されたスケーリングが必要なアーキテクチャで有利になる可能性があります。
- Ollama バックエンド ディレクトリに移動します。
cd ollama-backend
- Ollama Dockerfile を開いて実装します。
TODO コメントを次の内容に置き換えます。cloudshell edit Dockerfile
🔧 この機能の概要:FROM ollama/ollama:latest # Listen on all interfaces, port 8080 ENV OLLAMA_HOST 0.0.0.0:8080 # Store model weight files in /models ENV OLLAMA_MODELS /models # Reduce logging verbosity ENV OLLAMA_DEBUG false # Never unload model weights from the GPU ENV OLLAMA_KEEP_ALIVE -1 # Store the model weights in the container image ENV MODEL gemma3:270m RUN ollama serve & sleep 5 && ollama pull $MODEL # Start Ollama ENTRYPOINT ["ollama", "serve"]
- 公式の Ollama イメージを基盤として使用する
- 任意の IP アドレスからの接続を受け入れるように
OLLAMA_HOST
を設定します - ポート 8080 を公開する
- GPU サポートを使用して Gemma バックエンドをデプロイします。
gcloud run deploy ollama-gemma3-270m-gpu \
--source . \
--region europe-west1 \
--concurrency 4 \
--cpu 8 \
--set-env-vars OLLAMA_NUM_PARALLEL=4 \
--gpu 1 \
--gpu-type nvidia-l4 \
--max-instances 3 \
--memory 16Gi \
--allow-unauthenticated \
--no-cpu-throttling \
--no-gpu-zonal-redundancy \
--timeout 600 \
--labels dev-tutorial=codelab-agent-gpu
「Deploying from source requires an Artifact Registry Docker repository to store built containers. 「A repository named [cloud-run-source-deploy] in region [europe-west1] will be created.」というメッセージが表示されたら、続行します。
⚙️ キーの構成の説明:
- GPU: 推論ワークロードの費用対効果に優れている NVIDIA L4 を選択。L4 は 24 GB の GPU メモリと最適化されたテンソル オペレーションを備えており、Gemma などの 2 億 7, 000 万のパラメータ モデルに最適です。
- メモリ: モデルの読み込み、CUDA オペレーション、Ollama のメモリ管理を処理する 16 GB のシステム メモリ
- CPU: 最適な I/O 処理と前処理タスクのための 8 コア
- 同時実行数: インスタンスあたり 4 つのリクエストで、スループットと GPU メモリ使用量のバランスを取ります。
- タイムアウト: 600 秒は、初期モデルの読み込みとコンテナの起動に対応します。
💰 費用の考慮事項: GPU インスタンスは、CPU のみのインスタンスよりも大幅に高価です(1 時間あたり約 $2 ~$4 対 1 時間あたり約 $0.10)。--max-instances 1
設定は、不要な GPU インスタンスのスケーリングを防ぐことで、費用を制御するのに役立ちます。
- デプロイが完了するまで待ち、サービス URL をメモします。
export OLLAMA_URL=$(gcloud run services describe ollama-gemma3-270m-gpu \ --region=europe-west1 \ --format='value(status.url)') echo "🎉 Gemma backend deployed at: $OLLAMA_URL"
8. ADK エージェント統合を実装する
次に、デプロイされた Gemma バックエンドに接続する最小限の ADK エージェントを作成します。
- ADK エージェント ディレクトリに移動します。
cd ../adk-agent
- エージェントの構成を開いて実装します。
すべての TODO コメントを次の最小限の実装に置き換えます。cloudshell edit production_agent/agent.py
🔧 この機能の概要:import os from pathlib import Path from dotenv import load_dotenv from google.adk.agents import Agent from google.adk.models.lite_llm import LiteLlm import google.auth # Load environment variables root_dir = Path(__file__).parent.parent dotenv_path = root_dir / ".env" load_dotenv(dotenv_path=dotenv_path) # Configure Google Cloud try: _, project_id = google.auth.default() os.environ.setdefault("GOOGLE_CLOUD_PROJECT", project_id) except Exception: pass os.environ.setdefault("GOOGLE_CLOUD_LOCATION", "europe-west1") # Configure model connection gemma_model_name = os.getenv("GEMMA_MODEL_NAME", "gemma3:270m") # Production Gemma Agent - GPU-accelerated conversational assistant gemma_agent = Agent( model=LiteLlm(model=f"ollama_chat/{gemma_model_name}"), name="gemma_agent", description="A production-ready conversational assistant powered by GPU-accelerated Gemma.", instruction="""You are 'Gem', a friendly, knowledgeable, and enthusiastic zoo tour guide. Your main goal is to make a zoo visit more fun and educational for guests by answering their questions. You can provide general information and interesting facts about different animal species, such as: - Their natural habitats and diet. 🌲🍓 - Typical lifespan and behaviors. - Conservation status and unique characteristics. IMPORTANT: You do NOT have access to any tools. This means you cannot look up real-time, specific information about THIS zoo. You cannot provide: - The names or ages of specific animals currently at the zoo. - The exact location or enclosure for an animal. - The daily schedule for feedings or shows. Always answer based on your general knowledge about the animal kingdom. Keep your tone cheerful, engaging, and welcoming for visitors of all ages. 🦁✨""", tools=[], # Gemma focuses on conversational capabilities ) # Set as root agent root_agent = gemma_agent
- LiteLlm を介してデプロイされた Gemma バックエンドに接続する
- シンプルな会話型エージェントを作成します
- Google Cloud との統合を構成します
- FastAPI サーバーを開いて実装します。
すべての TODO コメントを次のコードに置き換えます。cloudshell edit server.py
🔧 この機能の概要:import os from dotenv import load_dotenv from fastapi import FastAPI from google.adk.cli.fast_api import get_fast_api_app # Load environment variables load_dotenv() AGENT_DIR = os.path.dirname(os.path.abspath(__file__)) app_args = {"agents_dir": AGENT_DIR, "web": True} # Create FastAPI app with ADK integration app: FastAPI = get_fast_api_app(**app_args) # Update app metadata app.title = "Production ADK Agent - Lab 3" app.description = "Gemma agent with GPU-accelerated backend" app.version = "1.0.0" @app.get("/health") def health_check(): return {"status": "healthy", "service": "production-adk-agent"} @app.get("/") def root(): return { "service": "Production ADK Agent - Lab 3", "description": "GPU-accelerated Gemma agent", "docs": "/docs", "health": "/health" } if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8080, log_level="info")
- ADK 統合を使用して FastAPI サーバーを作成する
- テスト用のウェブ インターフェースを有効にします
- ヘルスチェック エンドポイントを提供する
- Dockerfile を開いて実装します。
すべての TODO コメントを次のコードに置き換えます。cloudshell edit Dockerfile
テクノロジーの選択肢の説明:FROM python:3.13-slim # Copy uv from the official image COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv # Install system dependencies RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* # Set working directory WORKDIR /app # Copy all files COPY . . # Install Python dependencies RUN uv sync # Expose port EXPOSE 8080 # Run the application CMD ["uv", "run", "uvicorn", "server:app", "--host", "0.0.0.0", "--port", "8080"]
- uv: pip より 10 ~ 100 倍高速な最新の Python パッケージ マネージャー。グローバル キャッシュと並列ダウンロードを使用して、コンテナのビルド時間を大幅に短縮します。
- Python 3.13-slim: システム依存関係を最小限に抑えた最新の Python バージョン。コンテナのサイズと攻撃対象領域を削減します。
- マルチステージ ビルド: 公式イメージから uv をコピーすることで、最新の最適化されたバイナリを取得できます。
9. 環境を構成してエージェントをデプロイする
次に、デプロイされた Gemma バックエンドに接続するように ADK エージェントを構成し、Cloud Run サービスとしてデプロイします。これには、環境変数の設定と、適切な構成でのエージェントのデプロイが含まれます。
- 環境構成を設定します。
cat << EOF > .env GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project) GOOGLE_CLOUD_LOCATION=europe-west1 GEMMA_MODEL_NAME=gemma3:270m OLLAMA_API_BASE=$OLLAMA_URL EOF
Cloud Run の環境変数について
環境変数は、実行時にアプリケーションを構成する Key-Value ペアです。特に次の場合に役立ちます。
- API エンドポイントとサービス URL(Ollama バックエンドなど)
- 環境(開発、ステージング、本番)間で変更される構成
- ハードコードすべきでない機密データ
ADK エージェントをデプロイします。
export PROJECT_ID=$(gcloud config get-value project)
gcloud run deploy production-adk-agent \
--source . \
--region europe-west1 \
--allow-unauthenticated \
--memory 4Gi \
--cpu 2 \
--max-instances 1 \
--concurrency 10 \
--timeout 300 \
--set-env-vars GOOGLE_CLOUD_PROJECT=$PROJECT_ID \
--set-env-vars GOOGLE_CLOUD_LOCATION=europe-west1 \
--set-env-vars GEMMA_MODEL_NAME=gemma3:270m \
--set-env-vars OLLAMA_API_BASE=$OLLAMA_URL \
--labels dev-tutorial=codelab-agent-gpu
⚙️ キーの構成:
- 自動スケーリング: 1 インスタンスに固定(軽量リクエスト処理)
- 同時実行: インスタンスあたり 10 件のリクエスト
- メモリ: ADK エージェント用に 4 GB
- 環境: Gemma バックエンドに接続します
🔒 セキュリティに関する注記: このラボでは、わかりやすくするために --allow-unauthenticated
を使用します。本番環境では、次の方法で適切な認証を実装します。
- サービス アカウントを使用した Cloud Run サービス間認証
- Identity and Access Management(IAM)ポリシー
- 外部アクセス用の API キーまたは OAuth
gcloud run services add-iam-policy-binding
を使用してアクセスを制御することを検討する
エージェント サービスの URL を取得します。
export AGENT_URL=$(gcloud run services describe production-adk-agent \
--region=europe-west1 \
--format='value(status.url)')
echo "🎉 ADK Agent deployed at: $AGENT_URL"
Cloud Run 環境変数のドキュメントに基づく、✅ 環境変数のベスト プラクティス:
- 予約済み変数を避ける:
PORT
(Cloud Run が自動的に設定します)またはX_GOOGLE_
で始まる変数を設定しないでください。 - 説明的な名前を使用する: 変数に接頭辞を付けて、競合を回避します(例:
GEMMA_MODEL_NAME
(MODEL
の代わりに使用) - カンマをエスケープする: 値にカンマが含まれている場合は、別の区切り文字(
--set-env-vars "^@^KEY1=value1,value2@KEY2=..."
)を使用します。 - 更新と置換:
--update-env-vars
を使用して、他の変数に影響を与えることなく特定の変数を追加または変更する
Cloud Run で変数を設定する方法:
- ファイルから:
gcloud run deploy SERVICE_NAME --env-vars-file .env --labels dev-tutorial codelab-adk
(ファイルから複数の変数を読み込みます) - 複数のフラグ: カンマで区切ることができない複雑な値の場合は、
--set-env-vars
を繰り返します。
10. ADK ウェブ インターフェースでテストする
両方のサービスがデプロイされたら、ADK エージェントが GPU アクセラレータ Gemma バックエンドと正常に通信し、ユーザーのクエリに応答できることを検証します。
- ヘルス エンドポイントをテストします。
次のように表示されます。curl $AGENT_URL/health
{ "status": "healthy", "service": "production-adk-agent" }
production-adk-agent
の URL を新しいブラウザタブに入力して、エージェントとやり取りします。ADK ウェブ インターフェースが表示されます。- 次のサンプル会話でエージェントをテストします。
- 「レッサーパンダは野生で何を食べていますか?」
- 「ユキヒョウに関する興味深い事実を教えてください。」
- 「ヤドクガエルはなぜあんなに鮮やかな色をしているの?」
- 「動物園の新しい赤ちゃんカンガルーはどこにいますか?」
- エージェントは、デプロイされた Gemma モデルを使用して応答します。これは、デプロイされた Gemma サービスのログを調べることで確認できます。次のセクションでこれを行います。
- レスポンスは GPU アクセラレーション バックエンドによって生成されます
- ウェブ インターフェースでクリーンなチャット エクスペリエンスを実現
11. 負荷テストを実装して実行する
本番環境のデプロイが実際のトラフィックをどのように処理するかを理解するために、ADK エージェントと GPU バックエンド サービスの両方で自動スケーリングをトリガーする包括的な負荷テストを実装します。
- 負荷テスト スクリプトを開いて実装します。
TODO コメントを次の内容に置き換えます。cloudshell edit load_test.py
🔧 この機能の概要:import random import uuid from locust import HttpUser, task, between class ProductionAgentUser(HttpUser): """Load test user for the Production ADK Agent.""" wait_time = between(1, 3) # Faster requests to trigger scaling def on_start(self): """Set up user session when starting.""" self.user_id = f"user_{uuid.uuid4()}" self.session_id = f"session_{uuid.uuid4()}" # Create session for the Gemma agent using proper ADK API format session_data = {"state": {"user_type": "load_test_user"}} self.client.post( f"/apps/production_agent/users/{self.user_id}/sessions/{self.session_id}", headers={"Content-Type": "application/json"}, json=session_data, ) @task(4) def test_conversations(self): """Test conversational capabilities - high frequency to trigger scaling.""" topics = [ "What do red pandas typically eat in the wild?", "Can you tell me an interesting fact about snow leopards?", "Why are poison dart frogs so brightly colored?", "Where can I find the new baby kangaroo in the zoo?", "What is the name of your oldest gorilla?", "What time is the penguin feeding today?" ] # Use proper ADK API format for sending messages message_data = { "app_name": "production_agent", "user_id": self.user_id, "session_id": self.session_id, "new_message": { "role": "user", "parts": [{ "text": random.choice(topics) }] } } self.client.post( "/run", headers={"Content-Type": "application/json"}, json=message_data, ) @task(1) def health_check(self): """Test the health endpoint.""" self.client.get("/health")
- セッションの作成:
/apps/production_agent/users/{user_id}/sessions/{session_id}
への POST で適切な ADK API 形式を使用します。session_id
とuser_id
を作成したら、エージェントにリクエストを送信できます。 - メッセージ形式:
app_name
、user_id
、session_id
、構造化されたnew_message
オブジェクトを含む ADK 仕様に準拠 - 会話エンドポイント:
/run
エンドポイントを使用してすべてのイベントを一度に収集します(負荷テストにおすすめ) - Realistic Load: 待機時間を短くして会話の負荷を作成し、自動スケーリングをトリガーします。
- セッションの作成:
- 依存関係をインストールします。
uv sync pip install locust
- Locust は、ウェブ アプリケーションやその他のシステムのパフォーマンスと負荷テスト用に設計された、Python ベースのオープンソースの負荷テストツールです。主な特徴は、テスト シナリオとユーザーの動作が標準の Python コードを使用して定義されることです。グラフィカル ユーザー インターフェースやドメイン固有言語に依存するツールと比較して、高い柔軟性と表現力を提供します。Locust を使用して、サービスへのユーザー トラフィックをシミュレートします。負荷テストを実行します。
テストのパラメータを変更して、出力を確認します。# Run a load test to trigger autoscaling locust -f load_test.py \ -H $AGENT_URL \ --headless \ -t 50s \ -u 3 \ -r 1
ollama-gemma3-270m-gpu
が 2 ~ 3 個のインスタンスに急増します。📊 負荷テスト パラメータ:- 再生時間: 50 秒
- ユーザー: 3 人の同時ユーザー
- 生成率: 1 ユーザー / 秒
- ターゲット: 両方のサービスで自動スケーリングをトリガーする
12. AutoScaling の動作を観察する
ロードテストの実行中に、Cloud Run の自動スケーリングの動作を確認できます。ここでは、ADK エージェントを GPU バックエンドから分離することによるアーキテクチャ上の主なメリットを確認できます。
ロードテスト中に、両方の Cloud Run サービスがコンソールでどのようにスケーリングされるかをモニタリングします。
- Cloud Console で、次の場所に移動します。
- Cloud Run → production-adk-agent → [指標]
- [Cloud Run] → [ollama-gemma3-270m-gpu] → [指標]
👀 確認事項:
🤖 ADK エージェント サービス:
- トラフィックが増加しても 1 インスタンスで安定している
- トラフィックが多いときに CPU とメモリの使用率が急増する
- セッション管理とリクエストのルーティングを効率的に処理する
🎮 Gemma バックエンド サービス(ボトルネック):
- 推論の需要に基づいて 1 ~ 3 個のインスタンスにスケーリングする
- 負荷がかかると GPU 使用率が大幅に増加する
- GPU 負荷の高いモデル推論により、このサービスがボトルネックになる
- GPU アクセラレーションにより、モデルの推論時間が一定に保たれる
💡 主な分析情報:
- GPU バックエンドがボトルネックになり、より積極的にスケーリングされます(1 ~ 3 個のインスタンス)。
- ADK エージェントは一貫性を保つ
- どちらのサービスも、個々の負荷特性に基づいて個別にスケーリングされます。
- 自動スケーリングは、さまざまな負荷条件下でパフォーマンスを維持するのに役立ちます
13. まとめ
おめでとうございます!これで、GPU アクセラレータ Gemma バックエンドを使用して本番環境対応の ADK エージェントをデプロイし、自動スケーリングの動作を確認できました。
✅ 達成したこと
- ✅ Cloud Run に GPU アクセラレーションを備えた Gemma モデル バックエンドをデプロイした
- ✅ Gemma バックエンドと統合する ADK エージェントを作成してデプロイした
- ✅ ADK ウェブ インターフェースを使用してエージェントをテストした
- ✅ 連携する 2 つの Cloud Run サービスで自動スケーリングの動作を確認した
💡 このラボの主な分析情報
- 🎮 GPU アクセラレーション: NVIDIA L4 GPU により、モデルの推論パフォーマンスが大幅に向上します
- 🔗 サービス連携: 2 つの Cloud Run サービスがシームレスに連携
- 📈 独立したスケーリング: 各サービスは、個々の負荷特性に基づいてスケーリングされます。
- 🚀 本番環境の準備: アーキテクチャは実際のトラフィック パターンを効果的に処理します
🔄 次のステップ
- さまざまな負荷パターンを試して、スケーリング動作を観察する
- さまざまな Gemma モデルサイズを試す(メモリと GPU を適宜調整する)
- 本番環境のデプロイにモニタリングとアラートを実装する
- グローバルな可用性を実現するマルチリージョン デプロイを検討する
🧹 クリーンアップ
課金されないようにするには、作業が完了したらリソースを削除します。
gcloud run services delete production-adk-agent --region=europe-west1
gcloud run services delete ollama-gemma3-270m-gpu --region=europe-west1