GKE의 TPU 문제 해결


이 페이지에서는 Google Kubernetes Engine(GKE)에서 TPU와 관련된 문제를 해결하는 방법을 설명합니다.

추가 지원이 필요하면 Cloud Customer Care에 연락합니다.

TPU 요청을 충족할 수 있는 할당량이 부족함

Insufficient quota to satisfy the request와 유사한 오류는 Google Cloud 프로젝트에 요청을 처리할 수 있는 할당량이 부족하다는 의미입니다.

이 문제를 해결하려면 프로젝트의 할당량 한도 및 현재 사용량을 확인하세요. 필요한 경우 TPU 할당량 증가를 요청하세요.

할당량 한도 및 현재 사용량 확인

TPU용 Compute Engine API 할당량의 한도 및 현재 사용량을 확인하려면 다음 단계를 따르세요.

  1. Google Cloud 콘솔의 할당량 페이지로 이동합니다.

    할당량으로 이동

  2. 필터 상자에서 다음을 수행합니다,

    1. 서비스 속성을 선택하고 Compute Engine API를 입력한 다음 Enter 키를 누릅니다.

    2. 유형 속성을 선택하고 할당량을 선택합니다.

    3. 측정기준(예: 위치) 속성을 선택하고 region:을 입력한 다음 GKE에서 TPU를 생성할 리전의 이름을 입력합니다. 예를 들어 us-west4-a 영역에 TPU 슬라이스 노드를 만들려면 region:us-west4를 입력합니다. TPU 할당량은 리전 기준이므로 동일한 리전 내의 모든 영역에서 동일한 TPU 할당량을 사용합니다.

입력한 필터와 일치하는 할당량이 없으면 원하는 리전에 대해 지정된 할당량이 프로젝트에 부여되지 않으므로 TPU 할당량 상향을 요청해야 합니다.

TPU 슬라이스 노드 풀에서 노드 자동 프로비저닝을 사용 설정할 때의 오류

TPU를 지원하지 않는 GKE 클러스터에서 노드 자동 프로비저닝을 사용 설정하는 경우 다음 오류가 발생합니다.

오류 메시지는 다음과 비슷합니다.

ERROR: (gcloud.container.clusters.create) ResponseError: code=400,
  message=Invalid resource: tpu-v4-podslice.

이 문제를 해결하려면 GKE 클러스터를 버전 1.27.6 이상으로 업그레이드합니다.

GKE가 TPU 슬라이스 노드를 자동으로 프로비저닝하지 않음

다음 섹션에서는 GKE가 TPU 슬라이스 노드를 자동으로 프로비저닝하지 않는 경우와 이를 해결하는 방법을 설명합니다.

구성 오류 제한

클러스터에 대해 정의한 자동 프로비저닝 제한이 너무 낮으면 GKE가 TPU 슬라이스 노드를 자동으로 프로비저닝하지 않습니다. 이러한 시나리오에서는 다음과 같은 오류가 관측될 수 있습니다.

  • TPU 슬라이스 노드 풀이 있지만 리소스 제한 위반으로 인해 GKE를 수직 확장할 수 없으면 kubectl get events 명령어를 실행할 때 다음 오류 메시지가 표시될 수 있습니다.

    11s Normal NotTriggerScaleUp pod/tpu-workload-65b69f6c95-ccxwz pod didn't
    trigger scale-up: 1 node(s) didn't match Pod's node affinity/selector, 1 max
    cluster cpu, memory limit reached
    

    또한 이 시나리오에서는 Google Cloud 콘솔에서 다음과 비슷한 경고 메시지가 표시될 수 있습니다.

    "Your cluster has one or more unschedulable Pods"
    
  • GKE가 리소스 한도를 초과하는 TPU 슬라이스 노드 풀을 자동 프로비저닝하려고 시도하면 클러스터 자동 확장 처리 가시성 로그에 다음 오류 메시지가 표시됩니다.

    messageId: "no.scale.up.nap.pod.zonal.resources.exceeded"
    

    또한 이 시나리오에서는 Google Cloud 콘솔에서 다음과 비슷한 경고 메시지가 표시될 수 있습니다.

    "Can't scale up because node auto-provisioning can't provision a node pool for
    the Pod if it would exceed resource limits"
    

