Agent Development Kit(ADK)とセルフホスト型 LLM を使用してエージェント AI アプリケーションを GKE にデプロイする

このチュートリアルでは、Google Kubernetes Engine(GKE)を使用して、コンテナ化されたエージェント AI / ML アプリケーションをデプロイおよび管理する方法について説明します。Google Agent Development Kit(ADK)と、vLLM によってサービングされる Llama 3.1 のようなセルフホスト型大規模言語モデル(LLM)を組み合わせることで、モデルスタックを完全に制御しながら、AI エージェントを効率的かつ大規模に運用できます。このチュートリアルでは、GPU アクセラレーションを備えた GKE Autopilot クラスタで Python ベースのエージェントを開発して本番環境にデプロイするまでのエンドツーエンドのプロセスについて説明します。

このチュートリアルは、エージェント AI / ML アプリケーションのサービングに Kubernetes コンテナ オーケストレーション機能を使用することに関心がある ML エンジニア、デベロッパー、クラウド アーキテクトを対象としています。 Google Cloudのコンテンツで参照されている一般的なロールとタスクの例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

始める前に、次の内容を理解しておいてください。

背景

このセクションでは、このチュートリアルで使用されている重要なテクノロジーについて説明します。

Agent Development Kit(ADK)

Agent Development Kit(ADK)は、AI エージェントの開発とデプロイ用に設計された、柔軟性の高いモジュール型のフレームワークです。ADK は Gemini と Google エコシステム向けに最適化されていますが、特定のモデルやデプロイメントを使用する必要はなく、他のフレームワークとの互換性を考慮して構築されています。ADK は、エージェント開発をソフトウェア開発のように感じられるよう設計されており、デベロッパーは基本的なタスクから複雑なワークフローまで、幅広いエージェント アーキテクチャを簡単に作成、デプロイ、オーケストレートできます。

詳細については、ADK のドキュメントをご覧ください。

GKE マネージド Kubernetes サービス

Google Cloud には、GKE など、AI / ML ワークロードのデプロイと管理に適したサービスが幅広く用意されています。GKE は、コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を簡素化するマネージド Kubernetes サービスです。GKE は、LLM のコンピューティング需要を処理するために必要なインフラストラクチャ(スケーラブルなリソース、分散コンピューティング、効率的なネットワーキングなど)を提供します。

Kubernetes の主なコンセプトの詳細については、Kubernetes の学習を開始するをご覧ください。GKE の詳細と、GKE が Kubernetes のスケーリング、自動化、管理にどのように役立つかについては、GKE の概要をご覧ください。

vLLM

vLLM は、GPU のサービング スループットを向上させる高度に最適化されたオープンソースの LLM サービング フレームワークであり、次のような機能を備えています。

  • PagedAttention による Transformer の実装の最適化
  • サービング スループットを全体的に向上させる連続的なバッチ処理
  • 複数の GPU でのテンソル並列処理と分散サービング

詳細については、vLLM のドキュメントをご覧ください。

環境を準備する

このチュートリアルでは、Cloud Shell を使用して Google Cloudでホストされているリソースを管理します。Cloud Shell には、このチュートリアルに必要なソフトウェア(kubectlterraformGoogle Cloud CLI など)がプリインストールされています。

Cloud Shell を使用して環境を設定するには、次の操作を行います。

  1. Google Cloud コンソールで Cloud Shell セッションを起動し、Cloud Shell 有効化アイコンCloud Shell をアクティブにする)をクリックします。これにより、 Google Cloud コンソール ペインでセッションが起動します。
  2. デフォルトの環境変数を設定します。

    gcloud config set project PROJECT_ID
    export GOOGLE_CLOUD_REGION=REGION
    export PROJECT_ID=PROJECT_ID
    

    次の値を置き換えます。

    • PROJECT_ID: 実際の Google Cloud プロジェクト ID
    • REGION: GKE クラスタ、Artifact Registry、その他のリージョン リソースをプロビジョニングする Google Cloud リージョン(例: us-east4)。L4 GPU と G2 マシンタイプ インスタンスがサポートされているリージョンを指定します。リージョンの可用性を確認するには、Compute Engine ドキュメントの GPU のリージョンとゾーンをご覧ください。

