GKE Standard に TPU ワークロードをデプロイする

このページでは、Google Kubernetes Engine(GKE)で TPU を使用して ML ワークロードを高速化する方法を学習するための基礎について説明します。TPU は、大規模なディープ ラーニング モデルのトレーニングなどの行列乗算処理用に設計されています。ML の巨大なデータセットと複雑なモデルの処理に最適化されているため、優れたパフォーマンスにより ML ワークロードの費用対効果とエネルギー効率が向上します。このガイドでは、Cloud TPU アクセラレータを使用して ML ワークロードをデプロイする方法、TPU の割り当てを構成する方法、TPU を実行するノードプールのアップグレードを構成する方法、TPU ワークロード指標をモニタリングする方法について説明します。

このチュートリアルは、TPU を使用する大規模なモデルのトレーニング、チューニング、推論ワークロードの管理に Kubernetes コンテナ オーケストレーションを使用することに関心のある ML エンジニアおよびプラットフォームの管理者とオペレーターを対象としています。 Google Cloud のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。

このページを読む前に、次のことをよく理解しておいてください。

始める前に

作業を始める前に、次のタスクが完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update コマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。

TPU 構成を計画する

モデルと必要なメモリ量に基づいて TPU 構成を計画します。このガイドに沿って TPU にワークロードをデプロイする前に、TPU 構成を計画するの手順を完了してください。

TPU の割り当てがあることを確認する

以降のセクションでは、GKE で TPU を使用するときに十分な割り当てを確保できるようにします。

オンデマンド VM または Spot VM の割り当て

オンデマンド VM または Spot VM で TPU スライス ノードプールを作成する場合は、使用するリージョンに十分な TPU の割り当てが必要です。

TPU 予約を使用する TPU スライス ノードプールの作成には、TPU の割り当ては必要ありません1。予約済みの TPU については、この手順はスキップしてもかまいません。

GKE でオンデマンドまたは Spot TPU スライス ノードプールを作成するには、Compute Engine API の割り当てが必要です。Compute Engine API の割り当て(compute.googleapis.com)は、Cloud TPU API の割り当て(tpu.googleapis.com)とは異なります。これは、Cloud TPU API を使用して TPU を作成するときに必要です。

TPU 用の Compute Engine API の割り当ての上限と現在の使用量を確認するには、次の操作を行います。

  1. Google Cloud コンソールで [割り当て] ページに移動します。

    [割り当て] に移動

  2. [ フィルタ] ボックスで次の操作を行います。

    1. 次の表を使用して、TPU のバージョンとマシンタイプに基づいて割り当てのプロパティを選択してコピーします。たとえば、マシンタイプが「ct5lp-」で始まるオンデマンド TPU v5e ノードを作成する場合は、「Name: TPU v5 Lite PodSlice chips」と入力します。

      TPU バージョン、次で始まるマシンタイプ オンデマンド インスタンスの割り当てのプロパティと名前 Spot2 インスタンスの割り当てのプロパティと名前
      TPU v3、
      ct3-
      Dimensions (e.g. location):
      tpu_family:CT3
      該当なし
      TPU v3、
      ct3p-
      Dimensions (e.g. location):
      tpu_family:CT3P
      該当なし
      TPU v4、
      ct4p-
      Name:
      TPU v4 PodSlice chips
      Name:
      Preemptible TPU v4 PodSlice chips
      TPU v5e、
      ct5lp-
      Name:
      TPU v5 Lite PodSlice chips
      Name:
      Preemptible TPU v5 Lite Podslice
      chips
      TPU v5p、
      ct5p-
      Name:
      TPU v5p chips
      Name:
      Preemptible TPU v5p chips
      TPU Trillium、
      ct6e-
      Dimensions (e.g. location):
      tpu_family:CT6E
      Name:
      Preemptible TPU slices v6e
    2. [項目(ロケーションなど)] プロパティを選択し、「region:」に続けて、GKE で TPU を作成するリージョンの名前を入力します。たとえば、ゾーン us-west4-a で TPU スライスノードを作成する場合は、「region:us-west4」と入力します。TPU の割り当てはリージョン単位であるため、同じリージョン内のすべてのゾーンで同じ TPU の割り当てが消費されます。

入力したフィルタに一致する割り当てがない場合、プロジェクトには目的のリージョンで指定した割り当てのいずれも付与されていないため、TPU 割り当ての調整をリクエストする必要があります。

TPU 予約が作成されると、対応する割り当ての上限と現在の使用量の値は、TPU 予約のチップ数の分だけ増加します。たとえば、マシンタイプが ct5lp- で始まる 16 個の TPU v5e チップの予約を作成すると、関連するリージョンの TPU v5 Lite PodSlice chips 割り当ての上限現在の使用量の両方が 16 増加します。

  1. TPU スライス ノードプールを作成する場合は、--reservation フラグと --reservation-affinity=specific フラグを使用して、予約済みインスタンスを作成します。TPU の予約は、コミットメントを購入した場合に利用できます。

  2. Spot インスタンスは、TPU スライス ノードプールの作成時に --spot フラグを使用して作成します。

追加の GKE リソースの割り当て

GKE がリソースを作成するリージョンで、次の GKE 関連の割り当てを増やす必要がある場合があります。

  • Persistent Disk SSD(GB)割り当て: 各 Kubernetes ノードのブートディスクにはデフォルトで 100 GB 必要です。そのため、この割り当ては、少なくとも、作成する予定の GKE ノードの最大数と 100 GB の積(ノード × 100 GB)以上の値に設定する必要があります。
  • 使用中の IP アドレスの割り当て: 各 Kubernetes ノードは 1 つの IP アドレスを消費します。そのため、この割り当てには、少なくとも作成することが予想される GKE ノードの最大数を設定する必要があります。
  • max-pods-per-node がサブネット範囲と一致していることを確認する: 各 Kubernetes ノードは、Pod にセカンダリ IP 範囲を使用します。たとえば、max-pods-per-node が 32 の場合、64 個の IP アドレスが必要になります。これはノードあたり /26 サブネットに相当します。この範囲は他のクラスタと共有しないでください。IP アドレス範囲が使い果たされないようにするには、--max-pods-per-node フラグを使用して、ノードでスケジュールできる Pod の数を制限します。max-pods-per-node の割り当ては、作成する予定の GKE ノードの最大数と同じ値に設定する必要があります。

割り当ての増加をリクエストするには、割り当ての調整をリクエストするをご覧ください。

予約の可用性を確保する

予約を使用して TPU スライス ノードプールを作成するには、ノードプールの作成時に予約に十分な使用可能な TPU チップが必要です。

プロジェクト内に存在する予約と、TPU 予約で使用可能な TPU チップ数を確認するには、予約のリストを表示します。

GKE で TPU をプロビジョニングする場合のオプション

GKE では、ワークロード マニフェストで Kubernetes nodeSelector を使用するか、TPU を使用して Standard モードのノードプールを作成することで、個々のワークロードで TPU を直接使用できます。

また、カスタム コンピューティング クラスを使用して TPU をリクエストすることもできます。カスタム コンピューティング クラスを使用すると、プラットフォーム管理者は、ノード スケーリングの決定時に GKE が優先順位を付けるノードの構成の階層を定義して、ワークロードが選択したハードウェアで実行されるようにできます。

手順については、カスタム コンピューティング クラスを使用して TPU をプロビジョニングするをご覧ください。

クラスタを作成する

使用可能な TPU があるリージョンに Standard モードで GKE クラスタを作成します。

ベスト プラクティス:

Kubernetes コントロール プレーンの高可用性を実現するリージョン クラスタを使用します。

gcloud container clusters create CLUSTER_NAME \
  --location LOCATION \
  --cluster-version VERSION

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

  • CLUSTER_NAME: 新しいクラスタの名前。
  • LOCATION: TPU の容量が使用可能なリージョン。
  • VERSION: GKE バージョン。使用するマシンタイプをサポートしている必要があります。デフォルトの GKE バージョンは、ターゲット TPU で利用できない場合があります。TPU マシンタイプで使用できる最小 GKE バージョンについては、GKE での TPU の可用性をご覧ください。

