GKE を使用した Cloud TPU での ResNet のトレーニング

目標

このチュートリアルでは、Cloud TPU と GKE で TensorFlow ResNet-50 モデルのトレーニングを行う方法について説明します。

このチュートリアルでは、テスト用に提供されている架空のデータセットを使用してモデルをトレーニングする手順を説明します。

  • モデル出力を格納する Cloud Storage バケットを作成します。
  • Cloud TPU リソースを管理する GKE クラスタを作成します。
  • Kubernetes ジョブ仕様をダウンロードします。このジョブ仕様には、Cloud TPU 上の TensorFlow で ResNet-50 をトレーニングするために必要なリソースが規定されています。
  • GKE クラスタでジョブを実行し、モデルのトレーニングを開始します。
  • ログとモデル出力を確認します。

要件と制限事項

構成を定義する際は、以下の点に注意してください。

  • GKE バージョン 1.13.4-gke.5 以降を使用する必要があります。バージョンを指定するには、下記の説明にあるように、gcloud container clusters create コマンドに --cluster-version パラメータを追加します。バージョンの詳細については、SDK のドキュメントをご覧ください。
  • TensorFlow 1.15.3 以降を使用する必要があります。下記の説明にあるように、Kubernetes ポッド仕様で、Cloud TPU で使用する TensorFlow バージョンを指定してください。
  • GKE クラスタおよびノードプールは、Cloud TPU を使用できるゾーン内に作成する必要があります。トレーニング データとモデルを格納する Cloud Storage バケットも GKE クラスタと同じリージョン内に作成する必要があります。このチュートリアルでは、us-central1-b ゾーンを使用します。
  • 各コンテナがリクエストできる Cloud TPU は 1 つまでですが、1 つの Pod 内の複数のコンテナのそれぞれが Cloud TPU をリクエストできます。
  • クラスタ オートスケーラーは GKE 1.11.4-gke.12 以上で Cloud TPU をサポートします。
  • GKE クラスタは VPC ネイティブ クラスタである必要があります。

始める前に

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    [プロジェクトの選択] ページに移動

  3. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. GKE で Cloud TPU を使用する際に、プロジェクトは Google Cloud の課金対象となるコンポーネントを使用します。Cloud TPU の料金GKE の料金を確認して費用を見積もり、使い終わったら手順に沿ってリソースのクリーンアップを行います。

  5. Cloud Console で次の API を有効にします。

サービス アカウントと Cloud Storage バケットを作成する

機械学習モデルのトレーニング結果を保存するには Cloud Storage バケットが必要です。

  1. Cloud Shell ウィンドウを開きます。

    Cloud Shell を開く

  2. プロジェクト ID の変数を作成します。

    export PROJECT_ID=project-id
    
  3. Cloud TPU プロジェクトのサービス アカウントを作成します。

    gcloud beta services identity create --service tpu.googleapis.com --project $PROJECT_ID
    

    このコマンドでは、Cloud TPU サービス アカウントを次の形式で返します。

    service-PROJECT_NUMBER@cloud-tpu.iam.gserviceaccount.com
    
  4. Cloud Console の Cloud Storage ページに移動します。

    Cloud Storage ページに移動

  5. 次のオプションを指定して新しいバケットを作成します。

    • 任意の一意な名前
    • ロケーション タイプ: region
    • 場所: us-central1
    • デフォルトのストレージ クラス: Standard
    • アクセス制御: fine-grained

    ストレージ バケットを使用する前に、Cloud TPU サービス アカウントにバケットへのアクセス権を付与する必要があります。上のアクセス制御リンクを使用して、Cloud TPU サービス アカウントにきめ細かい ACL を設定します。

Cloud TPU をサポートする GKE クラスタを作成する

新しい GKE クラスタで Cloud TPU のサポートを有効にできます。

Cloud TPU をサポートする新しいクラスタを作成する

Cloud Console または gcloud ツールを使用して、Cloud TPU をサポートするクラスタを作成できます。

以下のオプションを選択し、関連する手順をご覧ください。

Console

