在 GKE Autopilot 模式中,使用 GPU 訓練模型

本快速入門導覽課程說明如何在 Google Kubernetes Engine (GKE) 中使用 GPU 部署訓練模型,並將預測結果儲存在 Cloud Storage 中。本文適用於已有 Autopilot 模式叢集,且想首次執行 GPU 工作負載的 GKE 管理員。

您也可以在標準叢集上執行這些工作負載,只要在叢集中建立個別的 GPU 節點集區即可。如需操作說明,請參閱「在 GKE Standard 模式下使用 GPU 訓練模型」。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the GKE and Cloud Storage APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  5. 安裝 Google Cloud CLI。

  6. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  7. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  8. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  9. Verify that billing is enabled for your Google Cloud project.

  10. Enable the GKE and Cloud Storage APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  11. 安裝 Google Cloud CLI。

  12. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  13. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  14. 在 Google Cloud 控制台中啟用 Cloud Shell。

    啟用 Cloud Shell

    Google Cloud 主控台底部會開啟一個 Cloud Shell 工作階段,並顯示指令列提示。Cloud Shell 是已安裝 Google Cloud CLI 的殼層環境,並已針對您目前的專案設定好相關值。工作階段可能要幾秒鐘的時間才能初始化。

複製範例存放區

在 Cloud Shell 中執行下列指令:

git clone https://github.com/GoogleCloudPlatform/ai-on-gke && \
cd ai-on-gke/tutorials-and-examples/gpu-examples/training-single-gpu

建立叢集

  1. 前往 Google Cloud 控制台的「建立 Autopilot 叢集」頁面:

    前往「Create an Autopilot cluster」(建立 Autopilot 叢集) 頁面

  2. 在「Name」(名稱) 欄位中,輸入 gke-gpu-cluster

  3. 在「Region」(區域) 清單中選取「us-central1」。

  4. 點選「建立」

建立 Cloud Storage bucket

  1. 前往 Google Cloud 控制台的「建立 bucket」頁面:

    前往「建立 bucket」

  2. 在「開始使用」專區中,輸入 bucket 的全域不重複名稱:

    PROJECT_ID-gke-gpu-bucket
    

    PROJECT_ID 替換為 Google Cloud專案 ID。

  3. 按一下「繼續」

  4. 在「位置類型」部分,選取「區域」

  5. 在「Region」(區域) 清單中選取「us-central1 (Iowa)」,然後按一下「Continue」(繼續)

  6. 在「Choose a storage class for your data」(為資料選擇儲存空間級別) 專區中,按一下「Continue」(繼續)

  7. 在「Choose how to control access to objects」(選取如何控制物件的存取權) 專區中,將「Access control」(存取控管) 設為「Uniform」(統一)

  8. 點選「建立」

  9. 在「系統會禁止公開存取」對話方塊中,確認已選取「強制禁止公開存取這個 bucket」核取方塊,然後按一下「確認」

設定叢集,透過 Workload Identity Federation for GKE 存取儲存空間

如要讓叢集存取 Cloud Storage bucket,請執行下列操作:

  1. 在叢集中建立 Kubernetes ServiceAccount。
  2. 建立 IAM 允許政策,讓 ServiceAccount 存取值區。

在叢集中建立 Kubernetes ServiceAccount

在 Cloud Shell 中執行下列操作:

  1. 連線至叢集:

    gcloud container clusters get-credentials gke-gpu-cluster \
        --location=us-central1
    
  2. 建立 Kubernetes 命名空間:

    kubectl create namespace gke-gpu-namespace
    
  3. 在命名空間中建立 Kubernetes ServiceAccount:

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

在值區中建立 IAM 允許政策

在 bucket 上將 Storage 物件管理員 (roles/storage.objectAdmin) 角色授予 Kubernetes ServiceAccount:

gcloud storage buckets add-iam-policy-binding gs://PROJECT_ID-gke-gpu-bucket \
    --member=principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.svc.id.goog/subject/ns/gke-gpu-namespace/sa/gpu-k8s-sa \
    --role=roles/storage.objectAdmin \
    --condition=None