ノードプールを作成する

単一ホストまたはマルチホストの TPU スライス ノードプールを作成できます。

単一ホスト TPU スライス ノードプールを作成する

Google Cloud CLI、Terraform、または Google Cloud コンソールを使用して、単一ホスト TPU スライス ノードプールを作成できます。

gcloud

gcloud container node-pools create NODE_POOL_NAME \
    --location=LOCATION \
    --cluster=CLUSTER_NAME \
    --node-locations=NODE_ZONES \
    --machine-type=MACHINE_TYPE \
    [--sandbox=type=gvisor]

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

  • NODE_POOL_NAME: 新しいノードプールの名前。
  • LOCATION: 使用する TPU バージョンに基づくゾーンの名前。使用可能なロケーションについては、GKE での TPU の可用性をご覧ください。
  • CLUSTER_NAME: クラスタの名前。
  • NODE_ZONES: GKE がノードプールを作成する 1 つ以上のゾーンのカンマ区切りリスト。
  • MACHINE_TYPE: ノードに使用するマシンのタイプ。TPU 互換マシンタイプの詳細については、TPU バージョンを選択するの表をご覧ください。

必要に応じて、次のフラグも使用できます。

  • --num-nodes=NUM_NODES: 各ゾーンのノードプール内のノードの初期数。このフラグを省略すると、GKE はデフォルトの 3 を割り当てます。

    ベスト プラクティス:

    ノードプールに enable-autoscaling フラグを使用する場合は、num-nodes0 に設定して、ワークロードで必要になるとオートスケーラーが追加のノードを直ちにプロビジョニングするようにします。

  • --reservation=RESERVATION_NAME: ノードプールの作成時に GKE が使用する予約の名前。このフラグを省略すると、GKE は使用可能な TPU を使用します。TPU 予約の詳細については、Cloud TPU の予約についてをご覧ください。

  • --node-labels cloud.google.com/gke-workload-type=HIGH_AVAILABILITY: 単一ホスト TPU スライス ノードプールがコレクションの一部であることを GKE に伝えます。このフラグは、次の条件に該当する場合に使用します。

    • ノードプールが、新しいノードプールで推論ワークロードを実行する。
    • ノードプールが TPU Trillium を使用する。
    • ノードプールが Spot VM を使用していない。

    コレクションのスケジュール設定の管理の詳細については、単一ホスト TPU スライスでコレクションのスケジュール設定を管理するをご覧ください。

  • --enable-autoscaling: 自動スケーリングが有効なノードプールを作成します。次の追加フラグが必要です。

    • --total-min-nodes=TOTAL_MIN_NODES: ノードプール内のノードの最小数。
    • --total-max-nodes=TOTAL_MAX_NODES: ノードプール内のノードの最大数。
    • --location-policy=ANY: 未使用の予約を使用することを優先し、Spot VM のプリエンプション リスクを軽減します。
  • --spot: ノードプール内のノードに Spot VM を使用するようにノードプールを設定します。これは、ノードプールの作成後に変更することはできません。

  • --flex-start: Flex Start VM を使用するようにノードプールを設定します。Flex Start VM は、GKE バージョン 1.33.0-gke.1712000 以降でサポートされている Flex Start 使用オプションを使用して作成されます。

  • --sandbox=type=gvisor: GKE Sandbox が有効になっているノードをプロビジョニングします。TPU v4 以降のバージョンが必要です。詳細については、GKE Sandbox をご覧ください。

指定できるすべてのフラグの一覧については、gcloud container clusters create リファレンスをご覧ください。

Terraform

  1. google プロバイダのバージョン 4.84.0 以降を使用していることを確認します。
  2. Terraform 構成に次のブロックを追加します。
resource "google_container_node_pool" "NODE_POOL_RESOURCE_NAME" {
  provider           = google
  project            = PROJECT_ID
  cluster            = CLUSTER_NAME
  name               = POOL_NAME
  location           = CLUSTER_LOCATION
  node_locations     = [NODE_ZONES]

  node_config {
    machine_type = MACHINE_TYPE
    reservation_affinity {
      consume_reservation_type = "SPECIFIC_RESERVATION"
      key = "compute.googleapis.com/reservation-name"
      values = [RESERVATION_LABEL_VALUES]
    }
    spot = true
    flex_start = false
  }
}

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

  • NODE_POOL_RESOURCE_NAME: Terraform テンプレートのノードプール リソースの名前。
  • PROJECT_ID: プロジェクト ID。
  • CLUSTER_NAME: 既存のクラスタの名前。
  • POOL_NAME: 作成するノードプールの名前。
  • CLUSTER_LOCATION: クラスタのコンピューティング ゾーン。TPU バージョンを利用できるリージョンを指定します。詳細については、TPU のバージョンとトポロジの選択をご覧ください。
  • NODE_ZONES: GKE がノードプールを作成する 1 つ以上のゾーンのカンマ区切りリスト。
  • MACHINE_TYPE: 使用する TPU マシンのタイプ。TPU 互換マシンタイプを確認するには、TPU のバージョンを選択するの表をご覧ください。

必要に応じて、次の変数を使用することもできます。

  • autoscaling: 自動スケーリングが有効なノードプールを作成します。単一ホストの TPU スライスの場合、GKE は TOTAL_MIN_NODESTOTAL_MAX_NODES の値の間でスケーリングを行います。
    • TOTAL_MIN_NODES: ノードプール内のノードの最小数。自動スケーリングを指定しない場合、このフィールドは省略可能です。
    • TOTAL_MAX_NODES: ノードプール内のノードの最大数。自動スケーリングを指定しない場合、このフィールドは省略可能です。
  • RESERVATION_NAME: Cloud TPU 予約についてを使用する場合、これはノードプールの作成時に使用する予約リソースのラベルのリストです。reservation_affinity フィールドに RESERVATION_LABEL_VALUES を挿入する方法については、Terraform プロバイダをご覧ください。
  • spot: TPU ノードに Spot VM を使用するようにノードプールを設定します。これは、ノードプールの作成後に変更することはできません。詳細については、Spot VM をご覧ください。
  • flex_start: Flex Start 使用オプションを使用するようにノードプールを設定します。spot が有効になっている場合、true に設定することはできません。Flex Start は、GKE バージョン 1.33.0-gke.1712000 以降でサポートされています。

コンソール

TPU を使用してノードプールを作成するには:

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. クラスタのリストで、変更するクラスタの名前をクリックします。

  3. [ノードプールを追加] をクリックします。

  4. [ノードプールの詳細] セクションで、[ノードのロケーションを指定する] チェックボックスをオンにします。

  5. 使用する TPU のバージョンに基づいてゾーンを選択します。使用可能なゾーンについては、GKE での TPU の可用性をご覧ください。

  6. ナビゲーション パネルで [ノード] をクリックします。

  7. [マシンの構成] セクションで、[TPU] を選択します。

  8. [シリーズ] プルダウン メニューで、次のいずれかを選択します。

    • CT3: TPU v3、単一ホストデバイス
    • CT3P: TPU v3、マルチホスト Pod スライス
    • CT4P: TPU v4
    • CT5LP: TPU v5e
    • CT5P: TPU v5p
    • CT6E: TPU Trillium(v6e)
  9. [マシンタイプ] プルダウン メニューで、ノードに使用するマシンの名前を選択します。TPU バージョンを選択するの表で、単一ホスト TPU スライス ノードプールを作成するマシンタイプと TPU トポロジを定義する方法を確認します。

  10. [TPU トポロジ] プルダウン メニューで、TPU スライスの物理トポロジを選択します。

  11. [変更が必要です] ダイアログで [変更を適用] をクリックします。

  12. [ブートディスクの種類] が [標準永続ディスク] と [SSD 永続ディスク] のいずれかであることを確認します。

  13. 必要に応じて、[Spot VM 上にノードを作成する] チェックボックスをオンにして、ノードプール内のノードで Spot VM を使用します。

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