Cloud TPU をサポートする GKE クラスタの作成手順は以下のとおりです。

  1. Cloud Console の GKE ページに移動します。

    GKE ページに移動

  2. [クラスタを作成] をクリックします。

  3. クラスタの [名前] を指定します。名前はプロジェクトとゾーン内で一意にする必要があります。

  4. [ロケーション タイプ] として [ゾーン] を選択し、Cloud TPU リソースを使用する予定のゾーンを選択します。このチュートリアルでは、us-central1-b ゾーンを選択します。

  5. Cloud TPU をサポートできるよう、[マスターのバージョン] が 1.13.4-gke.5 以降に設定されていることを確認します。

  6. ナビゲーション パネルの構成するノードプールの下の [セキュリティ] をクリックします。

  7. [すべての Cloud API に完全アクセス権を許可] を選択します。これで、クラスタ内のすべてのノードで Cloud Storage バケットにアクセスできます。この設定を機能させるためには、クラスタとストレージ バケットが同じプロジェクト内に存在していなければなりません。デフォルトでは、Kubernetes Pod はデプロイされているノードのスコープを継承します。ポッド単位でアクセスを制限する場合は、GKE のサービス アカウントで認証するためのガイドをご覧ください。

  8. ナビゲーション パネルの [クラスタ] の下の [ネットワーキング] をクリックします。

  9. [VPC ネイティブのトラフィック ルーティングを有効にする(エイリアス IP を使用)] を選択します。現在のプロジェクトに VPC ネットワークがない場合は VPC ネットワークを作成する必要があります。

  10. ナビゲーション パネルの [クラスタ] の下の [機能] をクリックします。

  11. [Cloud TPU を有効にする] を選択します。

  12. クラスタの残りのオプションを、必要に応じて構成します。デフォルト値のままにしておくこともできます。

  13. [作成] をクリックします。

  14. クラスタに接続します。それには、Console の [Kubernetes クラスタ] ページでクラスタを選択してから [接続] ボタンをクリックします。これにより gcloud コマンドが表示されます。このコマンドを Cloud Shell で実行してクラスタに接続します。

gcloud

gcloud ツールを使用して環境を設定し、Cloud TPU をサポートする GKE クラスタを作成する手順は以下のとおりです。

  1. gcloud コンポーネントをインストールします。GKE を Cloud TPU で実行するには、このコンポーネントが必要です。

    $ gcloud components install kubectl 
  2. gcloud を Google Cloud プロジェクト ID で構成します。

    $ gcloud config set project project-name
    

    project-name は、Google Cloud プロジェクトの名前で置き換えます。

    このコマンドを新しい Cloud Shell VM で初めて実行すると、Authorize Cloud Shell ページが表示されます。ページの下部にある [Authorize] をクリックして、gcloud に認証情報を使用した GCP API の呼び出しを許可します。

  3. Cloud TPU リソースを使用する予定のゾーンで gcloud を構成します。このチュートリアルでは、us-central1-b ゾーンを使用します。

    $ gcloud config set compute/zone us-central1-b
    
  4. Cloud TPU をサポートするクラスタを GKE 上に作成するには、gcloud container clusters create コマンドを使用します。次のコマンドの cluster-name の部分は、任意のクラスタ名に置き換えます。

    $ gcloud container clusters create cluster-name \
      --cluster-version=1.16 \
      --scopes=cloud-platform \
      --enable-ip-alias \
      --enable-tpu
    

    コマンドフラグの説明

    cluster-version
    は、クラスタで最新の Kubernetes 1.16 リリースが使用されるように指定します。バージョン 1.13.4-gke.5 以降を使用する必要があります。
    scopes
    これで、クラスタ内のすべてのノードで Cloud Storage バケットにアクセスできます。この設定を機能させるためには、クラスタとストレージ バケットが同じプロジェクト内に存在していなければなりません。 デフォルトでは、Kubernetes Pod はデプロイされているノードのスコープを継承します。このため、scopes=cloud-platform によりクラスタ内で実行中のすべての Kubernetes Pod に cloud-platform スコープが指定されます。ポッド単位でアクセスを制限する場合は、GKE のサービス アカウントで認証するためのガイドをご覧ください。
    enable-ip-alias
    クラスタでエイリアス IP 範囲が使用されるように指定します。これは、GKE 上で Cloud TPU を使用する場合に必要です。
    enable-tpu
    クラスタで Cloud TPU がサポートされるように指定します。
    tpu-ipv4-cidr(任意。前述のチュートリアルでは指定されていません)
    Cloud TPU に使用する CIDR 範囲を指定します。IP_RANGEIP/20 の形式で指定します(例: 10.100.0.0/20)。このフラグを指定しなければ、/20 サイズの CIDR 範囲が自動的に割り当てられます。

    クラスタが作成されると、次のようなメッセージが表示されます。

    NAME             LOCATION       MASTER_VERSION    MASTER_IP     MACHINE_TYPE   NODE_VERSION      NUM_NODES  STATUS
    cluster-resnet  us-central1-b  1.16.15-gke.4901  34.71.245.25  n1-standard-1  1.16.15-gke.4901  3          RUNNING
    

オペレーションの表示

Cloud TPU サポートを有効にすると、更新オペレーションが始まります。このオペレーションには、ゾーンクラスタの場合は 5 分ほどかかり、リージョン クラスタの場合は 15 分ほどかかります(クラスタのリージョンに応じて異なります)。