サンプル プロジェクトのクローンを作成する

  1. Cloud Shell ターミナルから、チュートリアルのサンプルコード リポジトリのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples.git
    
  2. チュートリアル ディレクトリに移動します。

    cd kubernetes-engine-samples/ai-ml/adk-vllm
    

Google Cloud リソースを作成して構成する

エージェントをデプロイするには、まず必要な Google Cloudリソースをプロビジョニングする必要があります。GKE クラスタと Artifact Registry リポジトリは、gcloud CLI または Terraform を使用して作成できます。

gcloud

このセクションでは、GKE クラスタと Artifact Registry をセットアップする gcloud CLI コマンドについて説明します。

  1. GKE クラスタを作成する: コンテナ化されたエージェント アプリケーションは、GKE Autopilot クラスタまたは GKE Standard クラスタにデプロイできます。フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用します。ワークロードに最適な GKE のオペレーション モードを選択するには、GKE のオペレーション モードについてをご覧ください。

    Autopilot

    Cloud Shell で、次のコマンドを実行します。

    gcloud container clusters create-auto CLUSTER_NAME \
        --location=$GOOGLE_CLOUD_REGION
    

    CLUSTER_NAME を GKE クラスタの名前に置き換えます。

    GKE Autopilot では、ワークロードのリソース リクエストに基づいてノードが自動的にプロビジョニングされます。LLM に必要な GPU は、deploy-llm.yaml マニフェスト内で nodeSelector を使用してリクエストします。

    nvidia-l4 GPU をリクエストする nodeSelector を追加する手順は次のとおりです。

    1. kubernetes-engine-samples/ai-ml/adk-vllm/deploy-llm/deploy-llm.yaml をエディタで開きます。
    2. spec.template.spec の下に次の nodeSelector を追加します。

      nodeSelector:
      cloud.google.com/gke-accelerator: nvidia-l4
      

    Standard

    1. Cloud Shell で、次のコマンドを実行して Standard クラスタを作成します。

      gcloud container clusters create CLUSTER_NAME \
          --location=$GOOGLE_CLOUD_REGION
      

      CLUSTER_NAME を GKE クラスタの名前に置き換えます。

    2. 次のコマンドを実行して、クラスタの GPU 対応ノードプールを作成します。

      gcloud container node-pools create gpu-node-pool \
          --cluster=CLUSTER_NAME \
          --location=$GOOGLE_CLOUD_REGION \
          --machine-type=g2-standard-8 \
          --accelerator=type=nvidia-l4,count=1 \
          --enable-gvnic
      

      nvidia-l4 GPU は deploy-llm.yaml ファイルで指定されています。この GPU は G2 マシンシリーズで使用できます。このマシンタイプの詳細については、Compute Engine ドキュメントの GPU マシンタイプをご覧ください。

  2. Artifact Registry リポジトリを作成する: エージェントの Docker コンテナ イメージを安全に保存して管理するための Artifact Registry リポジトリを作成します。

    gcloud artifacts repositories create REPO_NAME \
        --repository-format=docker \
        --location=$GOOGLE_CLOUD_REGION
    

    REPO_NAME は、使用する Artifact Registry リポジトリの名前に置き換えます(例: adk-repo)。

  3. リポジトリの URL を取得する: リポジトリの完全なパスを確認するには、次のコマンドを実行します。この形式は、エージェント イメージをビルドするときに Docker イメージにタグを付けるために使用します。

    gcloud artifacts repositories describe REPO_NAME \
        --location $GOOGLE_CLOUD_REGION
    

Terraform