マルチホスト TPU スライス ノードプールを作成する

Google Cloud CLI、Terraform、または Google Cloud コンソールを使用して、マルチホスト TPU スライス ノードプールを作成できます。

gcloud

gcloud container node-pools create POOL_NAME \
    --location=LOCATION \
    --cluster=CLUSTER_NAME \
    --node-locations=NODE_ZONES \
    --machine-type=MACHINE_TYPE \
    --tpu-topology=TPU_TOPOLOGY \
    [--num-nodes=NUM_NODES] \
    [--spot \]
    [--flex-start \]
    [--enable-autoscaling \
      --max-nodes MAX_NODES]
    [--reservation-affinity=specific \
    --reservation=RESERVATION_NAME] \
    [--node-labels cloud.google.com/gke-nodepool-group-name=COLLECTION_NAME,cloud.google.com/gke-workload-type=HIGH_AVAILABILITY]
    [--placement-type=COMPACT]

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

  • POOL_NAME: 新しいノードプールの名前。
  • LOCATION: 使用する TPU バージョンに基づくゾーンの名前。使用可能なロケーションについては、GKE での TPU の可用性をご覧ください。
  • CLUSTER_NAME: クラスタの名前。
  • NODE_ZONES: GKE がノードプールを作成する 1 つ以上のゾーンのカンマ区切りリスト。
  • MACHINE_TYPE: ノードに使用するマシンのタイプ。使用可能なマシンタイプの詳細については、TPU バージョンを選択するをご覧ください。
  • TPU_TOPOLOGY: TPU スライスの物理トポロジ。トポロジの形式は TPU のバージョンによって異なります。TPU トポロジの詳細については、トポロジを選択するの表をご覧ください。

    詳細については、トポロジをご覧ください。

必要に応じて、次のフラグも使用できます。

  • NUM_NODES: ノードプール内のノード数。ゼロにするか、TPU_TOPOLOGY{A}x{B}x{C})で定義された値の積を各 VM のチップ数で割った数と同じにする必要があります。マルチホスト TPU v4 と TPU v5e の場合、各 VM のチップ数は 4 です。したがって、TPU_TOPOLOGY2x4x4(各 VM に 4 つのチップがある TPU v4)の場合、NUM_NODES は 32÷4 で 8 になります。このフラグを省略すると、ノード数が計算され、トポロジとマシンタイプに基づいてデフォルトが設定されます。
  • RESERVATION_NAME: ノードプールの作成時に GKE が使用する予約の名前。このフラグを省略すると、GKE は使用可能な TPU スライス ノードプールを使用します。TPU 予約の詳細については、TPU 予約をご覧ください。
  • --spot: TPU スライスノードに Spot VM を使用するようにノードプールを設定します。これは、ノードプールの作成後に変更することはできません。詳細については、Spot VM をご覧ください。
  • --flex-start: Flex Start VM を使用するようにノードプールを設定します。Flex Start VM は、GKE バージョン 1.33.0-gke.1712000 以降でサポートされている Flex Start 使用オプションを使用して作成されます。
  • --enable-autoscaling: 自動スケーリングが有効なノードプールを作成します。GKE がマルチホスト TPU スライス ノードプールをスケーリングすると、ノードプールがゼロから最大サイズまでアトミックにスケールアップされます。

    • MAX_NODES: ノードグループの最大サイズ。--enable-autoscaling が指定されている場合、--max-nodes フラグは必須です。TPU_TOPOLOGY{A}x{B}x{C})で定義された値の積を、各 VM のチップ数で割った数と同じにする必要があります。
  • --node-label=cloud.google.com/gke-nodepool-group-name=COLLECTION_NAME, cloud.google.com/gke-workload-type=HIGH_AVAILABILITY: マルチホスト TPU スライス ノードプールがコレクションであることを GKE に伝えます。このフラグは、次の条件に該当する場合に使用します。

    • ノードプールが、新しいノードプールで推論ワークロードを実行する。
    • ノードプールが TPU Trillium を使用する。
    • Spot VM が、コレクションのスケジュール設定をサポートしていない。

    コレクションのスケジュール設定の管理の詳細については、マルチホスト TPU スライスでコレクションのスケジュール設定を管理するをご覧ください。

  • --placement-type=COMPACT: コンパクト プレースメントを有効にしてノードプールを作成します。このオプションは、--tpu-topology フラグとともに使用する必要があります。詳細については、コンパクト プレースメント ポリシーを作成するTPU トポロジをご覧ください。

Terraform

  1. google プロバイダのバージョン 4.84.0 以降を使用していることを確認します。
  2. Terraform 構成に次のブロックを追加します。

    resource "google_container_node_pool" "NODE_POOL_RESOURCE_NAME" {
      provider           = google
      project            = PROJECT_ID
      cluster            = CLUSTER_NAME
      name               = POOL_NAME
      location           = CLUSTER_LOCATION
      node_locations     = [NODE_ZONES]
      initial_node_count = NUM_NODES
    
      autoscaling {
        max_node_count = MAX_NODES
        location_policy      = "ANY"
      }
      node_config {
        machine_type = MACHINE_TYPE
        reservation_affinity {
          consume_reservation_type = "SPECIFIC_RESERVATION"
          key = "compute.googleapis.com/reservation-name"
          values = [RESERVATION_LABEL_VALUES]
        }
        spot = true
        flex_start = false
      }
    
      placement_policy {
        type = "COMPACT"
        tpu_topology = TPU_TOPOLOGY
      }
    }
    

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

    • NODE_POOL_RESOURCE_NAME: Terraform テンプレートのノードプール リソースの名前。
    • PROJECT_ID: プロジェクト ID。
    • CLUSTER_NAME: ノードプールを追加する既存のクラスタの名前。
    • POOL_NAME: 作成するノードプールの名前。
    • CLUSTER_LOCATION: クラスタのコンピューティングのロケーション。Kubernetes コントロール プレーンの信頼性を高めるため、リージョン クラスタを使用することをおすすめします。ゾーンクラスタを使用することもできます。詳細については、TPU のバージョンとトポロジの選択をご覧ください。
    • NODE_ZONES: GKE がノードプールを作成する 1 つ以上のゾーンのカンマ区切りリスト。
    • NUM_NODES: ノードプール内のノード数。この値はゼロにするか、TPU チップの数を 4 で割った数のプロダクトにする必要があります。これは、マルチホスト TPU スライスでは各 TPU スライスノードに 4 つのチップがあるためです。たとえば、TPU_TOPOLOGY4x8 の場合、32 チップがあるため、NUM_NODES は 8 にする必要があります。TPU トポロジの詳細については、TPU バージョンを選択するの表をご覧ください。
    • TPU_TOPOLOGY: TPU スライスに必要な物理トポロジを示します。トポロジの形式は、使用している TPU のバージョンによって異なります。TPU トポロジの詳細については、トポロジを選択するの表をご覧ください。

    必要に応じて、次の変数を使用することもできます。

    • RESERVATION_NAME: TPU 予約を使用する場合、これはノードプールの作成時に使用する予約リソースのラベルのリストです。reservation_affinity フィールドに RESERVATION_LABEL_VALUES を挿入する方法については、Terraform プロバイダをご覧ください。
    • autoscaling: 自動スケーリングが有効なノードプールを作成します。GKE がマルチホスト TPU スライス ノードプールをスケーリングすると、ノードプールがゼロから最大サイズまでアトミックにスケールアップされます。
      • MAX_NODES: ノードプールの最大サイズです。TPU_TOPOLOGY{A}x{B}x{C})で定義された値の積を各 VM のチップ数で割った数と同じにする必要があります。
    • spot: TPU スライスノードに Spot VM を使用するようにノードプールを設定します。これは、ノードプールの作成後に変更することはできません。詳細については、Spot VM をご覧ください。
    • flex_start: Flex Start 使用オプションを使用するようにノードプールを設定します。spot が有効になっている場合、true に設定することはできません。

コンソール