PROJECT_NUMBER 替換為您的 Google Cloud專案編號。

確認 Pod 可以存取 Cloud Storage bucket

  1. 在 Cloud Shell 中建立下列環境變數:

    export K8S_SA_NAME=gpu-k8s-sa
    export BUCKET_NAME=PROJECT_ID-gke-gpu-bucket
    

    PROJECT_ID 替換為 Google Cloud專案 ID。

  2. 建立具有 TensorFlow 容器的 Pod:

    envsubst < src/gke-config/standard-tensorflow-bash.yaml | kubectl --namespace=gke-gpu-namespace apply -f -
    

    這個指令會將您建立的環境變數插入資訊清單中的對應參照。您也可以在文字編輯器中開啟資訊清單,然後將 $K8S_SA_NAME$BUCKET_NAME 替換為對應的值。

  3. 在 bucket 中建立範例檔案:

    touch sample-file
    gcloud storage cp sample-file gs://PROJECT_ID-gke-gpu-bucket
    
  4. 等待 Pod 準備就緒:

    kubectl wait --for=condition=Ready pod/test-tensorflow-pod -n=gke-gpu-namespace --timeout=180s
    

    Pod 準備就緒時,輸出內容如下:

    pod/test-tensorflow-pod condition met
    

    如果指令逾時,GKE 可能仍在建立新的節點來執行 Pod。再次執行指令,並等待 Pod 準備就緒。

  5. 在 TensorFlow 容器中開啟殼層:

    kubectl -n gke-gpu-namespace exec --stdin --tty test-tensorflow-pod --container tensorflow -- /bin/bash
    
  6. 嘗試讀取您建立的範例檔案:

    ls /data
    

    輸出畫面會顯示範例檔案。

  7. 查看記錄,找出附加至 Pod 的 GPU:

    python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU'))"
    

    輸出內容會顯示附加至 Pod 的 GPU,如下所示:

    ...
    PhysicalDevice(name='/physical_device:GPU:0',device_type='GPU')
    
  8. 退出容器:

    exit
    
  9. 刪除範例 Pod:

    kubectl delete -f src/gke-config/standard-tensorflow-bash.yaml \
        --namespace=gke-gpu-namespace
    

使用 MNIST 資料集訓練及預測

