Questo documento spiega come configurare un cluster GKE per massimizzare la disponibilità dell'addestramento AI sulle Tensor Processing Unit (TPU). Configura un sistema di failover automatico utilizzando uno strumento di accodamento dei job open source chiamato Kueue e Dynamic Workload Scheduler (DWS) diGoogle Cloud.
La configurazione definita in questo documento configura un pool di nodi primario e un pool di nodi di backup:
- On demand (piano A): questo pool di nodi è la tua prima scelta per i nodi. Il sistema tenta innanzitutto di pianificare i job su queste macchine on demand. Il termine on demand indica che, una volta avviate, queste macchine ti garantiscono un accesso affidabile e ininterrotto.
- DWS flex-start (Piano B): Questo è il tuo pool di nodi di backup. Quando le macchine del piano A non sono disponibili, il programma di pianificazione Kueue assegna automaticamente il tuo job a questo pool del piano B. DWS cerca quindi l'hardware del piano B, ma non garantisce l'accesso immediato perché anche questo hardware potrebbe non essere disponibile. DWS non si arrende: mantiene la tua richiesta in coda per un massimo di 7 giorni e fornisce automaticamente le macchine non appena sono disponibili.
Questo approccio riduce al minimo il tempo di attesa dei job in coda. Ciò significa che non devi controllare manualmente le risorse disponibili o riscrivere lo script per macchine diverse.
Panoramica dei passaggi di configurazione
Per configurare il sistema di failover automatico, devi completare diversi passaggi di configurazione. È utile dividere questa configurazione in due categorie:
- Attività dell'amministratore del cluster:configurazione dell'infrastruttura una tantum, ad esempio la creazione del cluster GKE, il provisioning dei pool di nodi e l'installazione del controller di pianificazione Kueue.
- Attività dello sviluppatore di AI: flussi di lavoro quotidiani ripetitivi, come la definizione dei requisiti del job di addestramento e l'invio del workload.
Anche se esegui tutti questi passaggi personalmente, tenere presente questa distinzione aiuta a chiarire il processo complessivo.
Prima di configurare il sistema, esamina i passaggi di configurazione che eseguirai.
Concetti fondamentali
- Pool di nodi on demand (piano A):il pool di nodi principale ad alta priorità. Il tuo job tenta sempre di utilizzare prima questo pool.
- Node pool di nodi avvio flessibile (piano B):il pool di nodi di backup. Se le macchine nel pool principale non sono disponibili, il sistema utilizza automaticamente questo pool per cercare hardware disponibile.
- Kueue:un programma di pianificazione che gestisce la coda dei job. Intercetta la richiesta di job e decide qualepool di nodil utilizzare (piano A o piano B).
- Job:il workload di addestramento AI che vuoi eseguire. In questo documento, lo definiamo utilizzando un manifest RayJob.
Prima di iniziare
-
Nella console Google Cloud , nella pagina di selezione del progetto, seleziona o crea un progetto Google Cloud .
Ruoli richiesti per selezionare o creare un progetto
- Seleziona un progetto: la selezione di un progetto non richiede un ruolo IAM specifico. Puoi selezionare qualsiasi progetto per il quale ti è stato concesso un ruolo.
-
Crea un progetto: per creare un progetto, devi disporre del ruolo Autore progetto
(
roles/resourcemanager.projectCreator), che contiene l'autorizzazioneresourcemanager.projects.create. Scopri come concedere i ruoli.
-
Verifica che la fatturazione sia abilitata per il tuo progetto Google Cloud .
Attiva le API Google Kubernetes Engine e Cloud TPU.
Ruoli richiesti per abilitare le API
Per abilitare le API, devi disporre del ruolo IAM Amministratore utilizzo dei servizi (
roles/serviceusage.serviceUsageAdmin), che include l'autorizzazioneserviceusage.services.enable. Scopri come concedere i ruoli.-
Nella console Google Cloud , attiva Cloud Shell.
-
Assicurati di avere una quota prerilasciabile sufficiente per utilizzare le VM TPU con avvio flessibile. Se la quota predefinita non è sufficiente per le tue esigenze, richiedi un'allocazione più elevata. Per i dettagli, consulta Quote di Cloud TPU e Configura l'ambiente Cloud TPU.
Definisci le variabili di ambiente
Per semplificare i comandi eseguiti in questo documento, puoi impostare le variabili di ambiente in Cloud Shell. Queste variabili memorizzano valori come l'ID del tuo progetto Google Cloud , i nomi dei tuoi pool di nodi e la posizione del tuo cluster GKE.
Dopo aver definito queste variabili, puoi riutilizzarle in più comandi facendo riferimento al nome della variabile (ad esempio, $CLUSTER_NAME) anziché digitare o sostituire i valori ogni volta. Questo approccio semplifica la procedura
e riduce il rischio di errori.
Per definire le seguenti variabili di ambiente utili in Cloud Shell, esegui i seguenti comandi:
export PROJECT_ID=$(gcloud config get project)
export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
export ZONE="us-east5-b"
export REGION="us-east5"
export CLUSTER_NAME="tpu-cluster"
export GKE_VERSION="1.34"
export ONDEMAND_NODEPOOL="on-demand-pool"
export DWS_NODEPOOL="dws-pool"
Ecco una spiegazione di queste variabili di ambiente:
PROJECT_ID: l'ID del tuo Google Cloud progetto.PROJECT_NUMBER: il numero identificatore univoco del tuo progetto (ad esempio, 123456789012).ZONE: la zona di computing del cluster (ad esempio,us-east5-b). Seleziona una zona con disponibilità per il tipo di acceleratore scelto. Per informazioni sulla disponibilità, consulta Quote di Cloud TPU o Quote di GPU.REGION: la regione in cui creare le risorse del cluster (ad esempio,us-east5).CLUSTER_NAME: il nome che scegli per il tuo cluster GKE.GKE_VERSION: la versione di GKE del tuo cluster. Utilizza la versione 1.34 o successive.ONDEMAND_NODEPOOL: il nome del tuo pool di nodi standard on demand. (questo è pool di nodil del piano A).DWS_NODEPOOL: il nome del tuo pool di nodi con avvio flessibile DWS. (Questo è il tuo pool di nodil di backup).
Configura l'infrastruttura (amministratore cluster)
In qualità di amministratore del cluster, configuri il cluster GKE e i node pool per supportare il meccanismo di fallback.
Crea un cluster GKE
Innanzitutto, crea il cluster GKE. Questo cluster è l'ambiente in cui installi il controller Kueue, configuri i node pool ed esegui i job di addestramento AI. Per creare un cluster e connetterti a esso:
Crea il cluster:
gcloud container clusters create ${CLUSTER_NAME} \ --cluster-version=${GKE_VERSION} \ --machine-type=n2-standard-16 \ --location=${ZONE} \ --enable-image-streaming \ --addons=RayOperator \ --project=${PROJECT_ID}Questo comando utilizza i seguenti flag chiave:
--addons=RayOperator: installa l'operatore Ray sul cluster. Questo operatore ti serve per gestire il workload RayJob che invierai più avanti in questo documento.--enable-image-streaming: consente al cluster di estrarre più rapidamente le immagini container. Questa funzionalità riduce notevolmente il tempo necessario per l'avvio delle immagini dei container AI di grandi dimensioni.
Recupera le credenziali del cluster in modo che la CLI kubectl possa connettersi al cluster. Questo comando aggiorna il file di configurazione di Kubernetes, archiviato per impostazione predefinita nella directory
~/.kube/config:gcloud container clusters get-credentials ${CLUSTER_NAME} \ --location=${ZONE} \ --project=${PROJECT_ID}
Crea i node pool
Crea i pool di nodi primario e di backup per il tuo ambiente: il pool di nodi on demand (piano A) e il pool di nodi con avvio flessibile DWS (piano B):
Crea il node pool on demand: questo pool funge da risorsa principale per i job di addestramento:
gcloud container node-pools create ${ONDEMAND_NODEPOOL} \ --cluster=${CLUSTER_NAME} \ --location=${ZONE} \ --machine-type=ct6e-standard-4t \ --tpu-topology=4x4 \ --reservation-affinity=none \ --enable-autoscaling \ --num-nodes=0 \ --min-nodes=0 \ --max-nodes=4In questo esempio, le macchine di prima scelta sono gli acceleratori TPU v6e. Specifica questo hardware utilizzando il flag
--machine-type=ct6e-standard-4t. Puoi modificare questo tipo di macchina in modo che corrisponda all'hardware, ad esempio GPU o TPU diverse, che vuoi per il tuo modello di AI.Crea il pool di nodi con avvio flessibile DWS: in questo esempio, seleziona lo stesso tipo di macchina (
--machine-type=ct6e-standard-4t) scelto per il pool di nodi on demand principale. Il pool di nodi del piano B non deve utilizzare un tipo di macchina diverso. Poiché vuoi davvero questo hardware specifico, sceglierlo come opzione di riserva significa solo che passerai a un altro metodo di acquisto se non è disponibile immediatamente. Questo metodo alternativo utilizza DWS, che cerca continuamente l'hardware disponibile fino a 7 giorni:gcloud container node-pools create ${DWS_NODEPOOL} \ --cluster=${CLUSTER_NAME} \ --location=${ZONE} \ --machine-type=ct6e-standard-4t \ --tpu-topology=4x4 \ --reservation-affinity=none \ --enable-autoscaling \ --enable-queued-provisioning \ --flex-start \ --num-nodes=0 \ --min-nodes=0 \ --max-nodes=4Questi comandi utilizzano i seguenti flag delle chiavi:
--num-nodes=0,--min-nodes=0,--max-nodes=4e--enable-autoscaling: questa combinazione consente ai pool di nodi di scalare da zero nodi quando un job ne ha bisogno e di ridimensionarsi quando sono inattivi, il che contribuisce a ridurre i costi.--tpu-topology: definisce la disposizione fisica dei chip TPU. Specifichi questo layout perché la disposizione fisica dei chip influisce sulla velocità di esecuzione del job di addestramento distribuito.--reservation-affinity=none: contribuisce a garantire che il pool di nodi non consumi l'hardware prenotato in anticipo. Google Cloud consente di prenotare macchine specifiche per garantire la disponibilità. Se imposti questo flag sunone, il sistema ignora queste prenotazioni e richiede dinamicamente macchine non riservate.--enable-queued-provisioninge--flex-start: (solo pool del piano B) Questi flag consentono a DWS di eseguire il provisioning dei nodi per il pool del piano B dalla capacità flessibile quando diventa disponibile.
Verifica lo stato dell'avvio flessibile nel pool di nodi
Ispeziona il pool di nodi DWS con avvio flessibile e verifica che l'avvio flessibile sia abilitato:
gcloud container node-pools describe ${DWS_NODEPOOL} \
--cluster=${CLUSTER_NAME} \
--location=${ZONE} \
--format="get(config.flexStart)"
Se l'avvio flessibile è abilitato, l'output è True.
Installare e configurare Kueue (amministratore del cluster)
In questa sezione, installerai il controller Kueue sul tuo cluster. Ricorda che Kueue è un programma di pianificazione che gestisce la coda dei job. Intercetta la richiesta di job, decide quale pool di nodi utilizzare (on demand o DWS avvio flessibile) e poi assegna il job.
Installa Kueue
Esegui questo comando per installare Kueue. Questo comando scarica i manifest di installazione dal repository ufficiale e li applica al tuo cluster:
helm install kueue oci://registry.k8s.io/kueue/charts/kueue \
--namespace kueue-system \
--create-namespace \
--set "controllerManager.featureGates[0].name=ElasticJobsViaWorkloadSlices" \
--set "controllerManager.featureGates[0].enabled=true"
Definisci le regole di configurazione
Crea un manifest YAML che definisca le regole di priorità. Queste regole indicano a Kueue di utilizzare prima il pool on demand e poi il pool DWS ad avvio flessibile:
Crea un file denominato
dws-tpu-queue.yamlcon il seguente contenuto. Questo file definisce due varianti di risorse (on demand e DWS ad avvio flessibile) e una coda del cluster che assegna loro la priorità. Questo file di configurazione definisce la logica utilizzata da Kueue per gestire i job:ResourceFlavor: all'inizio di questo documento, hai creato due pool di nodi e hai assegnato loro dei nomi utilizzando le variabili di ambiente${ONDEMAND_NODEPOOL}e${DWS_NODEPOOL}. Quando ha creato questi pool di nodi, GKE ha etichettato automaticamente ogni nodo di questi pool con il nome scelto per queste variabili di ambiente. La sezioneResourceFlavorindica a Kueue di cercare nodi con queste etichette.ClusterQueue: questa sezione del manifest definisce la regola di priorità. Elenca prima il tipo on demand, quindi Kueue tenta di eseguire il provisioning delle macchine on demand. Se Kueue non riesce a ottenere queste macchine, prova a eseguire il provisioning di macchine DWS ad avvio flessibile.Quotas: il file imposta una quota, ovvero un limite alle risorse totali (come CPU, memoria e chip TPU) che i tuoi job possono utilizzare in qualsiasi momento nel pool di nodi on demand. Quando i tuoi job raggiungono questo limite, Kueue tenta automaticamente di eseguire il provisioning delle macchine DWS con avvio flessibile (le macchine di riserva), che hai configurato indws-tpu-queue.yamlcon un limite di quota molto più elevato.
Applica la configurazione al cluster. Il seguente comando utilizza uno strumento a riga di comando chiamato
envsubstper sostituire le variabili segnaposto che appaiono nel filedws-tpu-queue.yaml.envsubstsostituisce i segnaposto con i valori delle variabili di ambiente che hai definito in precedenza:envsubst < dws-tpu-queue.yaml | kubectl apply -f -
Esegui un job di addestramento (sviluppatore di AI)
In qualità di sviluppatore di AI, definisci e invii un carico di lavoro di addestramento creando un manifest RayJob. Specifichi i requisiti delle risorse in questo manifest e il sistema di fallback automatico, configurato in precedenza dall'amministratore del cluster con Kueue e DWS, gestisce i pool di nodi sottostanti.
In questa sezione, esegui i seguenti passaggi:
- Crea uno script di addestramento Python.
- Archivia lo script in un ConfigMap Kubernetes.
- Esegui il deployment di un RayJob che monta ConfigMap come volume in modo che lo script di addestramento possa essere eseguito sui nodi.
Dopo aver eseguito questi passaggi, Ray Train distribuisce automaticamente il carico di lavoro JAX tra i nodi e Kueue gestisce l'ottenimento delle macchine necessarie.
Lo script di addestramento
Copia e incolla il seguente script Python in un file chiamato train.py:
Lo script di addestramento utilizza JAX, una libreria Python per il calcolo numerico ad alte prestazioni, per addestrare un modello di regressione lineare. Questo script è un esempio semplificato progettato per mostrare come utilizzare DWS e Kueue per il fallback automatico e non esegue il parallelismo dei dati o il parallelismo del modello.
Tieni presente che la sezione ScalingConfig dello script di addestramento definisce i
requisiti hardware per il job di addestramento. Questa sezione richiede una topologia TPU 4x4, che corrisponde al layout fisico dei node pool configurati in precedenza.
Crea ConfigMap
Carica i contenuti dello script train.py in un oggetto Kubernetes
ConfigMap. In questo modo, il cluster può archiviare lo script e renderlo
disponibile per RayJob:
kubectl create configmap jax-train-script --from-file=train.py
Il RayJob che definisci nella sezione successiva monta questo ConfigMap come volume. In questo modo, il file di script viene visualizzato all'interno dei container Ray in modo che il software Ray possa trovarlo ed eseguirlo.
Applica il manifest RayJob
Crea un file denominato rayjob-tpu-v6e-dws.yaml con il seguente contenuto. Questo
manifest definisce il job di addestramento e indica al sistema come instradarlo:
Questo manifest include tre configurazioni che consentono il funzionamento del sistema di fallback:
- Richiede hardware specifico:la sezione
nodeSelectorspecifica l'hardware richiesto dallo script (in questo esempio, unatpu-v6e-slicecon una topologia 4x4). - Seleziona la coda:l'etichetta
kueue.x-k8s.io/queue-nameindirizza il job direttamente a Kueue. In questo modo viene attivata la logica di fallback automatica. - Tollera i nodi di avvio flessibile DWS:la sezione
tolerationsconsente al job di essere eseguito sul tuo pool di nodi di piano B. Poiché i nodi con inizio flessibile DWS sono contrassegnati in modo speciale (tainted) da GKE in modo che i carichi di lavoro normali non vengano eseguiti accidentalmente, il tuo job deve tollerare esplicitamente il taintcloud.google.com/gke-queued.
Invia il workload
Per dimostrare che il sistema di fallback funziona, devi inviare due job. Il primo job utilizza la capacità on demand del piano A, il che costringe il secondo job a utilizzare la capacità di avvio flessibile DWS del piano B.
Esegui questo comando per inviare i due job. Il comando utilizza un ciclo for
e envsubst per inserire un ID job univoco nel manifest per ogni esecuzione:
for i in 1 2; do
export JOB_ID=$i
envsubst < rayjob-tpu-v6e-dws.yaml | kubectl apply -f -
echo "Submitted Job $i"
sleep 2
done
Dopo l'invio dei job, il sistema gestisce il workload nel seguente modo:
- Intercettazione:Kueue rileva i job utilizzando l'etichetta della coda e li sospende temporaneamente.
- Decisione: Kueue valuta la disponibilità delle risorse in base alle regole dell'amministratore. Controlla prima il pool del piano A.
- Compito:
- Poiché le risorse del piano A sono disponibili per il primo job, Kueue assegna il job 1 a questo piano.
- Poiché il job 1 utilizza le risorse del piano A, Kueue assegna automaticamente il job 2 al pool del piano B (avvio flessibile DWS).
- Lancio:Kueue riattiva i job. Questa azione attiva il gestore della scalabilità automatica del cluster GKE per eseguire il provisioning dei nodi e avviare gli script di addestramento.
Connettiti a RayJob
Come passaggio di verifica finale, puoi utilizzare il comando kubectl port-forward per
connetterti alla dashboard Ray e osservare l'esecuzione dei job.
Per controllare lo stato del primo job, esegui questo comando:
kubectl port-forward service/rayjob-tpu-v6e-dws-1-head-svc 8265:8265 &
Dopo aver eseguito questo comando, apri un browser web e vai a
http://localhost:8265. Nella dashboard Ray, puoi visualizzare lo stato del job e
le metriche riportate per verificare che entrambi i job vengano completati correttamente nei rispettivi pool di nodi.
Puoi anche visualizzare i log del primo job eseguendo questo comando:
kubectl logs job/rayjob-tpu-v6e-dws-1
L'output troncato dello script di addestramento dovrebbe essere simile al seguente. Dovresti
vedere i messaggi Training Complete! e Job
'rayjob-tpu-v6e-dws-1-498t6' succeeded verso la fine dell'output:
(pid=, ip=10.68.3.4) 5] XLA::TPU program HBM usage: 52.5K / 31.25G
(pid=, ip=10.68.9.4) :2152] XLA::TPU program VMEM usage: 141.0K / 128.00M [repeated 5x across cluster]
(pid=, ip=10.68.9.4) I0320 03:59:34.722540 855 deepsea_compiler_backend.cc:2163] Total hbm usage >= 260.14M: [repeated 5x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777634 888 deepsea_compiler_backend.cc:2167] reserved 204B [repeated 19x across cluster]
(pid=, ip=10.68.9.4) I0320 03:59:34.722542 855 deepsea_compiler_backend.cc:2163] program 70.0K [repeated 5x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777626 888 deepsea_compiler_backend.cc:2163] arguments 0B [repeated 12x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777627 888 deepsea_compiler_backend.cc:2163] Output size 0B; shares 0B with arguments. [repeated 14x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777625 888 deepsea_compiler_backend.cc:2163] Total host usage >= 0B: [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777626 888 deepsea_compiler_backend.cc:2163] program unknown size [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777634 888 deepsea_compiler_backend.cc:2167] Program sflag requirement 224B: [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777637 888 deepsea_compiler_backend.cc:2167] scoped 40B [repeated 21x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777636 888 deepsea_compiler_backend.cc:2167] Program vmem requirement 141.0K: [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777637 888 deepsea_compiler_backend.cc:2167] Program smem requirement 40B: [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777637 888 deepsea_compiler_backend.cc:2167] Program host requirement 0B: [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777637 888 deepsea_compiler_backend.cc:2167] Program hbm requirement 70.0K: [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777638 888 deepsea_compiler_backend.cc:2167] overlays 70.0K [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777638 888 deepsea_compiler_backend.cc:2175] XLA::TPU program SMEM usage: 1.9K / 1.00M (3 parameters) [repeated 7x across cluster]
(pid=, ip=10.68.6.4) I0320 03:59:34.777636 888 deepsea_compiler_backend.cc:2167] HLO temp 76.0K (0.0% utilization: Unpadded (0B) Padded (0B), 100.0% fragmentation (76.0K)) [repeated 14x across cluster]
(RayTrainWorker pid=542, ip=10.68.6.4) Training Complete! [repeated 3x across cluster]
(RayTrainWorker pid=542, ip=10.68.6.4) Epoch 40: Loss 0.0000 [repeated 3x across cluster]
2026-03-20 03:59:51,008 SUCC cli.py:65 -- ------------------------------------------
2026-03-20 03:59:51,008 SUCC cli.py:66 -- Job 'rayjob-tpu-v6e-dws-1-498t6' succeeded
2026-03-20 03:59:51,008 SUCC cli.py:67 -- ------------------------------------------
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo documento, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.
Elimina il progetto
Elimina le singole risorse
Se vuoi conservare il progetto GGoogle Cloud che hai utilizzato in questo documento, esegui il seguente comando per eliminare il cluster:
gcloud container clusters delete ${CLUSTER_NAME} \
--location=${ZONE} \
--project=${PROJECT_ID} \
--quiet
Riepilogo
In questo documento hai configurato e testato un ambiente di addestramento Ray. Questo ambiente utilizza unpool di nodil principale e un pool DWS di backup per massimizzare la disponibilità dell'hardware. Eseguendo automaticamente il failover su DWS quando le macchine principali non sono disponibili, hai ridotto al minimo il tempo di attesa dei job di addestramento.
Per far funzionare questa configurazione, hai eseguito i seguenti passaggi:
- È stato creato un cluster GKE:è stato creato l'ambiente per ospitare i node pool e gli strumenti di pianificazione.
- Configurato i pool di nodi:è stato creato un pool di nodi on demand (piano A) e un pool di nodi DWS (piano B).
- Kueue installato e configurato:è stato eseguito il deployment del controller Kueue e sono state applicate regole di priorità che indicano al sistema di provare prima il piano A e di ripiegare sul piano B.
- Creazione di un ConfigMap:deployment di uno script di addestramento JAX semplificato nel cluster per fungere da workload di test.
- Definito un manifest RayJob:configurato il job per richiedere hardware specifico, indirizzare al controller Kueue e tollerare i nodi DWS.
- Invio del workload:invio di due job per forzare Kueue a instradare automaticamente il secondo job al piano B quando le risorse del piano A sono utilizzate.
- Verifica dei risultati:ha utilizzato l'inoltro delle porte per connettersi alla dashboard Ray e ha confermato che entrambi i job sono stati eseguiti correttamente.
Passaggi successivi
- Scopri come visualizzare i log e le metriche per i cluster e i job Ray.
- Scopri come gestire carichi di lavoro TPU distribuiti più grandi che si estendono su più slice.