TPU を使用してノードプールを作成するには:

  1. Google Cloud コンソールで [Google Kubernetes Engine] ページに移動します。

    Google Kubernetes Engine に移動

  2. クラスタのリストで、変更するクラスタの名前をクリックします。

  3. [ノードプールを追加] をクリックします。

  4. [ノードプールの詳細] セクションで、[ノードのロケーションを指定する] チェックボックスをオンにします。

  5. 使用する TPU バージョンに基づくゾーンの名前を選択します。使用可能なロケーションについては、GKE での TPU の可用性をご覧ください。

  6. ナビゲーション パネルで [ノード] をクリックします。

  7. [マシンの構成] セクションで、[TPU] を選択します。

  8. [シリーズ] プルダウン メニューで、次のいずれかを選択します。

    • CT3P: TPU v3 の場合。
    • CT4P: TPU v4 の場合。
    • CT5LP: TPU v5e の場合。
  9. [マシンタイプ] プルダウン メニューで、ノードに使用するマシンの名前を選択します。TPU バージョンを選択するの表で、マルチホスト TPU スライス ノードプールを作成するマシンタイプと TPU トポロジを定義する方法を確認します。

  10. [TPU トポロジ] プルダウン メニューで、TPU スライスの物理トポロジを選択します。

  11. [変更が必要です] ダイアログで [変更を適用] をクリックします。

  12. [ブートディスクの種類] が [標準永続ディスク] と [SSD 永続ディスク] のいずれかであることを確認します。

  13. 必要に応じて、[Spot VM 上にノードを作成する] チェックボックスをオンにして、ノードプール内のノードで Spot VM を使用します。

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

GKE が容量の問題を処理する方法

使用可能な TPU 容量が不足しているために GKE が TPU スライス ノードプールを作成できない場合、GKE は、容量不足が原因で TPU スライスノードを作成できないことを示すエラー メッセージを返します。

単一ホスト TPU スライス ノードプールを作成している場合は、次のようなエラー メッセージが表示されます。

2 nodes cannot be created due to lack of capacity. The missing nodes will be
created asynchronously once capacity is available. You can either wait for the
nodes to be up, or delete the node pool and try re-creating it again later.

マルチホスト TPU スライス ノードプールを作成している場合は、次のようなエラー メッセージが表示されます。

The nodes (managed by ...) cannot be created now due to lack of capacity. They
will be created asynchronously once capacity is available. You can either wait
for the nodes to be up, or delete the node pool and try re-creating it again
later.

TPU プロビジョニング リクエストは長時間キューに留まり、キューにある間は「プロビジョニング」状態のままになります。

容量が利用可能になると、GKE は作成されていない残りのノードを作成します。

すぐに容量が必要な場合は、Spot VM の使用を検討してください。ただし、Spot VM は、オンデマンド インスタンスとは異なる割り当てを消費します

キューに格納された TPU リクエストを削除するには、TPU スライス ノードプールを削除します。

TPU スライスノードでワークロードを実行する

このセクションでは、ワークロードを準備する方法と、ワークロードを実行する方法の例について説明します。

ワークロードを準備する

TPU ワークロードには、次の準備要件があります。

  1. JAX、PyTorch、TensorFlow などのフレームワークは、libtpu 共有ライブラリを使用して TPU VM にアクセスします。libtpu には、XLA コンパイラ、TPU ランタイム ソフトウェア、TPU ドライバが含まれています。PyTorch と JAX の各リリースには、特定の libtpu.so バージョンが必要です。パッケージ バージョンの競合を避けるため、JAX AI イメージを使用することをおすすめします。GKE で TPU を使用するには、次のバージョンを使用してください。
    TPU タイプ libtpu.so のバージョン
    TPU Trillium(v6e)
    tpu-v6e-slice
    TPU v5e
    tpu-v5-lite-podslice
    TPU v5p
    tpu-v5p-slice
    • 推奨される JAX AI イメージ: jax0.4.35-rev1 以降
    • 推奨される jax[tpu] バージョン: 0.4.19 以降
    • 推奨される torchxla[tpuvm] バージョン: 毎晩更新されるバージョンの 2023 年 10 月 23 日付のビルドを使用することをおすすめします。
    TPU v4
    tpu-v4-podslice
    TPU v3
    tpu-v3-slice
    tpu-v3-device
  2. TPU リソースをリクエストするコンテナに、次の環境変数を設定します。
    • TPU_WORKER_ID: 各 Pod の一意の整数。この ID は、TPU スライス内の一意のワーカー ID を示します。このフィールドでサポートされる値の範囲は、0 から Pod 数から 1 を引いた値までです。
    • TPU_WORKER_HOSTNAMES: スライス内で相互に通信する必要がある TPU VM ホスト名または IP アドレスのカンマ区切りのリスト。スライス内の TPU VM ごとにホスト名または IP アドレスが必要です。IP アドレスまたはホスト名のリストは、TPU_WORKER_ID によって順序付けされ、ゼロのインデックスが付けられます。
    • GKE は、completionMode: Indexedsubdomainparallelism > 1 で Job が作成され、google.com/tpu プロパティをリクエストしたときに、変更用 Webhook を使用してこれらの環境変数を自動的に挿入します。また、Service の背後にある Pod の DNS レコードが追加されるように、ヘッドレス Service が追加されます。

      Kuberay を使用して TPU マルチホスト リソースをデプロイする場合、GKE は、Ray on GKE を実行するための試験運用版 Terraform テンプレートの一部として、デプロイ可能な Webhook を提供します。TPU を使用して Ray on GKE を実行する手順については、試験運用版 TPU ユーザーガイドをご覧ください。変更用の Webhook は、これらの環境変数を Ray クラスタに挿入し、google.com/tpu プロパティとマルチホスト cloud.google.com/gke-tpu-topology ノードセレクタをリクエストします。

    • ワークロード マニフェストに Kubernetes ノードセレクタを追加して、定義した TPU マシンタイプと TPU トポロジで、GKE が TPU ワークロードをスケジュールできるようにします。

        nodeSelector:
          cloud.google.com/gke-tpu-accelerator: TPU_ACCELERATOR
          cloud.google.com/gke-tpu-topology: TPU_TOPOLOGY
        

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

      • TPU_ACCELERATOR: TPU アクセラレータの名前。
      • TPU_TOPOLOGY: TPU スライスの物理トポロジ。トポロジの形式は TPU のバージョンによって異なります。詳細については、GKE で TPU を計画するをご覧ください。

ワークロードの準備が完了したら、TPU を使用する Job を実行できます。

以降のセクションでは、TPU で基本的な計算を実行する Job の実行例を示します。

例 1: TPU スライス ノードプールで使用可能な TPU チップの数を表示するワークロードを実行する

次のワークロードは、マルチホスト TPU スライス内のノード全体の TPU チップ数を返します。マルチホスト スライスを作成する場合、ワークロードに次のパラメータを設定します。

  • TPU バージョン: TPU v4
  • トポロジ: 2x2x4

