GKE で単一の GPU を持つモデルを提供する


このチュートリアルでは、Google Kubernetes Engine(GKE)モードで GPU を使用して単純なモデルを提供する方法について説明します。このチュートリアルでは、単一の L4 Tensor Core GPU を使用する GKE クラスタを作成し、オンライン推論を行うように GKE インフラストラクチャを準備します。このチュートリアルでは、オンライン サービングでよく使用される次の 2 つのフレームワークを使用します。

目標

このチュートリアルは、GKE クラスタで事前トレーニング済みの ML モデルをホストするインフラストラクチャ エンジニア、MLOps エンジニア、DevOps エンジニア、クラスタ管理者を対象としています。

このチュートリアルでは、次の手順について説明します。

  1. GKE Autopilot クラスタまたは GKE Standard クラスタを作成する。
  2. 事前トレーニング済みモデルが存在する Cloud Storage バケットを構成する。
  3. 選択したオンライン推論フレームワークをデプロイする。
  4. デプロイされたサービスにテスト リクエストを送信する。

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

  • GKE
  • Cloud Storage
  • L4 GPU アクセラレータ
  • 下り(外向き)トラフィック

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

プロジェクトを設定する

  1. 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.
  2. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. Enable the GKE API.

    Enable the API

  5. In the Google Cloud console, on the project selector page, click Create project to begin creating a new Google Cloud project.

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the GKE API.

    Enable the API

Google Cloud CLI のデフォルト値を設定する

  1. Google Cloud コンソールで、Cloud Shell インスタンスを起動します。
    Cloud Shell を開く

  2. このサンプルアプリのソースコードをダウンロードします。

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    cd kubernetes-engine-samples/ai-ml/gke-online-serving-single-gpu
    
  3. デフォルトの環境変数を設定します。

    gcloud config set project PROJECT_ID
    gcloud config set compute/region COMPUTE_REGION
    

    次の値を置き換えます。

  4. Cloud Shell で、次の環境変数を作成します。

    export PROJECT_ID=$(gcloud config get project)
    export REGION=$(gcloud config get compute/region)
    export K8S_SA_NAME=gpu-k8s-sa
    export GSBUCKET=$PROJECT_ID-gke-bucket
    export MODEL_NAME=mnist
    export CLUSTER_NAME=online-serving-cluster
    

GKE クラスタを作成する

GKE Autopilot クラスタまたは GKE Standard クラスタの単一 GPU でモデルを提供できます。フルマネージドの Kubernetes エクスペリエンスを実現するには、Autopilot クラスタを使用することをおすすめします。GKE Autopilot では、リソースはモデルのリクエストに基づいて自動的にスケーリングされます。

ワークロードに最適な GKE の運用モードを選択するには、GKE の運用モードを選択するをご覧ください。

Autopilot

次のコマンドを実行して、GKE Autopilot クラスタを作成します。

  gcloud container clusters create-auto ${CLUSTER_NAME} \
      --region=${REGION} \
      --project=${PROJECT_ID} \
      --release-channel=rapid

GKE は、デプロイされたワークロードからのリクエストに応じた CPU ノードと GPU ノードを持つ Autopilot クラスタを作成します。

Standard

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

      gcloud container clusters create ${CLUSTER_NAME} \
        --project=${PROJECT_ID}  \
        --region=${REGION}  \
        --workload-pool=${PROJECT_ID}.svc.id.goog \
        --addons GcsFuseCsiDriver \
        --release-channel=rapid \
        --num-nodes=1
    

    クラスタの作成には数分かかることもあります。

  2. 次のコマンドを実行してノードプールを作成します。

      gcloud container node-pools create gpupool \
        --accelerator type=nvidia-l4,count=1,gpu-driver-version=latest \
        --project=${PROJECT_ID} \
        --location=${REGION} \
        --node-locations=${REGION}-a \
        --cluster=${CLUSTER_NAME} \
        --machine-type=g2-standard-8 \
        --num-nodes=1
    

    GKE は、ノードごとに 1 つの L4 GPU を含む単一のノードプールを作成します。

Cloud Storage バケットを作成する

提供する事前トレーニング済みモデルを保存する Cloud Storage バケットを作成します。

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

gcloud storage buckets create gs://$GSBUCKET

GKE 用 Workload Identity 連携を使用してバケットにアクセスするようにクラスタを構成する

クラスタから Cloud Storage バケットにアクセスできるようにする手順は次のとおりです。

  1. Google Cloud サービス アカウントを作成する。
  2. クラスタに Kubernetes ServiceAccount を作成する。
  3. Kubernetes ServiceAccount を Google Cloud サービス アカウントにバインドする。

