Nesta página, mostramos como resolver problemas relacionados a TPUs no Google Kubernetes Engine (GKE).
Se precisar de mais ajuda, entre em contato com o Cloud Customer Care.Cota insuficiente para atender à solicitação de TPU
Um erro semelhante a Insufficient quota to satisfy the request
indica que seu
projeto do Google Cloud não tem cota suficiente para atender a
solicitação.
Para resolver esse problema, verifique o limite da cota e o uso atual do seu projeto. Se necessário, solicite um aumento da sua cota de TPU.
Verificar o limite da cota e o uso atual
As seções a seguir ajudam a garantir que você tenha cota suficiente ao usar TPUs no GKE.
Para verificar o limite e o uso atual da sua cota da API Compute Engine para TPUs, siga estas etapas:
Acesse a página Cotas no console do Google Cloud.
Na caixa Filtro
, faça o seguinte:Selecione a propriedade Serviço, insira API Compute Engine e pressione Enter.
Selecione a propriedade Tipo e escolha Cota.
Selecione a propriedade Nome e digite o nome da cota com base na versão da TPU e no tipo de máquina . Por exemplo, se você planeja criar nós da TPU v5e sob demanda com o tipo de máquina que começa com
TPU v5 Lite PodSlice chips
, digite.Versão da TPU Nome da cota para instâncias sob demanda Nome da cota para instâncias para Spot2 TPU v3 TPU v3 Device chips
Preemptible TPU v3 Device chips
TPU v3 TPU v3 PodSlice chips
Preemptible TPU v3 PodSlice chips
TPU v4 TPU v4 PodSlice chips
Preemptible TPU v4 PodSlice chips
TPU v5e TPU v5 Lite Device chips
Preemptible TPU v5 Lite Device chips
TPU v5e TPU v5 Lite PodSlice chips
Preemptible TPU v5 Lite PodSlice chips
TPU v5p TPU v5p chips
Preemptible TPU v5p chips
TPU v6e (pré-lançamento) TPU v6e Slice chips
Preemptible TPU v6e Lite PodSlice chips
Selecione a propriedade Dimensões (por exemplo, locais) e insira
region:
seguido do nome da região em que você planeja criar TPUs no GKE. Por exemplo, insiraregion:us-west4
se planeja criar nós de fração da TPU na zonaus-west4-a
. A cota de TPU é regional, portanto, todas as zonas na mesma região consomem a mesma cota de TPU.
Se nenhuma cota corresponder ao filtro inserido, isso significa que o projeto não recebeu nenhuma das cotas especificadas para a região desejada. Você precisará solicitar um aumento de cota de TPU.
Quando uma reserva de TPU é criada, os valores de limite e de uso atual da cota correspondente aumentam pelo número de chips na reserva da TPU. Por exemplo, quando uma reserva é criada para 16 chips de TPU v5e
com
,
o Limite e o
Uso atual para a cota de TPU v5 Lite PodSlice chips
na região
relevante aumentam em 16.
Cotas para outros recursos do GKE
Talvez seja necessário aumentar as seguintes cotas relacionadas ao GKE nas regiões em que o GKE cria seus recursos.
- Cota SSD de disco permanente (GB): o disco de inicialização de cada nó do Kubernetes requer 100 GB por padrão. Portanto, essa cota precisa ser definida pelo menos até o produto do número máximo de nós do GKE que você espera criar e 100 GB (nós * 100 GB).
- Cota de endereços IP em uso: cada nó do Kubernetes consome um endereço IP. Portanto, essa cota precisa ser definida pelo menos tão alta quanto o número máximo de nós do GKE que você prevê que serão criados.
- Verifique se
max-pods-per-node
está alinhado com o intervalo de sub-rede: cada nó do Kubernetes usa intervalos de IP secundários para pods. Por exemplo,max-pods-per-node
de 32 requer 64 endereços IP, o que se traduz em uma sub-rede /26 por nó. Esse intervalo não pode ser compartilhado com nenhum outro cluster. Para evitar que o intervalo de endereços IP seja esgotado, use a flag--max-pods-per-node
para limitar o número de pods que podem ser programados em um nó. A cota demax-pods-per-node
precisa ser definida pelo menos tão alta quanto o número máximo de nós do GKE que você prevê que serão criados.
Para solicitar um aumento de cota, consulte Solicitar uma cota maior.
Erro ao ativar o provisionamento automático de nós em um pool de nós de fração da TPU
O erro a seguir ocorre ao ativar o provisionamento automático de nós em um cluster do GKE que não dá suporte a TPUs.
A mensagem de erro é semelhante a esta:
ERROR: (gcloud.container.clusters.create) ResponseError: code=400,
message=Invalid resource: tpu-v4-podslice.
Para resolver esse problema, faça upgrade do cluster do GKE para a versão 1.27.6 ou mais recente.
O GKE não provisiona os nós de fração da TPU de maneira automática
As seções a seguir descrevem os casos em que o GKE não provisiona os nós de fração da TPU de maneira automática e como corrigir esse problema.
Limitar configurações incorretas
O GKE não provisiona os nós de fração da TPU de maneira automática quando os limites de provisionamento automático definidos para um cluster são muito baixos. Nesses casos, é possível notar os seguintes erros:
Quando há um pool de nós de fração da TPU, mas o GKE não consegue escalonar os nós verticalmente devido à violação dos limites de recursos, a seguinte mensagem de erro é exibida ao executar o comando
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
Além disso, nesse cenário, é possível notar mensagens de aviso semelhantes às seguintes no console do Google Cloud:
"Your cluster has one or more unschedulable Pods"
Quando o GKE tenta provisionar automaticamente um pool de nós de fração da TPU que excede os limites de recursos, os registros de visibilidade do escalonador automático do cluster exibem a seguinte mensagem de erro:
messageId: "no.scale.up.nap.pod.zonal.resources.exceeded"
Além disso, nesse cenário, é possível notar mensagens de aviso semelhantes às seguintes no console do 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"
Para resolver esses problemas, aumente o número máximo de chips de TPU, núcleos de CPU e memória no cluster.
Para seguir essas etapas, faça o seguinte:
- Calcule os requisitos de recursos para uma determinada contagem e um determinado tipo de máquina de TPU. Você precisa adicionar recursos para pools de nós de fração que não sejam de TPU, como cargas de trabalho do sistema.
Confira uma descrição da TPU, da CPU e da memória disponíveis para um tipo de máquina e uma zona específicos. Use a gcloud CLI:
gcloud compute machine-types describe MACHINE_TYPE \ --zone COMPUTE_ZONE
Substitua:
MACHINE_TYPE
: o tipo de máquina a ser pesquisado.COMPUTE_ZONE
: o nome da zona do Compute.
A saída inclui uma linha de descrição semelhante à seguinte:
description: 240 vCPUs, 407 GB RAM, 4 Google TPUs ```
Calcule o número total de CPU e memória multiplicando esses valores pelo número necessário de nós. Por exemplo, o tipo de máquina
ct4p-hightpu-4t
usa 240 núcleos de CPU e 407 GB de RAM com 4 chips de TPU. Supondo que você precise de 20 chips de TPU, que correspondem a cinco nós, defina os seguintes valores:--max-accelerator=type=tpu-v4-podslice,count=20
.CPU = 1200
(240 x 5)memory = 2035
(407 x 5)
Defina os limites com alguma margem para acomodar nós de fração que não sejam de TPU, como cargas de trabalho do sistema.
Atualize os limites do cluster:
gcloud container clusters update CLUSTER_NAME \ --max-accelerator type=TPU_ACCELERATOR \ count=MAXIMUM_ACCELERATOR \ --max-cpu=MAXIMUM_CPU \ --max-memory=MAXIMUM_MEMORY
Substitua:
CLUSTER_NAME
: o nome do cluster.TPU_ACCELERATOR
: o nome do acelerador de TPU.MAXIMUM_ACCELERATOR
: o número máximo de chips de TPU no cluster.MAXIMUM_CPU
: o número máximo de núcleos no cluster.MAXIMUM_MEMORY
: o número máximo de gigabytes de memória no cluster.
Nem todas as instâncias estão em execução
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.
Este erro pode aparecer quando a operação do GKE atinge o tempo limite ou a solicitação não pode ser atendida e colocada na fila para provisionar pools de nós de TPU de host único ou de vários hosts. Para reduzir os problemas de capacidade, use reservas ou considere usar VMs spot.
Configuração incorreta de carga de trabalho
Esse erro ocorre devido à configuração incorreta da carga de trabalho. Confira a seguir algumas das causas mais comuns para esse erro:
- Os rótulos
cloud.google.com/gke-tpu-accelerator
ecloud.google.com/gke-tpu-topology
estão incorretos ou ausentes na especificação do pod. O GKE não vai provisionar pools de nós de fração da TPU, e o provisionamento automático de nós não vai escalonar verticalmente o cluster. - A especificação do pod não especifica
google.com/tpu
nos requisitos de recursos.
Para resolver esse problema, siga uma das seguintes recomendações:
- Verifique se há algum rótulo sem suporte no seletor de nós de carga de trabalho.
Por exemplo, um seletor de nós para o rótulo
cloud.google.com/gke-nodepool
vai impedir que o GKE crie pools de nós adicionais para os pods. - Verifique se as especificações do modelo de pod, em que a carga de trabalho da TPU é executada, incluem
os seguintes valores:
- Os rótulos
cloud.google.com/gke-tpu-accelerator
ecloud.google.com/gke-tpu-topology
emnodeSelector
. google.com/tpu
na solicitação.
- Os rótulos
Para saber como implantar cargas de trabalho de TPU no GKE, consulte Executar uma carga de trabalho que exibe o número de chips de TPU disponíveis em um pool de nós de fração da TPU.
Como programar erros ao implantar pods que consomem TPUs no GKE
O problema a seguir ocorre quando o GKE não consegue programar pods que solicitam TPUs em nós de fração de TPU. Por exemplo, isso pode ocorrer quando algumas frações que não são de TPU já estavam programadas em nós de TPU.
A mensagem de erro, emitida como um evento FailedScheduling
no pod, é semelhante ao seguinte:
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
Para resolver esse problema, faça o seguinte:
Verifique se você tem pelo menos um pool de nós de CPU no cluster para que os pods críticos do sistema possam ser executados nos nós não TPU. Para saber mais, consulte Implantar um pod em um pool de nós específico.
Como solucionar problemas comuns com JobSets no GKE
Para problemas comuns com o JobSet e sugestões de solução de problemas, consulte a página de solução de problemas do JobSet. Nesta página, abordamos problemas comuns, como o erro "Webhook não disponível", job filho ou pods que não são criados, além de retomar o problema de cargas de trabalho preemptivas usando JobSet e Kueue.
Falha na inicialização da TPU
O problema a seguir ocorre quando o GKE não consegue provisionar novas cargas de trabalho de TPU devido à falta de permissão para acessar dispositivos de TPU.
A mensagem de erro é semelhante a esta:
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
Para resolver esse problema, execute o contêiner da TPU no modo privilegiado ou aumente a ulimit
dentro do contêiner.
Programando impasse
A programação de dois ou mais jobs pode falhar no impasse. Por exemplo, no cenário em que ocorre o seguinte:
- Você tem dois jobs (Job A e Job B) com regras de afinidade de pod.
O GKE programa as frações de TPU para os dois jobs com uma topologia de TPU de
v4-32
. - Você tem duas frações de TPU
v4-32
no cluster. - O cluster tem ampla capacidade de programar jobs e, teoricamente, cada job pode ser programado rapidamente em cada fração de TPU.
- O programador do Kubernetes programa um pod do job A em uma fração e, em seguida, programa um pod do job B na mesma fatia.
Nesse caso, dadas as regras de afinidade de pod para o job A, o programador tenta programar todos os pods restantes para o job A e para o job B em cada fatia da TPU. Como resultado, o GKE não conseguirá programar completamente os jobs A ou B. Portanto, o status de ambos os jobs permanecerá pendente.
Para resolver esse problema, use a
antiafinidade de pods
com cloud.google.com/gke-nodepool
como topologyKey
, conforme mostrado no exemplo a seguir:
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
Permissão negada durante a criação do cluster em us-central2
Ao tentar criar um cluster em us-central2
(a única região
em que a TPU v4 está disponível), talvez você encontre uma mensagem de erro semelhante
a esta:
ERROR: (gcloud.container.clusters.create) ResponseError: code=403,
message=Permission denied on 'locations/us-central2' (or it may not exist).
Esse erro ocorre porque a região us-central2
é particular.
Para resolver esse problema, registre um caso de suporte ou entre em contato com sua
equipe de conta para solicitar que us-central2
fique visível no
projeto do Google Cloud.
Cota insuficiente durante a criação do pool de nós de TPU em us-central2
Se você estiver tentando criar um pool de nós de fração de TPU em us-central2
(a única região em que a TPU v4 está disponível), talvez seja necessário aumentar as seguintes cotas relacionadas ao GKE ao criar pools de nós TPU v4 pela primeira vez:
- Cota SSD de disco permanente (GB) em us-central2: o disco de inicialização de cada nó do Kubernetes requer 100 GB por padrão. Portanto, essa cota precisa ser definida
pelo menos até o produto do número máximo de nós do GKE
que você espera criar em
us-central2
e 100 GB (maximum_nodes
X100 GB
). - Cota de endereços IP em uso na us-central2: cada nó do Kubernetes consome
um endereço IP. Portanto, essa cota precisa ser definida pelo menos tão alta quanto o
número máximo de nós do GKE que você prevê que serão criados em
us-central2
.
Sub-rede ausente durante a criação do cluster do GKE
Ao tentar criar um cluster em us-central2
(a única região
em que a TPU v4 está disponível), talvez você encontre uma mensagem de erro semelhante
a esta:
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>.
Uma sub-rede é necessária na rede VPC para fornecer conectividade
com os nós do GKE. No entanto, em determinadas regiões, como
us-central2
, uma sub-rede padrão pode não ser criada, mesmo quando você usa a
rede VPC padrão no modo automático (para criação de sub-redes).
Para resolver esse problema, verifique se você criou uma sub-rede personalizada na região antes de criar o cluster do GKE. Essa sub-rede não pode se sobrepor a outras criadas em regiões na mesma rede VPC.
Acessar os registros de TPU do GKE
Para conferir todos os registros relacionados à TPU de uma carga de trabalho específica, o Cloud Logging oferece um local centralizado para consultar esses registros quando o registro de carga de trabalho e do sistema do GKE está ativado. No Cloud Logging, os registros são organizados em entradas de registro, e cada entrada de registro individual tem um formato estruturado. Confira a seguir um exemplo de entrada de registro de job de treinamento de 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"
}
Cada entrada de registro dos nós de fração da TPU tem o rótulo
compute.googleapis.com/resource_name
com o valor definido como o nome do nó.
Se você quiser conferir os registros de um nó específico e souber o nome dele,
filtre os registros por esse nó na consulta. Por exemplo, a consulta a seguir mostra os registros do nó TPU gke-tpu-9243ec28-wwf5
:
resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" = "gke-tpu-9243ec28-wwf5"
O GKE anexa o rótulo cloud.google.com/gke-tpu-accelerator
e
cloud.google.com/gke-tpu-topology
a todos os nós que contêm TPUs. Portanto, se você não tiver certeza do nome do nó ou quiser listar todos os nós de fração da TPU, execute o seguinte comando:
kubectl get nodes -l cloud.google.com/gke-tpu-accelerator
Exemplo de resposta:
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
É possível filtrar mais com base nos rótulos de nó e nos valores deles. Por exemplo, o comando a seguir lista o nó de TPU com um tipo e uma topologia específicos:
kubectl get nodes -l cloud.google.com/gke-tpu-accelerator=tpu-v5-lite-podslice,cloud.google.com/gke-tpu-topology=1x1
Para conferir todos os registros nos nós de fração TPU, use a consulta que corresponde ao rótulo ao sufixo do nó de fração TPU. Por exemplo, use a seguinte consulta:
resource.type="k8s_container"
labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*"
log_id("stdout")
Para conferir os registros associados a uma carga de trabalho de TPU específica usando um
job do Kubernetes,
filtre os registros usando o rótulo batch.kubernetes.io/job-name
. Por
exemplo, para o job mnist-training-job
, é possível executar a consulta a seguir para
os registros STDOUT:
resource.type="k8s_container"
labels."k8s-pod/batch_kubernetes_io/job-name" = "mnist-training-job"
log_id("stdout")
Para conferir os registros de uma carga de trabalho de TPU usando um JobSet do Kubernetes,
filtre os registros usando o rótulo k8s-pod/jobset_sigs_k8s_io/jobset-name
.
Por exemplo:
resource.type="k8s_container"
labels."k8s-pod/jobset_sigs_k8s_io/jobset-name"="multislice-job"
Para detalhar ainda mais, você pode filtrar com base nos outros rótulos de carga de trabalho.
Por exemplo, para conferir os registros de uma carga de trabalho com várias frações do worker 0 e
da fração 1, é possível filtrar com base nos rótulos: job-complete-index
e job-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"
Também é possível filtrar usando o padrão de nome do pod:
resource.labels.pod_name:<jobSetName>-<replicateJobName>-<job-index>-<worker-index>
Por exemplo, na consulta a seguir, jobSetName
é job de várias frações e replicateJobName
é fração. job-index
e worker-index
são 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"
Para outras cargas de trabalho da TPU, como uma única carga de trabalho do pod do GKE, é possível filtrar os registros por nomes de pods. Por exemplo:
resource.type="k8s_container"
resource.labels.pod_name="tpu-job-jax-demo"
Se você quiser verificar se o plug-in do dispositivo TPU está sendo executado corretamente, use a consulta a seguir para verificar os registros do contêiner:
resource.type="k8s_container"
labels.k8s-pod/k8s-app="tpu-device-plugin"
resource.labels.namespace_name="kube-system"
Execute a consulta a seguir para verificar os eventos relacionados:
jsonPayload.involvedObject.name=~"tpu-device-plugin.*"
log_id("events")
Para todas as consultas, é possível adicionar outros filtros, como nome do cluster, localização e ID do projeto. Também é possível combinar condições para restringir os resultados. Por exemplo:
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")
O operador AND
é opcional entre comparações e pode ser omitido. Para mais
informações sobre a linguagem de consulta, leia a especificação da linguagem de consulta do Logging.
Você também pode ler Consultas de registro relacionadas ao Kubernetes
para conferir mais exemplos de consultas.
Se você preferir o SQL usando a Análise de dados de registros, confira exemplos de consultas em Consulta SQL com a Análise de dados de registros. Como alternativa, você também pode executar as consultas usando a CLI do Google Cloud, em vez de usar a Análise de registros. Por exemplo:
gcloud logging read 'resource.type="k8s_container" labels."compute.googleapis.com/resource_name" =~ "gke-tpu-9243ec28.*" log_id("stdout")' --limit 10 --format json