在本節中,您將在 MNIST 範例資料集上執行訓練工作負載。

  1. 將範例資料複製到 Cloud Storage bucket:

    gcloud storage cp src/tensorflow-mnist-example gs://PROJECT_ID-gke-gpu-bucket/ --recursive
    
  2. 建立下列的環境變數:

    export K8S_SA_NAME=gpu-k8s-sa
    export BUCKET_NAME=PROJECT_ID-gke-gpu-bucket
    
  3. 查看訓練工作:

    # Copyright 2023 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: mnist-training-job
    spec:
      template:
        metadata:
          name: mnist
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-tesla-t4
          tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:latest-gpu 
            command: ["/bin/bash", "-c", "--"]
            args: ["cd /data/tensorflow-mnist-example; pip install -r requirements.txt; python tensorflow_mnist_train_distributed.py"]
            resources:
              limits:
                nvidia.com/gpu: 1
                cpu: 1
                memory: 3Gi
            volumeMounts:
            - name: gcs-fuse-csi-vol
              mountPath: /data
              readOnly: false
          serviceAccountName: $K8S_SA_NAME
          volumes:
          - name: gcs-fuse-csi-vol
            csi:
              driver: gcsfuse.csi.storage.gke.io
              readOnly: false
              volumeAttributes:
                bucketName: $BUCKET_NAME
                mountOptions: "implicit-dirs"
          restartPolicy: "Never"
  4. 部署訓練工作:

    envsubst < src/gke-config/standard-tf-mnist-train.yaml | kubectl -n gke-gpu-namespace apply -f -
    

    這個指令會將您建立的環境變數,替換為資訊清單中的對應參照。您也可以在文字編輯器中開啟資訊清單,然後將 $K8S_SA_NAME$BUCKET_NAME 替換為對應的值。

  5. 等待工作達到 Completed 狀態:

    kubectl wait -n gke-gpu-namespace --for=condition=Complete job/mnist-training-job --timeout=180s
    

    工作就緒時,輸出內容會類似下列內容:

    job.batch/mnist-training-job condition met
    

    如果指令逾時,GKE 可能仍在建立新的節點來執行 Pod。再次執行指令,並等待工作準備就緒。

  6. 檢查 TensorFlow 容器的記錄:

    kubectl logs -f jobs/mnist-training-job -c tensorflow -n gke-gpu-namespace
    

    輸出內容會顯示發生下列事件:

    • 安裝必要的 Python 套件
    • 下載 MNIST 資料集
    • 使用 GPU 訓練模型
    • 儲存模型
    • 評估模型
    ...
    Epoch 12/12
    927/938 [============================>.] - ETA: 0s - loss: 0.0188 - accuracy: 0.9954
    Learning rate for epoch 12 is 9.999999747378752e-06
    938/938 [==============================] - 5s 6ms/step - loss: 0.0187 - accuracy: 0.9954 - lr: 1.0000e-05
    157/157 [==============================] - 1s 4ms/step - loss: 0.0424 - accuracy: 0.9861
    Eval loss: 0.04236088693141937, Eval accuracy: 0.9861000180244446
    Training finished. Model saved
    
  7. 刪除訓練工作負載:

    kubectl -n gke-gpu-namespace delete -f src/gke-config/standard-tf-mnist-train.yaml
    

部署推論工作負載

在本節中,您將部署推論工作負載,以範例資料集做為輸入內容,並傳回預測結果。

  1. 將用於預測的圖片複製到 bucket:

    gcloud storage cp data/mnist_predict gs://PROJECT_ID-gke-gpu-bucket/ --recursive
    
  2. 查看推論工作負載:

    # Copyright 2023 Google LLC
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    #      http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: mnist-batch-prediction-job
    spec:
      template:
        metadata:
          name: mnist
          annotations:
            gke-gcsfuse/volumes: "true"
        spec:
          nodeSelector:
            cloud.google.com/gke-accelerator: nvidia-tesla-t4
          tolerations:
          - key: "nvidia.com/gpu"
            operator: "Exists"
            effect: "NoSchedule"
          containers:
          - name: tensorflow
            image: tensorflow/tensorflow:latest-gpu 
            command: ["/bin/bash", "-c", "--"]
            args: ["cd /data/tensorflow-mnist-example; pip install -r requirements.txt; python tensorflow_mnist_batch_predict.py"]
            resources:
              limits:
                nvidia.com/gpu: 1
                cpu: 1
                memory: 3Gi
            volumeMounts:
            - name: gcs-fuse-csi-vol
              mountPath: /data
              readOnly: false
          serviceAccountName: $K8S_SA_NAME
          volumes:
          - name: gcs-fuse-csi-vol
            csi:
              driver: gcsfuse.csi.storage.gke.io
              readOnly: false
              volumeAttributes:
                bucketName: $BUCKET_NAME
                mountOptions: "implicit-dirs"
          restartPolicy: "Never"
  3. 部署推論工作負載:

    envsubst < src/gke-config/standard-tf-mnist-batch-predict.yaml | kubectl -n gke-gpu-namespace apply -f -
    

    這個指令會將您建立的環境變數,替換為資訊清單中的對應參照。您也可以在文字編輯器中開啟資訊清單,然後將 $K8S_SA_NAME$BUCKET_NAME 替換為對應的值。

  4. 等待工作達到 Completed 狀態:

    kubectl wait -n gke-gpu-namespace --for=condition=Complete job/mnist-batch-prediction-job --timeout=180s
    

    輸出結果會與下列內容相似:

    job.batch/mnist-batch-prediction-job condition met
    
  5. 檢查 TensorFlow 容器的記錄:

    kubectl logs -f jobs/mnist-batch-prediction-job -c tensorflow -n gke-gpu-namespace
    

    輸出內容會顯示每張圖片的預測結果,以及模型對預測結果的信心程度,如下所示:

    Found 10 files belonging to 1 classes.
    1/1 [==============================] - 2s 2s/step
    The image /data/mnist_predict/0.png is the number 0 with a 100.00 percent confidence.
    The image /data/mnist_predict/1.png is the number 1 with a 99.99 percent confidence.
    The image /data/mnist_predict/2.png is the number 2 with a 100.00 percent confidence.
    The image /data/mnist_predict/3.png is the number 3 with a 99.95 percent confidence.
    The image /data/mnist_predict/4.png is the number 4 with a 100.00 percent confidence.
    The image /data/mnist_predict/5.png is the number 5 with a 100.00 percent confidence.
    The image /data/mnist_predict/6.png is the number 6 with a 99.97 percent confidence.
    The image /data/mnist_predict/7.png is the number 7 with a 100.00 percent confidence.
    The image /data/mnist_predict/8.png is the number 8 with a 100.00 percent confidence.
    The image /data/mnist_predict/9.png is the number 9 with a 99.65 percent confidence.
    