이 문제를 해결하려면 클러스터에서 TPU 칩, CPU 코어, 메모리의 최대 한도를 늘립니다.

이러한 단계를 완료하려면 다음 안내를 따르세요.

  1. 제공된 TPU 머신 유형 및 개수의 리소스 요구사항을 계산합니다. 시스템 워크로드와 같이 TPU 슬라이스 이외의 노드 풀에 대해 리소스를 추가해야 합니다.
  2. 특정 머신 유형 및 영역에 대해 사용 가능한 TPU, CPU, 메모리에 대한 설명을 확인합니다. gcloud CLI를 사용합니다.

    gcloud compute machine-types describe MACHINE_TYPE \
        --zone COMPUTE_ZONE
    

    다음을 바꿉니다.

    • MACHINE_TYPE: 검색할 머신 유형입니다.
    • COMPUTE_ZONE: 컴퓨팅 영역의 이름입니다.

    출력에 다음과 비슷한 설명 줄이 포함됩니다.

      description: 240 vCPUs, 407 GB RAM, 4 Google TPUs
      ```
    
  3. 이러한 양에 필요한 노드 수를 곱하여 총 CPU 및 메모리 수를 계산합니다. 예를 들어 ct4p-hightpu-4t 머신 유형에는 TPU 칩 4개와 함께 240개 CPU 코어와 407GB RAM이 사용됩니다. 5개 노드에 해당하는 20개의 TPU 칩이 필요하다고 가정하면 다음 값을 정의해야 합니다.

    • --max-accelerator=type=tpu-v4-podslice,count=20.
    • CPU = 1200(240 곱하기 5)
    • memory = 2035(407 곱하기 5)

    시스템 워크로드와 같은 TPU 이외의 슬라이스 노드를 수용할 수 있도록 약간의 여유를 두고 한도를 정의해야 합니다.

  4. 클러스터 한도를 업데이트합니다.

    gcloud container clusters update CLUSTER_NAME \
        --max-accelerator type=TPU_ACCELERATOR \
        count=MAXIMUM_ACCELERATOR \
        --max-cpu=MAXIMUM_CPU \
        --max-memory=MAXIMUM_MEMORY
    

    다음을 바꿉니다.

    • CLUSTER_NAME: 클러스터의 이름입니다.
    • TPU_ACCELERATOR: TPU 가속기의 이름입니다.
    • MAXIMUM_ACCELERATOR: 클러스터의 최대 TPU 칩 수입니다.
    • MAXIMUM_CPU: 클러스터의 최대 코어 수입니다.
    • MAXIMUM_MEMORY: 클러스터의 최대 메모리 용량(GB)입니다.

일부 인스턴스가 실행되지 않음

ERROR: 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.

GKE 작업의 시간이 초과되었거나 단일 호스트 또는 멀티 호스트 TPU 노드 풀 프로비저닝을 위해 요청을 처리하고 대기열에 추가할 수 없는 경우에 이 오류가 표시될 수 있습니다. 용량 문제를 완화하려면 예약을 사용하거나 스팟 VM을 고려해 보세요.

워크로드 구성 오류

이 오류는 워크로드 구성 오류로 인해 발생합니다. 이 오류의 가장 일반적인 원인은 다음과 같습니다.

  • 포드 사양에서 cloud.google.com/gke-tpu-acceleratorcloud.google.com/gke-tpu-topology 라벨이 잘못되었거나 누락되었습니다. GKE는 TPU 슬라이스 노드 풀을 프로비저닝하지 않으며 노드 자동 프로비전으로 클러스터를 수직 확장할 수 없습니다.
  • 포드 사양의 해당 요구사항에 google.com/tpu가 지정되지 않았습니다.

이 문제를 해결하려면 다음 중 한 가지를 따르세요.

  1. 워크로드 노드 선택기에 지원되지 않는 라벨이 없는지 확인합니다. 예를 들어 cloud.google.com/gke-nodepool 라벨의 노드 선택기는 GKE가 포드에 대해 추가 노드 풀을 만들지 못하도록 방지합니다.
  2. TPU 워크로드가 실행되는 포드 템플릿 사양에 다음 값이 포함되는지 확인합니다.
    • nodeSelector에 있는 cloud.google.com/gke-tpu-acceleratorcloud.google.com/gke-tpu-topology 라벨
    • 요청에 있는 google.com/tpu

GKE에서 TPU 워크로드를 배포하는 방법은 TPU 슬라이스 노드 풀에서 사용 가능한 TPU 칩 수를 표시하는 워크로드 실행을 참조하세요.

GKE에서 TPU를 사용하는 포드를 배포할 때 발생하는 예약 오류

다음 문제는 GKE가 TPU 슬라이스 노드에서 포드 요청 TPU를 예약할 수 없을 때 발생합니다. 예를 들어 이 문제는 일부 TPU 이외의 슬라이스가 TPU 포드에 이미 예약된 경우에 발생할 수 있습니다.

포드에서 FailedScheduling 이벤트로 발생하는 오류 메시지는 다음과 비슷합니다.

Cannot schedule pods: Preemption is not helpful for scheduling.

Error message: 0/2 nodes are available: 2 node(s) had untolerated taint
{google.com/tpu: present}. preemption: 0/2 nodes are available: 2 Preemption is
not helpful for scheduling

이 문제를 해결하려면 다음 단계를 따르세요.

시스템에 중요한 포드가 비 TPU 노드에서 실행될 수 있도록 클러스터에 CPU 노드 풀이 하나 이상 있는지 확인합니다. 자세한 내용은 특정 노드 풀에 노드 배포를 참조하세요.

GKE에서 JobSet의 일반적인 문제 해결

JobSet의 일반적인 문제 및 권장되는 해결 방법은 JobSet 문제 해결 페이지를 참조하세요. 이 페이지에서는 '웹훅을 사용할 수 없음' 오류, 하위 작업 또는 포드가 생성되지 않는 경우, JobSet 및 Kueue를 사용하는 선점된 워크로드의 재개 문제와 같은 일반적인 문제를 다룹니다.

TPU 초기화 실패

다음 문제는 TPU 기기 액세스 권한 부족으로 인해 GKE가 새 TPU 워크로드를 프로비저닝할 수 없을 때 발생합니다.

오류 메시지는 다음과 비슷합니다.

TPU platform initialization failed: FAILED_PRECONDITION: Couldn't mmap: Resource
temporarily unavailable.; Unable to create Node RegisterInterface for node 0,
config: device_path: "/dev/accel0" mode: KERNEL debug_data_directory: ""
dump_anomalies_only: true crash_in_debug_dump: false allow_core_dump: true;
could not create driver instance

이 문제를 해결하려면 권한이 있는 모드에서 TPU 컨테이너를 실행하거나 컨테이너 내 ulimit을 늘려야 합니다.

예약 교착 상태

두 개 이상의 작업 예약이 교착 상태로 인해 실패할 수 있습니다. 다음 상황이 모두 발생하는 시나리오를 예시로 들겠습니다.

  • 포드 어피니티 규칙이 있는 두 개의 작업(작업 A 및 작업 B)이 있습니다. GKE는 v4-32의 TPU 토폴로지를 사용하여 두 작업에 대해 TPU 슬라이스를 예약합니다.
  • 클러스터에 v4-32 TPU 슬라이스가 2개 있습니다.
  • 클러스터에는 두 작업을 예약할 수 있는 충분한 용량이 있으며 이론적으로는 각 작업을 각 TPU 슬라이스에 빠르게 예약할 수 있습니다.
  • Kubernetes 스케줄러는 한 슬라이스에서 작업 A의 포드 한 개를 예약한 후 동일한 슬라이스에서 작업 B의 포드 한 개를 예약합니다.

이 경우 작업 A에 대한 포드 어피니티 규칙을 고려해 스케줄러가 각 단일 TPU 슬라이스에 작업 A와 작업 B의 나머지 모든 포드를 예약하려고 시도합니다. 그 결과, GKE에서 작업 A나 작업 B를 완전히 예약할 수 없게 됩니다. 따라서 두 작업의 상태는 대기 중으로 유지됩니다.

이 문제를 해결하려면 다음 예시와 같이 cloud.google.com/gke-nodepooltopologyKey로 사용한 포드 안티-어피니티를 사용합니다.

apiVersion: batch/v1
kind: Job
metadata:
 name: pi
spec:
 parallelism: 2
 template:
   metadata:
     labels:
       job: pi
   spec:
     affinity:
       podAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
         - labelSelector:
             matchExpressions:
             - key: job
               operator: In
               values:
               - pi
           topologyKey: cloud.google.com/gke-nodepool
       podAntiAffinity:
         requiredDuringSchedulingIgnoredDuringExecution:
         - labelSelector:
             matchExpressions:
             - key: job
               operator: NotIn
               values:
               - pi
           topologyKey: cloud.google.com/gke-nodepool
           namespaceSelector:
             matchExpressions:
             - key: kubernetes.io/metadata.name
               operator: NotIn
               values:
               - kube-system
     containers:
     - name: pi
       image: perl:5.34.0
       command: ["sleep",  "60"]
     restartPolicy: Never
 backoffLimit: 4

us-central2에서 클러스터 생성 중에 권한이 거부됨

us-central2(TPU v4를 사용할 수 있는 유일한 리전)에서 클러스터를 만들려고 시도하면 다음과 비슷한 오류 메시지가 표시될 수 있습니다.

ERROR: (gcloud.container.clusters.create) ResponseError: code=403,
message=Permission denied on 'locations/us-central2' (or it may not exist).

이 오류는 us-central2 리전이 비공개 리전이기 때문에 발생합니다.

이 문제를 해결하려면 지원 케이스를 제출하거나 계정팀에 Google Cloud 프로젝트 내에서 us-central2를 볼 수 있게 해달라고 요청하세요.

us-central2에서 TPU 노드 풀 만들기 중 할당량 부족

us-central2(TPU v4를 사용할 수 있는 유일한 리전)에서 TPU 슬라이스 노드 풀을 만들려고 시도하면 처음 TPU v4노드 풀을 만들 때 다음 GKE 관련 할당량을 늘려야 할 수 있습니다.

  • us-central2의 영구 디스크 SSD(GB) 할당량: 각 Kubernetes 노드의 부팅 디스크에는 기본적으로 100GB가 필요합니다. 따라서 이 할당량은 us-central2 및 100GB(maximum_nodes X 100 GB)에서 생성될 것으로 예상되는 최대 GKE 노드 수의 곱 이상으로 설정해야 합니다.
  • us-central2의 사용 중인 IP 주소 할당량: 각 Kubernetes 노드는 하나의 IP 주소를 사용합니다. 따라서 이 할당량은 us-central2에서 생성될 것으로 예상되는 최대 GKE 노드 수 이상으로 설정해야 합니다.

GKE 클러스터 만들기 중 서브넷 누락

us-central2(TPU v4를 사용할 수 있는 유일한 리전)에서 클러스터를 만들려고 시도하면 다음과 비슷한 오류 메시지가 표시될 수 있습니다.

ERROR: (gcloud.container.clusters.create) ResponseError: code=404,
message=Not found: project <PROJECT> does not have an auto-mode subnetwork
for network "default" in region <REGION>.

GKE 노드에 연결을 제공하려면 VPC 네트워크에 서브넷이 필요합니다. 하지만 us-central2와 같은 특정 리전에서는 서브넷 만들기를 위해 자동 모드로 기본 VPC 네트워크를 사용하더라도 기본 서브넷이 생성되지 않을 수 있습니다.

이 문제를 해결하려면 GKE 클러스터를 만들기 전에 리전에 커스텀 서브넷이 생성되었는지 확인합니다. 이 서브넷은 동일 VPC 네트워크의 다른 리전에 생성된 다른 서브넷과 겹치지 않아야 합니다.

GKE TPU 로그 보기

GKE 시스템 및 워크로드 로깅이 사용 설정된 경우 Cloud Logging은 특정 워크로드의 모든 TPU 관련 로그를 볼 수 있도록 해당 로그를 쿼리할 수 있는 중앙 위치를 제공합니다. Cloud Logging에서 로그는 로그 항목으로 구성되며 개별 로그 항목은 구조화된 형식을 갖습니다. 다음은 TPU 학습 작업 로그 항목의 예시입니다.

{
  insertId: "gvqk7r5qc5hvogif"
  labels: {
  compute.googleapis.com/resource_name: "gke-tpu-9243ec28-wwf5"
  k8s-pod/batch_kubernetes_io/controller-uid: "443a3128-64f3-4f48-a4d3-69199f82b090"
  k8s-pod/batch_kubernetes_io/job-name: "mnist-training-job"
  k8s-pod/controller-uid: "443a3128-64f3-4f48-a4d3-69199f82b090"
  k8s-pod/job-name: "mnist-training-job"
}
logName: "projects/gke-tpu-demo-project/logs/stdout"
receiveTimestamp: "2024-06-26T05:52:39.652122589Z"
resource: {
  labels: {
    cluster_name: "tpu-test"
    container_name: "tensorflow"
    location: "us-central2-b"
    namespace_name: "default"
    pod_name: "mnist-training-job-l74l8"
    project_id: "gke-tpu-demo-project"
}
  type: "k8s_container"
}
severity: "INFO"
textPayload: "
  1/938 [..............................] - ETA: 13:36 - loss: 2.3238 - accuracy: 0.0469
  6/938 [..............................] - ETA: 9s - loss: 2.1227 - accuracy: 0.2995   
 13/938 [..............................] - ETA: 8s - loss: 1.7952 - accuracy: 0.4760
 20/938 [..............................] - ETA: 7s - loss: 1.5536 - accuracy: 0.5539
 27/938 [..............................] - ETA: 7s - loss: 1.3590 - accuracy: 0.6071
 36/938 [>.............................] - ETA: 6s - loss: 1.1622 - accuracy: 0.6606
 44/938 [>.............................] - ETA: 6s - loss: 1.0395 - accuracy: 0.6935
 51/938 [>.............................] - ETA: 6s - loss: 0.9590 - accuracy: 0.7160
……
937/938 [============================>.] - ETA: 0s - loss: 0.2184 - accuracy: 0.9349"
timestamp: "2024-06-26T05:52:38.962950115Z"
}

TPU 슬라이스 노드의 각 로그 항목에는 값이 노드 이름으로 설정된 compute.googleapis.com/resource_name 라벨이 있습니다. 특정 노드의 로그를 보려는 경우 노드 이름을 알고 있다면 쿼리에서 해당 노드로 로그를 필터링할 수 있습니다. 예를 들어 다음 쿼리는 TPU 노드 gke-tpu-9243ec28-wwf5의 로그를 보여줍니다.

resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" = "gke-tpu-9243ec28-wwf5"

GKE는 TPU가 포함된 모든 노드에 cloud.google.com/gke-tpu-acceleratorcloud.google.com/gke-tpu-topology 라벨을 연결합니다. 따라서 노드 이름을 모르거나 모든 TPU 슬라이스 노드를 나열하려면 다음 명령어를 실행하면 됩니다.

kubectl get nodes -l cloud.google.com/gke-tpu-accelerator

샘플 출력:

NAME                    STATUS   ROLES    AGE     VERSION
gke-tpu-9243ec28-f2f1   Ready    <none>   25m     v1.30.1-gke.1156000
gke-tpu-9243ec28-wwf5   Ready    <none>   7d22h   v1.30.1-gke.1156000

노드 라벨과 값을 기준으로 추가 필터링을 수행할 수 있습니다. 예를 들어 다음 명령어는 특정 유형과 토폴로지를 갖는 TPU 노드를 나열합니다.

kubectl get nodes -l cloud.google.com/gke-tpu-accelerator=tpu-v5-lite-podslice,cloud.google.com/gke-tpu-topology=1x1

여러 TPU 슬라이스 노드의 모든 로그를 보려면 라벨을 TPU 슬라이스 노드 서픽스와 일치시키는 쿼리를 사용하면 됩니다. 예를 들어 다음 쿼리를 사용합니다.

resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*"
log_id("stdout")

Kubernetes 작업을 사용하는 특정 TPU 워크로드와 연결된 로그를 보려면 batch.kubernetes.io/job-name 라벨을 사용하여 로그를 필터링하면 됩니다. 예를 들어 mnist-training-job 작업의 경우 STDOUT 로그에 대해 다음 쿼리를 실행할 수 있습니다.

resource.type="k8s_container"
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job"
log_id("stdout")

Kubernetes JobSet을 사용하는 TPU 워크로드의 로그를 보려면 k8s-pod/jobset_sigs_k8s_io/jobset-name 라벨을 사용하여 로그를 필터링하면 됩니다. 예를 들면 다음과 같습니다.

resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"

더 자세히 살펴보려면 다른 워크로드 라벨을 기준으로 필터링하면 됩니다. 예를 들어 작업자 0 및 슬라이스 1의 멀티슬라이스 워크로드 로그를 보려면 job-complete-indexjob-index 라벨을 기준으로 필터링하면 됩니다.

​​resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
labels."k8s-pod/batch_kubernetes_io/job-completion-index"="0"
labels."k8s-pod/jobset_sigs_k8s_io/job-index"="1"

포드 이름 패턴을 사용하여 필터링할 수도 있습니다.

resource.labels.pod_name:<jobSetName>-<replicateJobName>-<job-index>-<worker-index>

예를 들어 다음 쿼리에서 jobSetName은 multislice-job이고 replicateJobName은 slice입니다. job-indexworker-index 모두 0입니다.

resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
resource.labels.pod_name:"multislice-job-slice-0-0"

단일 GKE 포드 워크로드 등 여타 TPU 워크로드에 대해서는 포드 이름으로 로그를 필터링할 수 있습니다. 예를 들면 다음과 같습니다.

resource.type="k8s_container"
resource.labels.pod_name="tpu-job-jax-demo"

TPU 기기 플러그인이 올바르게 실행 중인지 확인하려면 다음 쿼리를 사용하여 컨테이너 로그를 확인하면 됩니다.

resource.type="k8s_container"
labels.k8s-pod/k8s-app="tpu-device-plugin"
resource.labels.namespace_name="kube-system"

다음 쿼리를 실행하여 관련 이벤트를 확인합니다.

jsonPayload.involvedObject.name=~"tpu-device-plugin.*"
log_id("events")

모든 쿼리에 클러스터 이름, 위치, 프로젝트 ID와 같은 필터를 추가할 수 있습니다. 여러 조건을 결합하여 결과 범위를 좁힐 수도 있습니다. 예를 들면 다음과 같습니다.

resource.type="k8s_container" AND
resource.labels.project_id="gke-tpu-demo-project" AND
resource.labels.location="us-west1" AND
resource.labels.cluster_name="tpu-demo" AND
resource.labels.namespace_name="default" AND
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" AND
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job" AND
log_id("stdout")

비교 간에 AND 연산자는 선택사항이며 생략할 수 있습니다. 쿼리 언어에 관한 자세한 내용은 Logging 쿼리 언어 사양을 참조하세요. Kubernetes 관련 로그 쿼리에서도 더 많은 쿼리 예시를 확인할 수 있습니다.

로그 애널리틱스를 사용하는 SQL을 선호하는 경우 로그 애널리틱스를 사용한 SQL 쿼리에서 쿼리 예시를 확인할 수 있습니다. 로그 탐색기 대신 Google Cloud CLI를 사용하여 쿼리를 실행할 수도 있습니다. 예를 들면 다음과 같습니다.

gcloud logging read 'resource.type="k8s_container" labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" log_id("stdout")' --limit 10 --format json

다음 단계

추가 지원이 필요하면 Cloud Customer Care에 문의하세요.