このバージョンとトポロジの選択により、マルチホスト スライスが作成されます。

  1. 次のマニフェストを available-chips-multihost.yaml として保存します。
    apiVersion: v1
    kind: Service
    metadata:
      name: headless-svc
    spec:
      clusterIP: None
      selector:
        job-name: tpu-available-chips
    ---
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: tpu-available-chips
    spec:
      backoffLimit: 0
      completions: 4
      parallelism: 4
      completionMode: Indexed
      template:
        spec:
          subdomain: headless-svc
          restartPolicy: Never
          nodeSelector:
            cloud.google.com/gke-tpu-accelerator: tpu-v4-podslice # Node selector to target TPU v4 slice nodes.
            cloud.google.com/gke-tpu-topology: 2x2x4 # Specifies the physical topology for the TPU slice.
          containers:
          - name: tpu-job
            image: us-docker.pkg.dev/cloud-tpu-images/jax-ai-image/tpu:latest
            ports:
            - containerPort: 8471 # Default port using which TPU VMs communicate
            - containerPort: 8431 # Port to export TPU runtime metrics, if supported.
            securityContext:
              privileged: true # Required for GKE versions earlier than 1.28 to access TPUs.
            command:
            - bash
            - -c
            - |
              python -c 'import jax; print("TPU cores:", jax.device_count())' # Python command to count available TPU chips.
            resources:
              requests:
                cpu: 10
                memory: 407Gi
                google.com/tpu: 4 # Request 4 TPU chips for this workload.
              limits:
                cpu: 10
                memory: 407Gi
                google.com/tpu: 4 # Limit to 4 TPU chips for this workload.
  2. マニフェストをデプロイします。
    kubectl create -f available-chips-multihost.yaml
    

    GKE は、4 つの VM(マルチホスト TPU スライス)を使用して TPU v4 スライスを実行します。スライスには、相互接続された 16 個の TPU チップがあります。

  3. Job によって 4 つの Pod が作成されたことを確認します。
    kubectl get pods
    

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

    NAME                       READY   STATUS      RESTARTS   AGE
    tpu-job-podslice-0-5cd8r   0/1     Completed   0          97s
    tpu-job-podslice-1-lqqxt   0/1     Completed   0          97s
    tpu-job-podslice-2-f6kwh   0/1     Completed   0          97s
    tpu-job-podslice-3-m8b5c   0/1     Completed   0          97s
    
  4. いずれかの Pod のログを取得します。
    kubectl logs POD_NAME
    

    POD_NAME は、作成した Pod の名前に置き換えます。例: tpu-job-podslice-0-5cd8r

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

    TPU cores: 16
    
  5. 省略可: ワークロードを削除します。
    kubectl delete -f available-chips-multihost.yaml
    

例 2: TPU スライスで使用可能な TPU チップの数を表示するワークロードを実行する

次のワークロードは、特定のノードに関連付けられている TPU チップの数を表示する静的 Pod です。単一ホストノードを作成するには、ワークロードに次のパラメータを設定します。

  • TPU バージョン: TPU v5e
  • トポロジ: 2x4

このバージョンとトポロジを選択すると、単一ホストのスライスが作成されます。

  1. 次のマニフェストを available-chips-singlehost.yaml として保存します。
    apiVersion: v1
    kind: Pod
    metadata:
      name: tpu-job-jax-v5
    spec:
      restartPolicy: Never
      nodeSelector:
        cloud.google.com/gke-tpu-accelerator: tpu-v5-lite-podslice # Node selector to target TPU v5e slice nodes.
        cloud.google.com/gke-tpu-topology: 2x4 # Specify the physical topology for the TPU slice.
      containers:
      - name: tpu-job
        image: us-docker.pkg.dev/cloud-tpu-images/jax-ai-image/tpu:latest
        ports:
        - containerPort: 8431 # Port to export TPU runtime metrics, if supported.
        securityContext:
          privileged: true # Required for GKE versions earlier than 1.28 to access TPUs.
        command:
        - bash
        - -c
        - |
          python -c 'import jax; print("Total TPU chips:", jax.device_count())'
        resources:
          requests:
            google.com/tpu: 8 # Request 8 TPU chips for this container.
          limits:
            google.com/tpu: 8 # Limit to 8 TPU chips for this container.
  2. マニフェストをデプロイします。
    kubectl create -f available-chips-singlehost.yaml
    

    GKE は、TPU v5e を使用する 8 つの単一ホスト TPU スライスを含むノードをプロビジョニングします。各 TPU ノードには 8 個の TPU チップがあります(単一ホストの TPU スライス)。

  3. Pod のログを取得します。
    kubectl logs tpu-job-jax-v5
    

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

    Total TPU chips: 8
    
  4. 省略可: ワークロードを削除します。
      kubectl delete -f available-chips-singlehost.yaml
      

アクセラレータ(GPU と TPU)を使用するノードプールをアップグレードする

GKE は、ノードプールを含む Standard クラスタを自動的にアップグレードします。ノードを新しいバージョンに早急に移行する必要がある場合は、ノードプールを手動でアップグレードすることもできます。クラスタのアップグレードの動作を制御するには、リリース チャンネルメンテナンスの時間枠と除外ロールアウトのシーケンスを使用します。

サージ アップグレードBlue/Green アップグレード短期間のアップグレードなど、ノードプールのノード アップグレード戦略を構成することもできます。これらの戦略を構成することで、環境の速度と中断の最適なバランスが実現されるようにノードプールをアップグレードできます。マルチホスト TPU スライス ノードプールの場合、GKE は、構成済みのノード アップグレード戦略を使用せずに、1 つのステップでノードプール全体をアトミックに再作成します。詳細については、GKE の TPU に関連する用語の「アトミック性」の定義をご覧ください。

ノードのアップグレード戦略を使用する場合は、構成に応じて、GKE が一時的に追加のリソースをプロビジョニングする必要があります。 Google Cloudでノードプールのリソースの容量が限られている場合(たとえば、GPU または TPU を使用してノードを追加しようとするとリソースの可用性エラーが表示される場合)は、リソースが制限された環境でのアップグレードをご覧ください。

クリーンアップ

このガイドで使用したリソースについて Google Cloud アカウントに課金されないようにするには、ワークロードのスケジュールがなくなった TPU スライス ノードプールの削除を検討してください。実行中のワークロードを正常に終了する必要がある場合は、ノードを削除する前に kubectl drain を使用してワークロードをクリーンアップします。

  1. TPU スライス ノードプールを削除します。

    gcloud container node-pools delete POOL_NAME \
        --location=LOCATION \
        --cluster=CLUSTER_NAME
    

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

    • POOL_NAME: ノードプールの名前。
    • CLUSTER_NAME: クラスタの名前。
    • LOCATION: クラスタの Compute Engine のロケーション。

追加設定を構成する

以降のセクションでは、TPU ワークロードに適用できる追加の構成について説明します。

コレクション スケジューリングを管理する

TPU Trillium では、コレクション スケジューリングを使用して TPU スライスノードをグループ化できます。これらの TPU スライスノードをグループ化すると、ワークロードの需要に合わせてレプリカの数を簡単に調整できます。 Google Cloud はソフトウェア アップデートを制御し、コレクション内に十分なスライスが常にあり、トラフィックの処理に使用できるようにします。

TPU Trillium は、推論ワークロードを実行する単一ホスト ノードプールとマルチホスト ノードプールのコレクション スケジューリングをサポートしています。次の表に示すのは、コレクション スケジューリング動作が使用する TPU スライスのタイプにどのように依存するかです。

  • マルチホスト TPU スライス: GKE はマルチホスト TPU スライスをグループ化してコレクションを形成します。各 GKE ノードプールは、このコレクション内のレプリカです。コレクションを定義するには、マルチホスト TPU スライスを作成し、コレクションに一意の名前を割り当てます。コレクションに TPU スライスを追加するには、同じコレクション名とワークロード タイプを持つ別のマルチホスト TPU スライス ノードプールを作成します。
  • 単一ホストの TPU スライス: GKE は、単一ホストの TPU スライス ノードプール全体をコレクションと見なします。コレクションに TPU スライスを追加するには、単一ホストの TPU スライス ノードプールのサイズを変更します。

コレクションを管理するには、使用するノードプールのタイプに基づいて、次のいずれかの操作を行います。

マルチホスト TPU スライス ノードプールでコレクション スケジューリングを管理する