清除所用資源

如要避免系統向您的 Google Cloud 帳戶收取本指南所建立資源的費用,請採取下列任一做法:

  • 保留 GKE 叢集:刪除叢集中的 Kubernetes 資源和 Google Cloud 資源
  • 保留專案:刪除 GKE 叢集和 Google Cloud 資源 Google Cloud
  • 刪除專案

刪除叢集中的 Kubernetes 資源和 Google Cloud 資源

  1. 刪除 Kubernetes 命名空間和您部署的工作負載:

    kubectl -n gke-gpu-namespace delete -f src/gke-config/standard-tf-mnist-batch-predict.yaml
    kubectl delete namespace gke-gpu-namespace
    
  2. 刪除 Cloud Storage bucket:

    1. 前往「Buckets」(值區) 頁面:

      前往值區

    2. 勾選 PROJECT_ID-gke-gpu-bucket 的核取方塊。

    3. 按一下「刪除」圖示

    4. 如要確認刪除,請輸入 DELETE,然後按一下「刪除」

  3. 刪除 Google Cloud 服務帳戶:

    1. 前往「Service accounts」(服務帳戶) 頁面:

      前往「Service accounts」(服務帳戶)

    2. 選取專案。

    3. 勾選 gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com 的核取方塊。

    4. 按一下「刪除」圖示

    5. 如要確認刪除,請按一下「刪除」

刪除 GKE 叢集和 Google Cloud 資源

  1. 刪除 GKE 叢集:

    1. 前往「Clusters」(叢集) 頁面:

      前往「Clusters」(叢集)

    2. 勾選 gke-gpu-cluster 的核取方塊。

    3. 按一下「刪除」圖示

    4. 如要確認刪除,請輸入 gke-gpu-cluster,然後按一下「刪除」

  2. 刪除 Cloud Storage bucket:

    1. 前往「Buckets」(值區) 頁面:

      前往值區

    2. 勾選 PROJECT_ID-gke-gpu-bucket 的核取方塊。

    3. 按一下「刪除」圖示

    4. 如要確認刪除,請輸入 DELETE,然後按一下「刪除」

  3. 刪除 Google Cloud 服務帳戶:

    1. 前往「Service accounts」(服務帳戶) 頁面:

      前往「Service accounts」(服務帳戶)

    2. 選取專案。

    3. 勾選 gke-gpu-sa@PROJECT_ID.iam.gserviceaccount.com 的核取方塊。

    4. 按一下「刪除」圖示

    5. 如要確認刪除,請按一下「刪除」

刪除專案

  1. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)
  3. 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。

後續步驟