Google Cloud サービス アカウントを作成する

  1. Google Cloud コンソールで、[サービス アカウントの作成] ページに移動します。

    [サービス アカウントの作成] に移動

  2. [サービス アカウント ID] フィールドに「gke-ai-sa」と入力します。

  3. [作成して続行] をクリックします。

  4. [ロール] リストで、[Cloud Storage] > [Storage Insights コレクタ サービス] ロールを選択します。

  5. [ 別のロールを追加] をクリックします。

  6. [ロールを選択] リストで、[Cloud Storage] > [Storage Object Admin] ロールを選択します。

  7. [続行] をクリックして [完了] をクリックします。

クラスタに Kubernetes ServiceAccount を作成する

Cloud Shell で、次の操作を行います。

  1. Kubernetes Namespace を作成します。

    kubectl create namespace gke-ai-namespace
    
  2. Namespace に Kubernetes ServiceAccount を作成します。

    kubectl create serviceaccount gpu-k8s-sa --namespace=gke-ai-namespace
    

Kubernetes ServiceAccount を Google Cloud サービス アカウントにバインドする

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

  1. Google Cloud サービス アカウントに IAM バインディングを追加します。

    gcloud iam service-accounts add-iam-policy-binding gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com \
        --role roles/iam.workloadIdentityUser \
        --member "serviceAccount:PROJECT_ID.svc.id.goog[gke-ai-namespace/gpu-k8s-sa]"
    

    --member フラグは、Google Cloud の Kubernetes ServiceAccount の完全な ID を指定します。

  2. Kubernetes ServiceAccount にアノテーションを付けます。

    kubectl annotate serviceaccount gpu-k8s-sa \
        --namespace gke-ai-namespace \
        iam.gke.io/gcp-service-account=gke-ai-sa@PROJECT_ID.iam.gserviceaccount.com
    

オンライン推論サーバーをデプロイする

各オンライン推論フレームワークは、特定の形式の事前トレーニング済み ML モデルを探すように構成されています。次のセクションでは、使用するフレームワークに応じて推論サーバーをデプロイする方法について説明します。

Triton

  1. Cloud Shell で、事前トレーニング済み ML モデルを Cloud Storage バケットにコピーします。

    gcloud storage cp src/triton-model-repository gs://$GSBUCKET --recursive
    
  2. Deployment を使用してフレームワークをデプロイします。Deployment は、クラスタ内のノード間で Pod の複数のレプリカを実行できる Kubernetes API です。

    envsubst < src/gke-config/deployment-triton.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. フレームワークがデプロイされたことを確認します。

    kubectl get deployments --namespace=gke-ai-namespace
    

    フレームワークの準備が整うと、出力は次のようになります。

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    triton-deployment    1/1     1            1           5m29s
    
  4. Deployment にアクセスする Service をデプロイします。

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-triton.yaml
    
  5. 外部 IP が割り当てられていることを確認します。

    kubectl get services --namespace=gke-ai-namespace
    

    出力は次のようになります。

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    triton-server   LoadBalancer   34.118.227.176   35.239.54.228   8000:30866/TCP,8001:31035/TCP,8002:30516/TCP   5m14s
    

    EXTERNAL-IP 列にある triton-server の IP アドレスをメモします。

  6. Service と Deployment が正常に機能していることを確認します。

    curl -v EXTERNAL_IP:8000/v2/health/ready
    

    出力は次のようになります。

    ...
    < HTTP/1.1 200 OK
    < Content-Length: 0
    < Content-Type: text/plain
    ...
    

TF Serving

  1. Cloud Shell で、事前トレーニング済み ML モデルを Cloud Storage バケットにコピーします。

    gcloud storage cp src/tfserve-model-repository gs://$GSBUCKET --recursive
    
  2. Deployment を使用してフレームワークをデプロイします。Deployment は、クラスタ内のノード間で Pod の複数のレプリカを実行できる Kubernetes API です。

    envsubst < src/gke-config/deployment-tfserve.yaml | kubectl --namespace=gke-ai-namespace apply -f -
    
  3. フレームワークがデプロイされたことを確認します。

    kubectl get deployments --namespace=gke-ai-namespace
    

    フレームワークの準備が整うと、出力は次のようになります。

    NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
    tfserve-deployment   1/1     1            1           5m29s
    
  4. Deployment にアクセスする Service をデプロイします。

    kubectl apply --namespace=gke-ai-namespace -f src/gke-config/service-tfserve.yaml
    
  5. 外部 IP が割り当てられていることを確認します。

    kubectl get services --namespace=gke-ai-namespace
    

    出力は次のようになります。

    NAME            TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                                        AGE
    kubernetes      ClusterIP      34.118.224.1     <none>          443/TCP                                        60m
    tfserve-server  LoadBalancer   34.118.227.176   35.239.54.228   8500:30003/TCP,8000:32194/TCP                  5m14s
    

    EXTERNAL-IP 列にある tfserve-server の IP アドレスをメモします。

  6. Service と Deployment が正常に機能していることを確認します。

    curl -v EXTERNAL_IP:8000/v1/models/mnist
    

    EXTERNAL_IP は、外部 IP アドレスに置き換えます。

    出力は次のようになります。

    ...
    < HTTP/1.1 200 OK
    < Content-Type: application/json
    < Date: Thu, 12 Oct 2023 19:01:19 GMT
    < Content-Length: 154
    <
    {
      "model_version_status": [
            {
            "version": "1",
            "state": "AVAILABLE",
            "status": {
              "error_code": "OK",
              "error_message": ""
            }
          }
        ]
    }
    

