Questo documento descrive gli strumenti e le best practice per massimizzare l'utilizzo delle risorse e ridurre al minimo i tempi di inattività dei carichi di lavoro AI/ML eterogenei in Google Kubernetes Engine (GKE), in particolare quando non è disponibile capacità nelle prenotazioni o tramite risorse on demand. I workload eterogenei si riferiscono a diversi tipi di workload AI/ML eseguiti contemporaneamente nello stesso cluster GKE. Ad esempio, potresti eseguire un servizio di inferenza online sensibile alla latenza insieme a una serie di job di addestramento batch interrompibili.
Questa guida fornisce consigli per gli amministratori e gli operatori della piattaforma e per gli specialisti di dati e AI.
Vantaggi della definizione delle priorità dei workload AI/ML
I workload eterogenei hanno priorità diverse e condividono capacità e risorse limitate. Le best practice in questa pagina descrivono come configurare GKE e gli strumenti open source per aiutarti a ottenere i seguenti vantaggi:
- Ridurre al minimo i tempi di inattività per i carichi di lavoro ad alta priorità.
- Esegui rapidamente i carichi di lavoro ad alta priorità.
- Ottimizza il consumo delle risorse.
Sfondo
GKE supporta i seguenti strumenti open source per ottimizzare l'utilizzo delle risorse.
Kueue:un sistema di accodamento dei workload nativo di Kubernetes progettato per carichi di lavoro batch, AI e di computing ad alte prestazioni. Kueue può essere esteso per gestire altri tipi di carichi di lavoro, ad esempio quelli definiti da definizioni di risorse personalizzate come
leaderworkerset. Kueue gestisce le quote e il modo in cui i carichi di lavoro le utilizzano in un cluster Kubernetes. Kueue decide quando un workload deve attendere, quando deve iniziare (ad esempio creando il pod) e quando un pod appartenente a un workload viene preempted.Per saperne di più su Kueue, consulta la documentazione relativa ai concetti di Kueue.
Sostituzione a caldo:una tecnica che riduce il tempo medio di ripristino (MTTR). Lo scambio a caldo consente la preemptive in base alla priorità del workload quando le risorse del cluster sono utilizzate completamente e non è disponibile capacità aggiuntiva, né da istanze on demand né da prenotazioni esistenti.
- Quando un nodo che ospita un carico di lavoro non è integro, il carico di lavoro viene ripianificato sui nodi di riserva idonei. Se non sono disponibili nodi di riserva, Hotswap può interrompere un workload con priorità inferiore per fare spazio al workload in fase di recupero.
- Se configuri i tuoi pod con
PriorityClass, il workload configurato con priorità più elevata espelle un workload a bassa priorità in esecuzione per acquisirne le risorse. Questa procedura di espulsione è nota come prerilascio.
Casi d'uso
Utilizza la seguente tabella per comprendere le best practice per ogni caso d'uso:
| Caso d'uso | Best practice | Descrizione |
|---|---|---|
| Più workload con priorità diverse | Utilizza Kueue per definire le code e assegnare priorità ai carichi di lavoro in base alla loro importanza. Kueue può gestire le quote in modo che determinati team o progetti abbiano accesso a una quantità fissa di risorse. |
Kueue ti consente di applicare le seguenti configurazioni:
Per testare la configurazione delle best practice, consulta l'esempio di Kueue in questo documento. |
| Devi ridurre l'MTTR attuale. | Utilizza Hotswap per riprogrammare i workload nelle risorse integre quando si verifica un'interruzione e per prerilasciare i workload a bassa priorità a favore di quelli ad alta priorità. |
Lo scambio a caldo ti consente di applicare le seguenti configurazioni:
Per testare la configurazione delle best practice, consulta l'esempio di sostituzione a caldo in questo documento. |
| Più workload di AI in competizione per risorse limitate | Combina Kueue e Hotswap. Questa combinazione fornisce un sistema solido che assegna la priorità ai workload critici sia durante la pianificazione iniziale sia durante l'esecuzione. |
Kueue e Hotswap ti consentono di applicare le seguenti configurazioni:
Per testare la configurazione delle best practice, consulta l'esempio di Kueue e Hotswap in questo documento. |
Esempi di implementazioni delle best practice
Gli esempi seguenti mostrano come implementare Kueue e Hotswap e come combinarli per le best practice descritte nella sezione precedente.
Kueue
Il seguente manifest di esempio mostra una configurazione di Kueue:
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: tpu-v6e-slice
spec:
nodeLabels:
cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: tpu-training-cq
spec:
resourceGroups:
- flavors:
- name: tpu-v6e-slice
resources:
- name: google.com/tpu
nominalQuota: 32
queueingStrategy: BestEffortFIFO
preemption:
reclaimWithinCohort: Never
reclaimOutOfCohort:
enable: true
reclaimMoreThanNominalQuota: false
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
name: default-queue
namespace: default
spec:
clusterQueue: tpu-training-cq
Questo manifest svolge le seguenti operazioni:
- Definisce un
ResourceFlavordenominatotpu-v6e-sliceche specifica le etichette dei nodi per gli slice TPU v6e. - Definisce un
ClusterQueuedenominatotpu-training-cqche gestisce la quota per le risorse TPU. - Definisce un
LocalQueuedenominatodefault-queueche consente ai workload nello spazio dei nomidefaultdi utilizzare la coda del clustertpu-training-cq.
Sostituzione a caldo
L'esempio seguente mostra una configurazione Hotswap che definisce
due classi di priorità, low-priority-job e high-priority-job. Questa
configurazione Hotswap crea un carico di lavoro JobSet ad alta priorità e utilizza
MaxText.
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low-priority-job
value: 1000000
globalDefault: false
description: "This priority class should be used for low priority pods only."
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority-job
value: 2000000
globalDefault: false
description: "This priority class should be used for critical pods only."
---
apiVersion: jobset.x-k8s.io/v1alpha2
kind: JobSet
metadata:
name: high-jax-trillium
annotations:
alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool
spec:
failurePolicy:
maxRestarts: 10
restartStrategy: BlockingRecreate
replicatedJobs:
- name: slice
replicas: 2
template:
spec:
backoffLimit: 0
completions: 4
parallelism: 4
template:
spec:
nodeSelector:
cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
cloud.google.com/gke-tpu-topology: 4x4
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
priorityClassName: high-priority-job
containers:
- name: jax-program
image: <IMAGE LOCATION>
command:
- python3
- MaxText/train.py
- MaxText/configs/base.yml
- model_name=llama2-7b
- run_name=<UNIQUE RUN NAME>
- steps=300
- base_output_directory=gs://<OUTPUT BUCKET>
- dataset_path=gs://max-datasets-rogue
- max_target_length=4096
- dataset_type=synthetic
- enable_checkpointing=False
resources:
limits:
google.com/tpu: 4
In base a questa configurazione, Hotswap esegue le seguenti azioni:
- Se un errore dell'infrastruttura interrompe il workload ad alta priorità, JobSet lo riavvia. Lo scambio a caldo ha la precedenza sul carico di lavoro a bassa priorità per riprogrammare il carico di lavoro ad alta priorità prima che l'infrastruttura venga ripristinata. Il carico di lavoro a bassa priorità rimane nello stato Non riuscito. Questo processo riduce notevolmente il tempo di inattività del workload.
- Quando l'infrastruttura viene ripristinata, Hotswap riprogramma il workload a bassa priorità nel pool di nodi ripristinato.
Kueue e Hotswap
Combina Kueue e Hotswap quando operi in un ambiente complesso con risorse limitate. Questa combinazione fornisce un sistema solido che assegna la priorità ai carichi di lavoro critici durante la pianificazione iniziale e durante l'esecuzione.
L'esempio seguente mostra una configurazione combinata di Kueue e Hotswap. Questo esempio utilizza MaxText:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: low-priority-job
value: 1000000
globalDefault: false
description: "This priority class should be used for low priority pods only."
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority-job
value: 2000000
globalDefault: false
description: "This priority class should be used for critical pods only."
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: tpu-v6e-slice
spec:
nodeLabels:
cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: tpu-training-cq
spec:
resourceGroups:
- flavors:
- name: tpu-v6e-slice
resources:
- name: google.com/tpu
nominalQuota: 32
queueingStrategy: BestEffortFIFO
preemption:
reclaimWithinCohort: Never
reclaimOutOfCohort:
enable: true
reclaimMoreThanNominalQuota: false
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
name: default-queue
namespace: default
spec:
clusterQueue: tpu-training-cq
---
apiVersion: jobset.x-k8s.io/v1alpha2
kind: JobSet
metadata:
name: low-jax-trillium
annotations:
kueue.x-k8s.io/queue-name: default-queue
alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool
spec:
failurePolicy:
maxRestarts: 10
restartStrategy: BlockingRecreate
replicatedJobs:
- name: slice
replicas: 2
template:
spec:
backoffLimit: 0
completions: 4
parallelism: 4
template:
metadata:
labels:
kueue.x-k8s.io/managed-by: kueue
kueue.x-k8s.io/priority-class: low-priority-job
spec:
nodeSelector:
cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
cloud.google.com/gke-tpu-topology: 4x4
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
priorityClassName: low-priority-job
containers:
- name: jax-program
image: <IMAGE LOCATION>
command:
- python3
- MaxText/train.py
- MaxText/configs/base.yml
- model_name=llama2-7b
- run_name=low-priority-run
- steps=30000
- base_output_directory=gs://<OUTPUT BUCKET>
- dataset_path=gs://max-datasets-rogue
- max_target_length=4096
- dataset_type=synthetic
- enable_checkpointing=False
resources:
limits:
google.com/tpu: 4
---
apiVersion: jobset.x-k8s.io/v1alpha2
kind: JobSet
metadata:
name: high-jax-trillium
annotations:
kueue.x-k8s.io/queue-name: default-queue
alpha.jobset.sigs.k8s.io/exclusive-topology: cloud.google.com/gke-nodepool
spec:
failurePolicy:
maxRestarts: 10
restartStrategy: BlockingRecreate
replicatedJobs:
- name: slice
replicas: 2
template:
spec:
backoffLimit: 0
completions: 4
parallelism: 4
template:
metadata:
labels:
kueue.x-k8s.io/managed-by: kueue
kueue.x-k8s.io/priority-class: high-priority-job
spec:
nodeSelector:
cloud.google.com/gke-tpu-accelerator: tpu-v6e-slice
cloud.google.com/gke-tpu-topology: 4x4
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
priorityClassName: high-priority-job
containers:
- name: jax-program
image: <IMAGE LOCATION>
command:
- python3
- MaxText/train.py
- MaxText/configs/base.yml
- model_name=llama2-7b
- run_name=high-priority-run
- steps=300
- base_output_directory=gs://<OUTPUT BUCKET>
- dataset_path=gs://max-datasets-rogue
- max_target_length=4096
- dataset_type=synthetic
- enable_checkpointing=False
resources:
limits:
google.com/tpu: 4
In base a questa configurazione, Kueue viene combinato con Hotswap ed esegue le seguenti azioni:
- Kueue gestisce l'ammissione di
low-jax-trilliumehigh-jax-trilliumJobSet nella coda del cluster in base alle priorità definite e alle risorse disponibili. - Se il
high-jax-trilliumJobSet viene interrotto da un errore dell'infrastruttura, Hotswap esegue l'interruzione preventiva del JobSetlow-jax-trilliumper riprogrammare il JobSet a priorità elevata. - Lo scambio a caldo garantisce il riavvio rapido di JobSet ad alta priorità, riducendo al minimo il suo tempo di inattività.
- Quando l'infrastruttura viene ripristinata, Hotswap riprogramma il JobSet a bassa priorità nel pool di nodi ripristinato.
Passaggi successivi
- Scopri come eseguire il deployment dei carichi di lavoro GPU in GKE.
- Scopri come eseguire il deployment dei carichi di lavoro TPU in GKE.