マルチホスト TPU スライス ノードプールを管理するには、次のタスクを使用します。

  • マルチホスト TPU スライスプールがコレクションの一部であるかどうかを確認するには、次のコマンドを実行します。

    gcloud container node-pools describe NODE_POOL_NAME \
        --location LOCATION \
        --cluster CLUSTER_NAME \
        --format="json" | jq -r \
        '"nodepool-group-name: \(.config.labels["cloud.google.com/gke-nodepool-group-name"] // "")\ngke-workload-type: \(.config.labels["cloud.google.com/gke-workload-type"] // "")"'
    

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

    nodepool-group-name: <code><var>NODE_POOL_COLLECTION_NAME</var></code>
    gke-workload-type: HIGH_AVAILABILITY
    

    マルチホスト TPU スライスプールがコレクションの一部である場合、出力に次のラベルが含まれます。

    • cloud.google.com/gke-workload-type: HIGH_AVAILABILITY
    • cloud.google.com/gke-nodepool-group-name: <code><var>COLLECTION_NAME</var></code>
  • クラスタ内のコレクションのリストを取得するには、次のコマンドを実行します。

    #!/bin/bash
    
    # Replace with your cluster name, project, and location
    CLUSTER_NAME=CLUSTER_NAME
    PROJECT=PROJECT_ID
    LOCATION=LOCATION
    
    declare -A collection_names
    
    node_pools=$(gcloud container node-pools list --cluster "$CLUSTER_NAME" --project "$PROJECT" --location "$LOCATION" --format="value(name)")
    
    # Iterate over each node pool
    for pool in $node_pools; do
        # Describe the node pool and extract labels using jq
        collection_name=$(gcloud container node-pools describe "$pool" \
            --cluster "$CLUSTER_NAME" \
            --project "$PROJECT" \
            --location "$LOCATION" \
            --format="json" | jq -r '.config.labels["cloud.google.com/gke-nodepool-group-name"]')
    
        # Add the collection name to the associative array if it's not empty
        if [[ -n "$collection_name" ]]; then
            collection_names["$collection_name"]=1
        fi
    done
    
    # Print the unique node pool collection names
    echo "Unique cloud.google.com/gke-nodepool-group-name values:"
    for name in "${!collection_names[@]}"; do
        echo "$name"
    done
    

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

    Unique cloud.google.com/gke-nodepool-group-name values: {COLLECTION_NAME_1}, {COLLECTION_NAME_2}, {COLLECTION_NAME_3}
    
  • コレクションに属するノードプールのリストを取得するには、次のコマンドを実行します。

    #!/bin/bash
    
    TARGET_COLLECTION_NAME=COLLECTION_NAME
    CLUSTER_NAME=CLUSTER_NAME
    PROJECT=PROJECT_ID
    LOCATION=LOCATION
    
    matching_node_pools=()
    
    # Get the list of all node pools in the cluster
    node_pools=$(gcloud container node-pools list --cluster "$CLUSTER_NAME" --project "$PROJECT" --location "$LOCATION" --format="value(name)")
    
    # Iterate over each node pool
    for pool in $node_pools; do
        # Get the value of the cloud.google.com/gke-nodepool-group-name label
        collection_name=$(gcloud container node-pools describe "$pool" \
            --cluster "$CLUSTER_NAME" \
            --project "$PROJECT" \
            --location "$LOCATION" \
            --format="json" | jq -r '.config.labels["cloud.google.com/gke-nodepool-group-name"]')
    
        # Check if the group name matches the target value
        if [[ "$collection_name" == "$TARGET_COLLECTION_NAME" ]]; then
            matching_node_pools+=("$pool")
        fi
    done
    
    # Print the list of matching node pools
    echo "Node pools with collection name '$TARGET_COLLECTION_NAME':"
    for pool in "${matching_node_pools[@]}"; do
        echo "$pool"
    done
    

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

    Node pools with collection name 'COLLECTION_NAME':
    {NODE_POOL_NAME_1}
    {NODE_POOL_NAME_2}
    {NODE_POOL_NAME_3}
    
  • コレクションをスケールアップするには、別のマルチホスト TPU スライス ノードプールを作成し、cloud.google.com/gke-workload-typecloud.google.com/gke-nodepool-group-name を追加します。cloud.google.com/gke-nodepool-group-name で同じコレクション名を使用し、同じワークロード タイプを実行します。クラスタでノード自動プロビジョニングが有効になっている場合、GKE はワークロードの需要に基づいてプールを自動的に作成します。

  • コレクションをスケールダウンするには、ノードプールを削除します。

  • コレクションを削除するには、関連付けられているすべてのノードプールを削除します。ノードプールを削除するか、クラスタを削除できます。クラスタを削除すると、クラスタ内のすべてのコレクションが削除されます。

単一ホスト TPU スライス ノードプールでコレクション スケジューリングを管理する

単一ホスト TPU スライス ノードプールを管理するには、次のタスクを使用します。

  • 単一ホスト TPU スライスプールでコレクション スケジューリングが有効になっているかどうかを確認するには、次のコマンドを実行します。

    gcloud container node-pools describe NODE_POOL_NAME \
        --cluster CLUSTER_NAME \
        --project PROJECT_NAME \
        --location LOCATION \
        --format="json" | jq -r '.config.labels["cloud.google.com/gke-workload-type"]'
    

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

    gke-workload-type: HIGH_AVAILABILITY
    

    単一ホスト TPU スライスプールがコレクションの一部である場合、出力に cloud.google.com/gke-workload-type: HIGH_AVAILABILITY ラベルが含まれます。

  • コレクションをスケールアップするには、ノードプールを手動でサイズ変更するか、ノード自動プロビジョニングを使用して自動的にサイズ変更します。

  • コレクションをスケールダウンするには、ノードプールを削除します。

  • コレクションを削除するには、関連付けられているすべてのノードプールを削除します。ノードプールを削除するか、クラスタを削除できます。クラスタを削除すると、クラスタ内のすべてのコレクションが削除されます。

マルチスライスを使用する

小さなスライスをマルチスライスに集約して、より大きなトレーニング ワークロードを処理できます。詳細については、GKE のマルチスライス TPU をご覧ください。

TPU 予約を移行する

既存の TPU 予約がある場合は、まず TPU 予約を新しい Compute Engine ベースの予約システムに移行する必要があります。移行が不要な Compute Engine ベースの予約システムを作成することもできます。TPU 予約を移行する方法については、TPU 予約をご覧ください。

ロギングを有効にする

TPU VM を含む GKE ノード上で実行されているコンテナによって出力されたログは、GKE ロギング エージェントが収集し、Logging に送信して、Logging に表示します。

GKE ノードの自動プロビジョニングを使用する

TPU ワークロードのリソース需要を満たすように、ノードプールを自動的に作成および削除するように GKE を構成できます。詳細については、Cloud TPU の構成をご覧ください。

カスタム コンピューティング クラスを使用して TPU をプロビジョニングする

カスタム コンピューティング クラスを使用して、新しいノードを作成するスケーリング オペレーション中に TPU をリクエストするように GKE を構成することもできます。

カスタム コンピューティング クラスの仕様で TPU 構成オプションを指定できます。GKE ワークロードがそのカスタム コンピューティング クラスを使用している場合、GKE はスケールアップ時に、指定された構成を使用する TPU をプロビジョニングしようとします。