このセクションでは、サンプル リポジトリに含まれている Terraform 構成を使用して Google Cloud リソースを自動的にプロビジョニングする方法について説明します。

  1. Terraform ディレクトリに移動する: \terraform ディレクトリには、GKE クラスタとその他の必須リソースを作成するために必要なすべての構成ファイルが含まれています。

    cd terraform
    
  2. Terraform 変数ファイルを作成する: 提供されたサンプル変数ファイル(example_vars.tfvars)をコピーして、独自の vars.tfvars ファイルを作成します。

    cp example_vars.tfvars vars.tfvars
    

    vars.tfvars ファイルをエディタで開き、プレースホルダの値を特定の構成に置き換えます。少なくとも、PROJECT_ID は Google Cloud プロジェクト ID に、CLUSTER_NAME は GKE クラスタの名前に置き換える必要があります。

  3. Terraform を初期化する: Google Cloud用の必要なプロバイダ プラグインをダウンロードするには、次のコマンドを実行します。

    terraform init
    
  4. 実行プランを確認する: 次のコマンドを実行すると、Terraform によってインフラストラクチャに加えられる変更が表示されます。

    terraform plan -var-file=vars.tfvars
    
  5. 構成を適用する: Google Cloud プロジェクトにリソースを作成するには、Terraform プランを実行します。プロンプトが表示されたら、yes で確定します。

    terraform apply -var-file=vars.tfvars
    

これらのコマンドを実行すると、GKE クラスタと Artifact Registry リポジトリがプロビジョニングされ、Workload Identity Federation for GKE を含む必要な IAM ロールとサービス アカウントが構成されます。

Terraform の使用方法の詳細については、Terraform を使用して GKE リソースをプロビジョニングするをご覧ください。

クラスタと通信するように kubectl を構成する

クラスタと通信するように kubectl を構成するには、次のコマンドを実行します。

gcloud container clusters get-credentials CLUSTER_NAME \
    --location=${GOOGLE_CLOUD_REGION}

CLUSTER_NAME を GKE クラスタの名前に置き換えます。

エージェント イメージをビルドする

gcloud CLI または Terraform を使用してインフラストラクチャを作成したら、次の手順に沿ってエージェント アプリケーションをビルドします。

  1. Cloud Build に必要な IAM ロールを付与する: Cloud Build サービスに、エージェントのコンテナ イメージを Artifact Registry に push する権限を与える必要があります。Cloud Build によって使用される Compute Engine のデフォルト サービス アカウントに roles/artifactregistry.writer ロールを付与します。

    1. Compute Engine のデフォルト サービス アカウントのメールアドレスを作成します。

      export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
      export COMPUTE_SA_EMAIL=${PROJECT_NUMBER}-compute@developer.gserviceaccount.com
      
    2. サービス アカウントに roles/artifactregistry.writer ロールを付与します。

      gcloud projects add-iam-policy-binding $PROJECT_ID \
          --member=serviceAccount:${COMPUTE_SA_EMAIL} \
          --role=roles/artifactregistry.writer
      
  2. エージェント コンテナ イメージをビルドして push する: プロジェクトのルート ディレクトリ(adk/llama/vllm)から次のコマンドを実行し、Docker イメージをビルドして Artifact Registry に push します。

    export IMAGE_URL="${GOOGLE_CLOUD_REGION}-docker.pkg.dev/${PROJECT_ID}/REPO_NAME/adk-agent:latest"
    gcloud builds submit --tag $IMAGE_URL
    
  3. イメージが push されたことを確認する: ビルドプロセスが正常に完了したら、リポジトリ内のイメージを一覧表示して、エージェントのコンテナ イメージが Artifact Registry に push されたことを確認します。

    gcloud artifacts docker images list ${GOOGLE_CLOUD_REGION}-docker.pkg.dev/${PROJECT_ID}/REPO_NAME
    

    出力されたイメージの一覧に、リポジトリに push して latest というタグを付けたイメージが含まれていることを確認します。

モデルをデプロイする