クラスタで実行中のオペレーションと完了したオペレーションをすべて一覧表示するには、次のコマンドを実行します。

   $ gcloud container operations list
   

特定のオペレーションの詳細情報を取得するには、次のコマンドを実行します。

   $ gcloud container operations describe operation-id
   

operation-id を、特定のオペレーションの ID に置き換えます。

GKE / ResNet Job の仕様

このチュートリアルで使用する Job 仕様では、TensorFlow 2.3 を使用するプリエンプティブル Cloud TPU v2 デバイスを 1 つリクエストしています。また、TensorBoard プロセスの処理も開始します。

Cloud TPU ノードの存続期間は、それらのノードをリクエストする Kubernetes Pod にバインドされます。Cloud TPU は、Kubernetes Pod がスケジュールされるとオンデマンドで作成され、Kubernetes Pod が削除されるとリサイクルされます。

apiVersion: batch/v1
kind: Job
metadata:
  name: resnet-tpu
spec:
  template:
    metadata:
      annotations:
        # The Cloud TPUs that will be created for this Job will support
        # TensorFlow 2.3. This version MUST match the
        # TensorFlow version that your model is built on.
        tf-version.cloud-tpus.google.com: "2.3"
    spec:
      restartPolicy: Never
      containers:
      - name: resnet-tpu
        # The official TensorFlow 2.3.0 image.
        # https://hub.docker.com/r/tensorflow/tensorflow
        image: tensorflow/tensorflow:2.3.0
        command:
        - bash
        - -c
        - |
          pip install tf-models-official==2.3.0
          python3 -m official.vision.image_classification.resnet.resnet_ctl_imagenet_main \
            --tpu=$(KUBE_GOOGLE_CLOUD_TPU_ENDPOINTS) \
            --distribution_strategy=tpu \
            --steps_per_loop=500 \
            --log_steps=500 \
            --use_synthetic_data=true \
            --dtype=fp32 \
            --enable_tensorboard=true \
            --train_epochs=90 \
            --epochs_between_evals=1 \
            --batch_size=1024 \
            --model_dir=gs://bucket-name/resnet
        resources:
          limits:
            # Request a single Preemptible v2-8 Cloud TPU device to train the
            # model. A single v2-8 Cloud TPU device consists of 4 chips, each of
            # which has 2 cores, so there are 8 cores in total.
            cloud-tpus.google.com/preemptible-v2: 8
      - name: tensorboard
        image: tensorflow/tensorflow:2.2.0
        command:
        - bash
        - -c
        - |
          pip install tensorboard-plugin-profile==2.3.0 cloud-tpu-client
          tensorboard --logdir=gs://bucket-name/resnet --port=6006
        ports:
        - containerPort: 6006

ジョブを作成する

GKE クラスタ内にジョブを作成するには、次の手順に従います。

  1. テキスト エディタを使用して、Job 仕様 example-job.yaml を作成し、上記の Job 仕様にコピーして貼り付けます。--model_dir パラメータと TensorBoard コマンドの bucket-name 変数は、ストレージ バケットの名前に必ず置き換えてください。

  2. ジョブを実行します。

    $ kubectl create -f example-job.yaml
    

    このコマンドは、Pod を自動的にスケジュールして次の出力を返すジョブを作成します。

    job "resnet-tpu" created
  3. Kubernetes Pod がスケジュールされて、Cloud TPU ノードがプロビジョニングされたことを確認します。Cloud TPU ノードをリクエストする Kubernetes Pod は、実行までに 5 分ほど保留されることがあります。Kubernetes Pod がスケジュールされるまでは、次のような出力が表示されます。

    $ kubectl get pods -w
    
    初期出力は次のようになります。
    
    NAME               READY     STATUS    RESTARTS   AGE
    resnet-tpu-cmvlf   0/1       Pending   0          1m
    

    5 分後に、次のような出力が表示されます。

    NAME               READY     STATUS    RESTARTS   AGE
    resnet-tpu-cmvlf   1/1       Running   0          6m
    

  4. STATUSrunning が表示されたら、トレーニングが開始されています。CTRL-C と入力して kubectl get pods -w プロセスを終了します。

Cloud TPU と TensorBoard コンテナのステータスとログを表示する

次の手順に従って、Kubernetes Podで使用される Cloud TPU インスタンスと TensorBoard インスタンスのステータスを確認し、ログを表示します。

  1. 次の手順に従って Deployment と Service の仕様を作成します。

    GKE ページに移動

  2. 左側のナビゲーション バーで [ワークロード] をクリックします。

  3. Job を選択する[マネージド Pod] という見出しを含むページが表示されます。

  4. [マネージド Pod] で、Kubernetes Pod を選択します。[コンテナ] という見出しを含むページに移動します。

  5. [コンテナ] にコンテナのリストが表示されます。このリストには、すべての Cloud TPU インスタンスと TensorBoard インスタンスが含まれます。 各コンテナについて、次の情報が表示されます。

    1. 実行ステータス
    2. コンテナログへのリンク