TPU ルールに従うカスタム コンピューティング クラスを使用して TPU をプロビジョニングし、ワークロードをデプロイするには、次の手順で操作します。

  1. 次のマニフェストを tpu-compute-class.yaml として保存します。

    apiVersion: cloud.google.com/v1
    kind: ComputeClass
    metadata:
      name: tpu-class
    spec:
      priorities:
      - tpu:
          type: tpu-v5-lite-podslice
          count: 4
          topology: 2x4
      - spot: true
        tpu:
          type: tpu-v5-lite-podslice
          count: 4
          topology: 2x4
      - flexStart:
          enabled: true
        tpu:
          type: tpu-v6e-slice
          count: 4
          topology: 2x4
      nodePoolAutoCreation:
        enabled: true
    
  2. コンピューティング クラスをデプロイします。

    kubectl apply -f tpu-compute-class.yaml
    

    カスタム コンピューティング クラスと TPU の詳細については、TPU の構成をご覧ください。

  3. 次のマニフェストを tpu-job.yaml として保存します。

    apiVersion: v1
    kind: Service
    metadata:
      name: headless-svc
    spec:
      clusterIP: None
      selector:
        job-name: tpu-job
    ---
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: tpu-job
    spec:
      backoffLimit: 0
      completions: 4
      parallelism: 4
      completionMode: Indexed
      template:
        spec:
          subdomain: headless-svc
          restartPolicy: Never
          nodeSelector:
            cloud.google.com/compute-class: tpu-class
          containers:
          - name: tpu-job
            image: us-docker.pkg.dev/cloud-tpu-images/jax-ai-image/tpu:latest
            ports:
            - containerPort: 8471 # Default port using which TPU VMs communicate
            - containerPort: 8431 # Port to export TPU runtime metrics, if supported.
            command:
            - bash
            - -c
            - |
              python -c 'import jax; print("TPU cores:", jax.device_count())'
            resources:
              requests:
                cpu: 10
                memory: MEMORY_SIZE
                google.com/tpu: NUMBER_OF_CHIPS
              limits:
                cpu: 10
                memory: MEMORY_SIZE
                google.com/tpu: NUMBER_OF_CHIPS
    

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

    • NUMBER_OF_CHIPS: コンテナで使用する TPU チップの数。limitsrequests の値は同じにする必要があります。また、選択したカスタムのコンピューティング クラスの tpu.count フィールドの値と同じにする必要があります。
    • MEMORY_SIZE: TPU が使用するメモリの最大量。メモリ上限は、使用する TPU のバージョンとトポロジによって異なります。詳しくは、アクセラレータの最小値と最大値をご覧ください。
    • NUMBER_OF_CHIPS: 使用するコンテナの TPU チップの数。limitsrequests の値は同じにする必要があります。
  4. Job をデプロイします。

    kubectl create -f tpu-job.yaml
    

    この Job を作成すると、GKE は自動的に次の処理を行います。

    • Pod を実行するノードをプロビジョニングします。指定した TPU タイプ、トポロジ、リソース リクエストに応じて、これらのノードは単一ホストスライスまたはマルチホスト スライスのいずれかになります。GKE は最優先の TPU リソースの可用性に応じて優先度の低いリソースにフォールバックし、取得可能性を最大化できます。
    • Pod に taint を追加してノードに toleration を追加し、他のワークロードが TPU ワークロードと同じノードで実行されないようにします。

    詳しくは、カスタムのコンピューティング クラスについてをご覧ください。

  5. このセクションを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。

    kubectl delete -f tpu-job.yaml
    

TPU スライスノードの自動修復を構成する

マルチホスト TPU スライス ノードプール内の TPU スライスノードが異常な場合は、ノードプール全体が再作成されます。一方、単一ホスト TPU スライス ノードプールでは、異常な TPU ノードのみが自動修復されます。

TPU スライスノードが異常な状態になる条件は次のとおりです。

  • 共通のノード条件を持つ TPU スライスノード。
  • 割り当てできない TPU 数が 0 より大きい TPU スライスノード。
  • プリエンプションにより停止または終了した TPU スライスの VM インスタンス。
  • ノードのメンテナンス: マルチホスト TPU スライス ノードプール内の TPU スライスノードがホスト メンテナンスのために停止した場合、GKE は TPU スライス ノードプール全体を再作成します。

修復ステータス(失敗の理由を含む)はオペレーション履歴で確認できます。割り当て不足が原因でエラーが発生する場合は、Google Cloud アカウント担当者に連絡して、対応する割り当ての増加をリクエストしてください。

TPU スライスノードの正常終了を構成する

コントロール プレーンで 1.29.1-gke.1425000 以降が実行されている GKE クラスタでは、TPU スライスノードはシャットダウンの差し迫ったノードに警告する SIGTERM シグナルをサポートしています。TPU ノードでは、最大 5 分前のシャットダウン通知を構成できます。

この通知期間内にワークロードを正常に終了するように GKE を構成するには、GPU と TPU の GKE ノードの中断を管理するの手順に沿って操作します。

特権モードを使用せずコンテナを実行する

GKE バージョン 1.28 以降のノードで実行されるコンテナでは、TPU にアクセスするために特権モードを有効にする必要はありません。GKE バージョン 1.28 以前のノードでは、特権モードが必要です。

TPU スライスノードがバージョン 1.28 以前で実行されている場合は、次のセクションをご覧ください。

TPU スライスの VM 上で実行されるコンテナでは、直接メモリアクセス(DMA)によってドライバが TPU チップと通信できるように、ロックメモリの上限を引き上げる必要があります。これを有効にするには、上位の ulimit を構成する必要があります。コンテナの権限スコープを縮小するには、次の操作を行います。

  1. securityContext を編集して次のフィールドを含めます。

    securityContext:
      capabilities:
        add: ["SYS_RESOURCE"]
    
  2. TPU リソースを使用するようにワークロードを設定する前に、コンテナ内で次のコマンドを実行して ulimit を増やします。

    ulimit -l 68719476736
    

TPU v5e の場合、バージョン 1.27.4-gke.900 以降のクラスタで特権モードなしでコンテナを実行できます。

オブザーバビリティと指標

ダッシュボード

Google Cloud コンソールのノードプール オブザーバビリティが一般提供になりました。GKE の TPU マルチホスト ノードプールのステータスを表示するには、Cloud Monitoring が提供する [GKE TPU Node Pool Status] ダッシュボードに移動します。

[GKE TPU Node Pool Status] に移動

このダッシュボードでは、マルチホスト TPU ノードプールの健全性に関する包括的な分析情報を確認できます。詳細については、TPU ノードとノードプールの健全性指標をモニタリングするをご覧ください。

Google Cloud コンソールの [Kubernetes クラスタ] ページの [オブザーバビリティ] タブにも TPU オブザーバビリティ指標が表示されます([アクセラレータ > TPU] 見出しの下の TPU 使用率など)。詳細については、オブザーバビリティ指標を表示するをご覧ください。

TPU ダッシュボードは、GKE クラスタでシステム指標が有効になっている場合にのみ表示されます。

ランタイム指標

GKE バージョン 1.27.4-gke.900 以降、JAX バージョン 0.4.14 以降を使用し containerPort: 8431 を指定する TPU ワークロードでは、TPU 使用率の指標を GKE システム指標としてエクスポートします。Cloud Monitoring では、TPU ワークロードのランタイム パフォーマンスをモニタリングするために、次の指標を使用できます。

  • デューティ サイクル: 過去のサンプリング期間(60 秒)において、TensorCore が TPU チップでアクティブに処理していた時間の割合。割合が大きいほど、TPU 使用率が高くなります。
  • メモリ使用量: 割り当てられたアクセラレータ メモリの量(バイト単位)。60 秒ごとにサンプリングされます。
  • メモリの総容量: アクセラレータの総メモリ(バイト単位)。60 秒ごとにサンプリングされます。

これらの指標は、Kubernetes ノード(k8s_node)と Kubernetes コンテナ(k8s_container)のスキーマにあります。

Kubernetes コンテナ:

  • kubernetes.io/container/accelerator/duty_cycle
  • kubernetes.io/container/accelerator/memory_used
  • kubernetes.io/container/accelerator/memory_total

Kubernetes ノード:

  • kubernetes.io/node/accelerator/duty_cycle
  • kubernetes.io/node/accelerator/memory_used
  • kubernetes.io/node/accelerator/memory_total

TPU ノードとノードプールの健全性指標をモニタリングする

トレーニング ジョブでエラーが発生した場合や、トレーニング ジョブが失敗して終了した場合は、基盤となるインフラストラクチャに関連する指標を確認して、中断の原因が基盤となるノードまたはノードプールの問題であるかどうかを判断できます。

ノードのステータス

GKE バージョン 1.32.1-gke.1357001 以降では、次の GKE システム指標が GKE ノードの状態を公開します。

  • kubernetes.io/node/status_condition

condition フィールドは、ReadyDiskPressureMemoryPressure などのノードの状態を報告します。status フィールドには、その状態について報告されたステータス(TrueFalseUnknown)が表示されます。これは、k8s_node モニタリング対象リソースタイプの指標です。

この PromQL クエリは、特定のノードが Ready かどうかを示します。

kubernetes_io:node_status_condition{
    monitored_resource="k8s_node",
    cluster_name="CLUSTER_NAME",
    node_name="NODE_NAME",
    condition="Ready",
    status="True"}

クラスタの問題のトラブルシューティングを行うには、他の状態を示しているノードを確認します。