GKE クラスタのセットアップとエージェント イメージのビルドが完了したら、次にセルフホスト型 Llama 3.1 モデルをクラスタにデプロイします。そのためには、Hugging Face からモデルを pull してクラスタ内で内部的にサービングする、事前構成された vLLM 推論サーバーをデプロイします。

  1. Hugging Face の認証情報用の Kubernetes Secret を作成する: GKE クラスタがゲート付きの Llama 3.1 モデルをダウンロードできるようにするには、Hugging Face トークンを Kubernetes Secret として提供する必要があります。deploy-llm.yaml マニフェストは、このシークレットを認証に使用するよう構成されています。

    kubectl create secret generic hf-secret \
        --from-literal=hf-token-secret=HUGGING_FACE_TOKEN
    

    HUGGING_FACE_TOKEN は、実際のトークンに置き換えます。

  2. マニフェストを表示する: プロジェクトのルート ディレクトリ(adk/llama/vllm)から、モデルの Deployment マニフェストを含む /deploy-llm ディレクトリに移動します。

    cd deploy-llm
    
  3. マニフェストを適用する: 次のコマンドを実行して、deploy-llm.yaml マニフェストをクラスタに適用します。

    kubectl apply -f deploy-llm.yaml
    

    このコマンドは、次の 3 つの Kubernetes リソースを作成します。

    • meta-llama/Llama-3.1-8B-Instruct モデルを使用するよう構成された vLLM サーバーを実行する Deployment。
    • 内部クラスタ IP アドレスで vLLM サーバーを公開し、その IP アドレスを介して ADK エージェントが vLLM サーバーと通信できるようにする、vllm-llama3-service という名前の Service。
    • Llama 3.1 モデルに必要な Jinja チャット テンプレートを含む ConfigMap。
  4. モデルの Deployment を確認する: vLLM サーバーが Hugging Face からモデルファイルを pull します。この処理には数分かかることがあります。Pod のステータスをモニタリングすることで、その readiness を確認できます。

    1. Deployment が使用可能になるまで待ちます。

      kubectl wait --for=condition=available --timeout=600s deployment/vllm-llama3-deployment
      
    2. 実行中の Pod のログを表示して、サーバーが正常に起動したことを確認します。

      export LLM_POD=$(kubectl get pods -l app=vllm-llama3 -o jsonpath='{.items[0].metadata.name}')
      kubectl logs -f $LLM_POD
      

      ログに次のような行が出力されていれば、Deployment の準備は完了です。これは、LLM サーバーが起動し、API ルートが使用可能になったことを示しています。

      INFO 07-16 14:15:16 api_server.py:129] Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
      
    3. モデルサーバーにリクエストを直接送信して、LLM が使用可能であることを確認します。そのためには、新しい Cloud Shell ターミナルを開き、次のコマンドを実行して vllm-llama3-service をローカルマシンに転送します。

      kubectl port-forward service/vllm-llama3-service 8000:8000
      
    4. 別のターミナルで、curl を使用してモデルの API エンドポイントにサンプル リクエストを送信します。次に例を示します。

      curl -X POST http://localhost:8000/v1/completions \
        -H "Content-Type: application/json" \
        -d '{
          "model": "meta-llama/Llama-3.1-8B-Instruct",
          "prompt": "Hello!",
          "max_tokens": 10
        }'
      

      成功の JSON レスポンスが返されたら、LLM は使用可能です。これで、ターミナル ウィンドウで Ctrl+C を押してポート転送プロセスを終了し、エージェントのデプロイに進むことができます。

エージェント アプリケーションをデプロイする