指標の可視化とパフォーマンス分析に対する、TensorBoard の使用

TensorBoard には、TensorFlow の指標を視覚的に表示するための一連のツールが用意されています。TensorBoard は、処理のボトルネックを識別し、パフォーマンスの改善方法を探る際に役立ちます。

TensorFlow Profiler は、個々の Cloud TPU または Cloud TPU Pod のプロファイルをキャプチャして TensorBoard で可視化できるようにする、TensorBoard プラグインです。可視化ツールとキャプチャできる情報の詳細については、TPU ツールのドキュメントをご覧ください。

GKE クラスタで TensorBoard を実行するには、次の手順に従います。

  1. TensorBoard のステータスを確認する手順に従い、TensorBoard インスタンスがコンテナ内で実行されていることを確認します。

  2. TensorBoard Kubernetes Pod へのポート転送:

    $ kubectl port-forward pod/resnet-tpu-pod-id 6006
    

    ここで、pod-id は、GKE Pod 名の最後の数字のセットであり、コンソールの [Kubernetes Engine] > [ワークロード] > [マネージド Pod] に表示されます。例: resnet-tpu-wxskc

  3. Cloud Shell の右上部にあるバーで [ウェブでプレビュー] ボタンをクリックし、ポート 6006 を開いて TensorBoard の出力を表示します。TensorBoard UI がブラウザにタブとして表示されます。

  4. [TensorBoard] ページの右上にあるプルダウン メニューから [PROFILE] を選択します。

  5. [PROFILE] ページの [CAPTURE PROFILE] ボタンをクリックします。

  6. ポップアップ メニューで、TPU 名のアドレスタイプを選択し、TPU 名を入力します。 Cloud Console の [Compute Engine] > [TPU] ページには、TPU 名が次の形式で表示されます。

    gke-cluster-name-cluster-id-tpu-tpu-id
    
    次に例を示します。
    gke-demo-cluster-25cee208-tpu-4b90f4c5

  7. プロファイリングを開始する準備ができたら、ポップアップ メニューの [CAPTURE] ボタンを選択し、プロファイルが完了するまで数秒待ちます。

  8. ブラウザを更新して、TensorBoard の [PROFILE] タブでトレースデータを表示します。

プロファイルをキャプチャして解釈する方法の詳細については、TensorFlow プロファイラ ガイドをご覧ください。

クリーンアップ

GKE 上で Cloud TPU を使い終わったら、リソースをクリーンアップして、Cloud 請求先アカウントに余分に課金されないようにしてください。

Console

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

  1. Cloud Console の GKE ページに移動します。

    GKE ページに移動

  2. 削除するクラスタの横にあるチェックボックスをオンにします。

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

データの検証が終了したら、このチュートリアルで作成した Cloud Storage バケットを削除します。

  1. Cloud Console の Cloud Storage ページに移動します。

    Cloud Storage ページに移動

  2. 削除するバケットの横にあるチェックボックスをオンにします。

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

無料の保存容量の制限やその他の料金に関する情報については、Cloud Storage の料金ガイドをご覧ください。

gcloud

  1. 次のコマンドを実行して GKE クラスタを削除します。cluster-name をクラスタ名に、project-name を Google Cloud プロジェクト名に置き換えます。

    $ gcloud container clusters delete cluster-name --zone=us-central1-b --project=project-name
    

    このコマンドは、クラスタ、コンテナ、Cloud TPU を削除します。

  2. データの確認が終わったら、gsutil コマンドを使用して、このチュートリアルで作成した Cloud Storage バケットを削除します。bucket-name を該当する Cloud Storage バケットの名前に置き換えます。

    $ gsutil rm -r gs://bucket-name
    

    無料の保存容量の制限やその他の料金に関する情報については、Cloud Storage の料金ガイドをご覧ください。

次のステップ

  • 次のジョブ仕様のいずれかを使用して、他のモデルとデータセット取得ジョブを実行する。

    • GKE に COCO データセットをダウンロードして前処理します。
    • GKE に ImageNet をダウンロードして前処理します。
    • Cloud TPU と GKE を使用して Mask RCNN をトレーニングします。
    • Cloud TPU と GKE を使用して AmoebaNet-D をトレーニングします。
    • Cloud TPU と GKE を使用して Inception v3 をトレーニングします。
    • Cloud TPU と GKE を使用して RetinaNet をトレーニングします。