kubernetes_io:node_status_condition{
    monitored_resource="k8s_node",
    cluster_name="CLUSTER_NAME",
    condition!="Ready",
    status="True"}

Ready ではないノードを確認することもできます。

kubernetes_io:node_status_condition{
    monitored_resource="k8s_node",
    cluster_name="CLUSTER_NAME",
    condition="Ready",
    status="False"}

データがない場合、ノードは準備完了です。ステータス状態は 60 秒ごとにサンプリングされます。

次のクエリを使用すると、フリート全体のノードのステータスを把握できます。

avg by (condition,status)(
  avg_over_time(
    kubernetes_io:node_status_condition{monitored_resource="k8s_node"}[${__interval}]))

ノードプールのステータス

k8s_node_pool モニタリング対象リソースの次の GKE システム指標は、GKE ノードプールのステータスを公開します。

  • kubernetes.io/node_pool/status

この指標は、マルチホスト TPU ノードプールに対してのみ報告されます。

status フィールドは、ノードプールのステータス(ProvisioningRunningErrorReconcilingStopping など)を報告します。ステータスの更新は、GKE API オペレーションの完了後に行われます。

特定のノードプールが Running ステータスかどうかを確認するには、次の PromQL クエリを使用します。

kubernetes_io:node_pool_status{
    monitored_resource="k8s_node_pool",
    cluster_name="CLUSTER_NAME",
    node_pool_name="NODE_POOL_NAME",
    status="Running"}

プロジェクト内のノードプールの数をステータス別にモニタリングするには、次の PromQL クエリを使用します。

count by (status)(
  count_over_time(
    kubernetes_io:node_pool_status{monitored_resource="k8s_node_pool"}[${__interval}]))

ノードプールの可用性

次の GKE システム指標は、マルチホスト TPU ノードプールが使用可能かどうかを示します。

  • kubernetes.io/node_pool/multi_host/available

この指標の値は、ノードプール内のすべてのノードが使用可能な場合は True になり、それ以外の場合は False になります。この指標は 60 秒ごとにサンプリングされます。

プロジェクトでマルチホスト TPU ノードプールが使用可能かどうかを確認するには、次の PromQL クエリを使用します。

avg by (node_pool_name)(
  avg_over_time(
    kubernetes_io:node_pool_multi_host_available{
      monitored_resource="k8s_node_pool",
      cluster_name="CLUSTER_NAME"}[${__interval}]))

ノードの中断回数

次の GKE システム指標は、最後のサンプリング以降の GKE ノードの中断回数を報告します(この指標は 60 秒ごとにサンプリングされます)。

  • kubernetes.io/node/interruption_count

interruption_typeTerminationEventMaintenanceEventPreemptionEvent など)フィールドと interruption_reasonHostErrorEvictionAutoRepair など)フィールドは、ノードが中断された理由を把握するのに役立ちます。

プロジェクトのクラスタ内の TPU ノードで発生した中断とその原因の内訳を取得するには、次の PromQL クエリを使用します。

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node"}[${__interval}]))

ホスト メンテナンス イベントのみを表示するには、interruption_reasonHW/SW Maintenance 値をフィルタするようにクエリを更新します。次の PromQL クエリを使用します。

  sum by (interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_interruption_count{monitored_resource="k8s_node", interruption_reason="HW/SW Maintenance"}[${__interval}]))

ノードプールごとに集計された中断回数を表示するには、次の PromQL クエリを使用します。

  sum by (node_pool_name,interruption_type,interruption_reason)(
    sum_over_time(
      kubernetes_io:node_pool_interruption_count{monitored_resource="k8s_node_pool", interruption_reason="HW/SW Maintenance", node_pool_name=NODE_POOL_NAME }[${__interval}]))

ノードプールの復旧時間(TTR)

次の GKE システム指標は、GKE マルチホスト TPU ノードプールの復旧期間の分布を報告します。

  • kubernetes.io/node_pool/accelerator/times_to_recover

この指標に記録された各サンプルは、ダウンタイム期間からの単一のノードプール復旧イベントを示します。

この指標は、マルチホスト TPU ノードプールの復旧時間と中断間隔を追跡するのに役立ちます。

次の PromQL クエリを使用すると、クラスタの過去 7 日間の平均復旧時間(MTTR)を計算できます。

sum(sum_over_time(
  kubernetes_io:node_pool_accelerator_times_to_recover_sum{
    monitored_resource="k8s_node_pool", cluster_name="CLUSTER_NAME"}[7d]))
/
sum(sum_over_time(
  kubernetes_io:node_pool_accelerator_times_to_recover_count{
    monitored_resource="k8s_node_pool",cluster_name="CLUSTER_NAME"}[7d]))

ノードプールの中断間隔(TBI)

ノードプールの中断間隔は、インフラストラクチャが中断するまでの稼働時間を測定します。これは、一定期間の平均として計算されます。分子はインフラストラクチャの稼働時間の合計を測定し、分母はインフラストラクチャの中断時間の合計を測定します。

次の PromQL の例は、特定のクラスタの 7 日間の平均中断間隔(MTBI)を示しています。

sum(count_over_time(
  kubernetes_io:node_memory_total_bytes{
    monitored_resource="k8s_node", node_name=~"gke-tpu.*|gk3-tpu.*", cluster_name="CLUSTER_NAME"}[7d]))
/
sum(sum_over_time(
  kubernetes_io:node_interruption_count{
    monitored_resource="k8s_node", node_name=~"gke-tpu.*|gk3-tpu.*", cluster_name="CLUSTER_NAME"}[7d]))

ホスト指標

GKE バージョン 1.28.1-gke.1066000 以降では、TPU スライスの VM は TPU 使用率の指標を GKE システム指標としてエクスポートします。Cloud Monitoring では、次の指標を使用して TPU ホストのパフォーマンスをモニタリングできます。

  • TensorCore の使用率: 使用されている TensorCore の現在の割合。TensorCore の値は、マトリックス乗算ユニット(MXU)およびベクトル ユニットの合計と等しくなります。TensorCore の使用率の値は、過去のサンプル期間(60 秒)に実行された TensorCore オペレーションを、同じ期間にサポートされている TensorCore オペレーションの数で割ったものです。値が大きいほど、使用率が高いことを意味します。
  • メモリ帯域幅の使用率: 現在使用されているアクセラレータ メモリ帯域幅の割合。サンプル期間(60 秒)で使用されたメモリ帯域幅を、同じサンプル期間でサポートされる最大帯域幅で割って計算されます。

これらの指標は、Kubernetes ノード(k8s_node)と Kubernetes コンテナ(k8s_container)のスキーマにあります。

Kubernetes コンテナ:

  • kubernetes.io/container/accelerator/tensorcore_utilization
  • kubernetes.io/container/accelerator/memory_bandwidth_utilization

Kubernetes ノード:

  • kubernetes.io/node/accelerator/tensorcore_utilization
  • kubernetes.io/node/accelerator/memory_bandwidth_utilization

詳細については、Kubernetes の指標GKE のシステム指標をご覧ください。

既知の問題

  • クラスタ オートスケーラーは、新しい TPU スライスノードが使用可能な TPU を報告する前に、そのノードの容量を誤って計算することがあります。これにより、クラスタ オートスケーラーが追加のスケールアップを実行して、結果として必要以上にノードを作成する場合があります。クラスタ オートスケーラーは、通常のスケールダウン オペレーションの後、不要なノードをスケールダウンします。
  • クラスタ オートスケーラーは、10 時間以上待機状態になっている TPU スライス ノードプールのスケールアップをキャンセルします。クラスタ オートスケーラーは、このようなスケールアップ オペレーションを後で再試行します。この動作により、予約を使用しないお客様の TPU の入手可能性が低下する可能性があります。
  • TPU taint の toleration がある TPU 以外のワークロードは、TPU ノードプールのドレイン中に再作成されると、ノードプールのスケールダウンを妨げることがあります。
  • メモリ帯域幅使用率の指標は、v5e TPU では使用できません。

次のステップ