次のステップは、ADK ベースのエージェント アプリケーションをデプロイすることです。

  1. /deploy-agent ディレクトリに移動する: プロジェクトのルート ディレクトリ(adk/llama/vllm)から、エージェントのソースコードとデプロイメント マニフェストを含む /deploy-agent ディレクトリに移動します。

    cd ../deploy-agent
    
  2. エージェントのデプロイメント マニフェストを更新する:

    1. サンプルの deploy-agent.yaml マニフェスト ファイルには、コンテナ イメージの URL にプロジェクト ID のプレースホルダが含まれています。このプレースホルダを実際の Google Cloud プロジェクト ID に置き換える必要があります。

      image: us-central1-docker.pkg.dev/PROJECT_ID/adk-repo/adk-agent:latest
      

      この置換をインプレースで行うには、次のコマンドを実行します。

      sed -i "s/<PROJECT_ID>/$PROJECT_ID/g" deploy-agent.yaml
      
    2. readinessProbe パスが、/dev-ui ではなく / に設定されていることを確認します。この置換をインプレースで行うには、次のコマンドを実行します。

      sed -i "s|path: /dev-ui/|path: /|g" deploy-agent.yaml
      
  3. マニフェストを適用する: 次のコマンドを実行して、deploy-agent.yaml マニフェストをクラスタに適用します。

    kubectl apply -f deploy-agent.yaml
    

    このコマンドは、次の 2 つの Kubernetes リソースを作成します。

    • カスタムビルドのエージェント コンテナ イメージを実行する、adk-agent という名前の Deployment。
    • エージェント アプリケーションを公開してテスト用にアクセスできるようにする、adk-agent という名前の NodePort タイプの Service。
  4. エージェントのデプロイメントを確認する: Pod のステータスを確認して、Pod が正しく実行されていることを確認します。

    1. Deployment が使用可能になるまで待ちます。

      kubectl wait --for=condition=available --timeout=300s deployment/adk-agent
      
    2. 実行中のエージェント Pod のログを表示します。

      export AGENT_POD=$(kubectl get pods -l app=adk-agent -o jsonpath='{.items[0].metadata.name}')
      kubectl logs -f $AGENT_POD
      

ログに次のような行が出力されていれば、デプロイは成功しています。これは、Uvicorn サーバーが実行されていて、リクエストを受け入れる準備ができていることを示します。

INFO:     Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)

デプロイしたエージェントをテストする

vLLM サーバーとエージェント アプリケーションの両方が正常にデプロイされたら、エージェントのウェブ UI を使用してエンドツーエンドの機能をテストできます。

  1. エージェントのサービスをローカルマシンに転送する: adk-agent サービスは NodePort タイプですが、Cloud Shell 環境からこのサービスにアクセスする最も直接的な方法は kubectl port-forward コマンドを使用することです。次のコマンドを実行して、エージェントの Pod への安全なトンネルを作成します。

    kubectl port-forward $AGENT_POD 8001:8001
    
  2. エージェントのウェブ UI にアクセスする: Cloud Shell で、[ウェブでプレビュー] ボタンをクリックして [ポート 8001 でプレビュー] を選択します。新しいブラウザタブが開き、エージェントのチャット インターフェースが表示されます。

  3. エージェントと対話する: エージェントの get_weather ツールを呼び出す質問をします。次に例を示します。

    What's the weather like in Tokyo?
    

    エージェントはまず LLM を呼び出してインテントを理解し、get_weather ツールを使用する必要があるかどうかを判断します。次に、「Tokyo」をパラメータとしてこのツールを実行します。最後に、ツールの出力を使用してレスポンスを生成します。次のようなレスポンスが表示されます。

      The weather in Tokyo is 25°C and sunny.
    
  4. (省略可)ログでツールの呼び出しを確認する: 各 Pod のログを表示することで、エージェントと LLM のやり取りやツールの実行を確認できます。

    1. エージェント Pod のログ: 新しいターミナルで、adk-agent Pod のログを表示します。ツールの呼び出しとその結果が表示されます。

      kubectl logs -f $AGENT_POD
      

      出力に、ツールが呼び出されたこと、結果が処理されたことが示されます。

    2. LLM Pod ログ: vllm-llama3-deployment Pod のログを表示して、エージェントからの受信リクエストを確認します。

      kubectl logs -f $LLM_POD
      

      ログには、エージェントが LLM に送信したプロンプトの全文が表示されます。これには、システム メッセージ、ユーザーからのクエリ、get_weather ツールの定義が含まれます。

テストが完了したら、ターミナル ウィンドウで Ctrl+C を押して port-forward プロセスを終了します。