モデルを提供する

Triton

  1. Cloud Shell で Python 仮想環境を作成します。

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. 必要な Python パッケージをインストールします。

    pip install -r src/client/triton-requirements.txt
    
  3. 画像を読み込んで Triton Inference Server をテストします。

    cd src/client
    python triton_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

    次のように置き換えます。

    • EXTERNAL_IP: 外部 IP アドレス。
    • TEST_IMAGE: テストする画像のファイル名。src/client/images に保存されている画像を使用できます。

    使用する画像に応じて、出力は次のようになります。

    Calling Triton HTTP Service      ->      Prediction result: 7
    

TF Serving

  1. Cloud Shell で Python 仮想環境を作成します。

    python -m venv ./mnist_client
    source ./mnist_client/bin/activate
    
  2. 必要な Python パッケージをインストールします。

    pip install -r src/client/tfserve-requirements.txt
    
  3. いくつかの画像を使用して TensorFlow Serving をテストします。

    cd src/client
    python tfserve_mnist_client.py -i EXTERNAL_IP -m mnist -p ./images/TEST_IMAGE.png
    

次のように置き換えます。

  • EXTERNAL_IP: 外部 IP アドレス。
  • TEST_IMAGE: 09 の値です。src/client/images に保存されている画像を使用できます。

使用する画像に応じて、次のような出力が表示されます。

  Calling TensorFlow Serve HTTP Service    ->      Prediction result: 5

クリーンアップ

このガイドで作成したリソースについて Google Cloud アカウントに課金されないようにするには、次のいずれかを行います。

  • GKE クラスタを保持する場合: クラスタにある Kubernetes リソースと Google Cloud リソースを削除する
  • Google Cloud プロジェクトを保持する場合: GKE クラスタと Google Cloud リソースを削除する
  • プロジェクトを削除する

クラスタにある Kubernetes リソースと Google Cloud リソースを削除する

  1. Kubernetes Namespace とデプロイしたワークロードを削除します。

Triton

kubectl -n gke-ai-namespace delete -f src/gke-config/service-triton.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-triton.yaml
kubectl delete namespace gke-ai-namespace

TF Serving

kubectl -n gke-ai-namespace delete -f src/gke-config/service-tfserve.yaml
kubectl -n gke-ai-namespace delete -f src/gke-config/deployment-tfserve.yaml
kubectl delete namespace gke-ai-namespace
  1. Cloud Storage バケットを削除します。

    1. [バケット] ページに移動します。

      [バケット] に移動

    2. PROJECT_ID-gke-bucket のチェックボックスをオンにします。

    3. [削除] をクリックします。

    4. 削除を確定するには、「DELETE」と入力して [削除] をクリックします。

  2. Google Cloud サービス アカウントを削除する

    1. [サービス アカウント] ページに移動します。

      [サービス アカウント] に移動

    2. プロジェクトを選択します。

    3. gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com のチェックボックスをオンにします。

    4. [削除] をクリックします。

    5. 削除を確定するには、[削除] をクリックします。

GKE クラスタと Google Cloud リソースを削除する

  1. GKE クラスタを削除します。

    1. [クラスタ] ページに移動します。

      [クラスタ] に移動

    2. online-serving-cluster のチェックボックスをオンにします。

    3. [削除] をクリックします。

    4. 削除を確定するには、「online-serving-cluster」と入力して [削除] をクリックします。

  2. Cloud Storage バケットを削除します。

    1. [バケット] ページに移動します。

      [バケット] に移動

    2. PROJECT_ID-gke-bucket のチェックボックスをオンにします。

    3. [削除] をクリックします。

    4. 削除を確定するには、「DELETE」と入力して [削除] をクリックします。

  3. Google Cloud サービス アカウントを削除する

    1. [サービス アカウント] ページに移動します。

      [サービス アカウント] に移動

    2. プロジェクトを選択します。

    3. gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com のチェックボックスをオンにします。

    4. [削除] をクリックします。

    5. 削除を確定するには、[削除] をクリックします。

プロジェクトを削除する

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

次のステップ