Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a: ✔️ Servizio Azure Kubernetes Standard automatico ✔️ Servizio Azure Kubernetes standard
MLOps è un set di procedure per la distribuzione, il monitoraggio e la gestione di modelli di Machine Learning negli ambienti di produzione.
Procedure consigliate principali di MLOps descritte in questo articolo:
- Infrastruttura distribuita come codice (IaC)
- Containerizzazione
- Gestione e controllo delle versioni dei modelli
- Automazione
- Scalabilità e gestione delle risorse
- Affidabilità dei processi batch a esecuzione prolungata
- Sicurezza e conformità
Questo articolo descrive le procedure consigliate e le considerazioni da tenere presenti quando si usa MLOps nel servizio Azure Kubernetes. Per altre informazioni su MLOps, vedere Operazioni di Machine Learning (MLOps) per i flussi di lavoro di Intelligenza artificiale e Machine Learning.
Scegli la modalità AKS per MLOps
AKS supporta due modalità del cluster: AKS Automatico e AKS Standard. Scegliere AKS Automatic quando si vuole una configurazione di base pronta per la produzione con meno attività di gestione della piattaforma successive alla distribuzione. Scegliere AKS Standard quando è necessario un controllo più approfondito sull'infrastruttura del cluster e sulla configurazione della piattaforma.
Le procedure MLOps descritte in questo articolo si applicano a entrambe le modalità. Tuttavia, la responsabilità dell'implementazione varia in base alla modalità: Il servizio Azure Kubernetes automatico fornisce impostazioni predefinite più preconfigurate, mentre il servizio Azure Kubernetes Standard richiede in genere una configurazione della piattaforma e una proprietà del ciclo di vita più espliciti.
| Area | AKS Automatico | Servizio Azure Kubernetes Standard |
|---|---|---|
| Configurazione del cluster di base | Pool di nodi preconfigurati, rete e monitoraggio pronti all’uso | Richiede la configurazione manuale di pool di nodi, CNI e stack di osservabilità |
| Operazioni del pool di nodi di sistema | Provisioning e ridimensionamento automatici dei nodi gestiti dal servizio | L'operatore deve configurare il ridimensionamento del pool di nodi, le regole di ridimensionamento e le finestre di manutenzione |
| Controlli di sicurezza di base | Criteri di rete, standard di sicurezza dei pod e identità del carico di lavoro abilitati per impostazione predefinita | Gli operatori devono abilitare e configurare in modo esplicito i criteri di rete, la sicurezza dei pod e le impostazioni di identità |
| Baseline di rete | Azure CNI Overlay preconfigurato con gli schemi di ingresso predefiniti | Flessibilità completa per scegliere il plug-in CNI, configurare controller di ingresso personalizzati e definire la topologia di rete |
| Operazioni e aggiornamenti | Aggiornamenti automatici dell'immagine del nodo e della versione di Kubernetes | Gli operatori pianificano e gestiscono le tempistiche degli aggiornamenti e la strategia di distribuzione |
| Focus sull'implementazione di MLOps | Convalidare, gestire e ottimizzare le impostazioni predefinite | Progettare e configurare i controlli della piattaforma |
| Capacità gpu e pianificazione | È possibile effettuare automaticamente il provisioning della capacità GPU idonea in base alle richieste di risorse del carico di lavoro e ai vincoli di pianificazione, in funzione della disponibilità regionale dello SKU e della quota della sottoscrizione | Gli operatori creano e gestiscono pool di nodi GPU, etichette, taint, limiti dell'autoscaler, driver e configurazione del device plugin |
| Training distribuito | La pianificazione predefinita di Kubernetes e il provisioning automatico dei nodi forniscono un punto di partenza; gli operatori per l'addestramento, gli scheduler gang e l'ottimizzazione della topologia restano scelte a livello di workload | Gli operatori installano esplicitamente operatori di training e scheduler e progettano pool di nodi con GPU, configurazione di rete, scalabilità e collocazione per i job distribuiti |
Infrastruttura come codice (IaC)
Considerazioni chiave: definire e modificare i modelli IaC per ogni fase della pipeline di intelligenza artificiale per garantire coerenza, efficienza dei costi e distribuzioni più veloci.
IaC consente il provisioning e la gestione coerenti e riproducibili dell'infrastruttura per una gamma di tipi di applicazioni. Con distribuzioni di applicazioni diverse, l'implementazione IaC potrebbe cambiare in tutta la pipeline di intelligenza artificiale, perché la potenza di calcolo e le risorse necessarie per l'inferenza, la gestione, il training e l'ottimizzazione dei modelli possono variare. La definizione e il controllo delle versioni dei modelli IaC per i team di sviluppo di intelligenza artificiale possono contribuire a garantire coerenza e efficienza tra i tipi di processi, chiarire i requisiti hardware e accelerare il processo di distribuzione.
In AKS Automatic, IaC può concentrarsi maggiormente sulle definizioni dei carichi di lavoro, sui vincoli di protezione dei criteri e sulla coerenza dell'ambiente, più che sui valori predefiniti della piattaforma. In AKS Standard, IaC include comunemente impostazioni della piattaforma del cluster più specifiche, come la rete, la scalabilità e le scelte di configurazione operativa.
Containerizzazione
Considerazioni chiave: peso del modello di pacchetto, metadati e configurazioni nelle immagini del contenitore per abilitare la portabilità, il controllo delle versioni semplificate e ridurre i costi di archiviazione.
La gestione dei pesi, dei metadati e delle configurazioni del modello nelle immagini container consente una maggiore portabilità, una gestione delle versioni semplificata e costi di archiviazione inferiori nel tempo. Con la containerizzazione, è possibile:
- Utilizza immagini di container esistenti, in particolare per modelli linguistici di grandi dimensioni (LLM) con un numero di parametri che va da milioni a miliardi e per modelli Stable Diffusion, archiviati in registri di container sicuri.
- Evitare un singolo punto di errore nella pipeline usando più contenitori leggeri che contengono le dipendenze univoche per ogni attività anziché mantenere un'immagine di grandi dimensioni.
- Archiviare set di dati di testo e immagine di grandi dimensioni all'esterno dell'immagine del contenitore di base e farvi riferimento quando necessario in fase di esecuzione. Inizia a usare Kubernetes AI Toolchain Operator (KAITO) per distribuire un LLM su AKS.
I controlli della supply chain dei contenitori rimangono essenziali in entrambe le modalità. Anche con le configurazioni predefinite della piattaforma in AKS Automatic, la provenienza delle immagini, la scansione e la protezione avanzata in fase di esecuzione restano responsabilità fondamentali dell’MLOps.
Modello Dockerfile per carichi di lavoro ml:
Usare un tag esplicito dell'immagine di base con supporto CUDA per i carichi di lavoro di training su GPU (ad esempio, pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime) anziché un riferimento a un'immagine di base senza tag. Aggiungere l'immagine in base al digest nell'ambiente di produzione per garantire compilazioni riproducibili e un comportamento CUDA/cuDNN prevedibile. Mantenere separate le varianti dell'immagine per CPU e GPU, in modo che l'allocazione dello scheduler e le dipendenze di runtime restino esplicite.
Gestione e controllo delle versioni dei modelli
Considerazioni chiave: versione dei modelli sistematicamente per mantenere la coerenza tra gli ambienti e abilitare un'iterazione più veloce con metodi di ottimizzazione efficiente dei parametri.
La gestione e il controllo delle versioni dei modelli sono essenziali per tenere traccia delle modifiche apportate ai modelli nel tempo. Versionando i modelli, è possibile:
- Mantenere la coerenza tra i contenitori del modello per semplificare la distribuzione in ambienti diversi.
- Impiegare metodi PEFT (Parameter-Efficient Fine-Tuning) per iterare più rapidamente su un sottoinsieme dei pesi del modello e mantenere nuove versioni in contenitori leggeri.
In AKS Automatic, le baseline della piattaforma preconfigurate possono semplificare l'uniformità tra ambienti. In AKS Standard, i team spesso devono applicare la parità in modo più esplicito tramite la configurazione della piattaforma e della distribuzione.
Automazione
Considerazioni chiave: automatizzare l'inserimento dei dati, il monitoraggio delle prestazioni del modello e ripetere il training delle pipeline per ridurre gli errori manuali e garantire la coerenza nel ciclo di vita di Machine Learning.
L'automazione consente di ridurre gli errori manuali, aumentare l'efficienza e garantire la coerenza nel ciclo di vita di Machine Learning. Automatizzando le attività, è possibile:
- Integra gli strumenti di allerta per attivare un flusso di acquisizione di vettori man mano che nuovi dati confluiscono nella tua applicazione.
- Impostare le soglie di prestazione del modello per monitorare i degradi delle prestazioni e attivare le pipeline di riaddestramento.
In entrambe le modalità AKS, includere l'automazione per la convalida dei criteri, il rilevamento della deriva della configurazione e la governance delle versioni, oltre ai trigger relativi alla qualità del modello.
Scalabilità e gestione delle risorse
Considerazioni chiave: ottimizzare l'utilizzo delle risorse tramite il calcolo distribuito, la scalabilità automatica e la pianificazione del ripristino di emergenza per gestire le diverse richieste di pipeline di intelligenza artificiale in modo conveniente.
La scalabilità e la gestione delle risorse sono fondamentali per garantire che la pipeline di intelligenza artificiale possa gestire le esigenze dell'applicazione. Ottimizzando l'utilizzo delle risorse, è possibile:
- Integrare gli strumenti che usano in modo efficiente le risorse di CPU, GPU e memoria allocate tramite il calcolo distribuito e più livelli di parallelismo, ad esempio dati, modelli e parallelismo della pipeline.
- Abilitare la scalabilità automatica nelle risorse di calcolo per supportare volumi di richieste di modelli elevati nei momenti di picco e ridurre le ore di minore attività.
- Pianifica il ripristino di emergenza seguendo le procedure consigliate di resilienza e affidabilità per AKS.
AKS Automatic può ridurre il sovraccarico di configurazione per scenari comuni di scalabilità e operatività, mentre AKS Standard offre un controllo più granulare per architetture di scalabilità personalizzate.
Eseguire processi batch con esecuzione prolungata
Passaggio chiave: eseguire il lavoro finito come Kubernetes Job, rendere persistente lo stato di avanzamento all'esterno del pod, gestire i segnali di terminazione e presupporre che il processo possa iniziare più volte.
Gli aggiornamenti dei nodi, i riavvii, gli eventi di riduzione delle prestazioni, la pressione delle risorse, la precedenza e gli errori dell'infrastruttura possono interrompere i processi batch a esecuzione prolungata. Un kubernetes Job sostituisce un pod non riuscito o eliminato, ma la sostituzione viene avviata in un altro nodo senza i file locali o la memoria del processo del pod precedente. Progettare l'applicazione in modo che possa riprendere da uno stato persistente e rieseguire le operazioni in sicurezza.
Usa queste pratiche per processi batch normali a uso intensivo di CPU, memoria o I/O. Le linee guida sulla pianificazione di gruppo e sulla coda dei carichi di lavoro si applicano nei casi in cui un carico di lavoro distribuito richiede che più worker si avviino contemporaneamente o in cui i team necessitano di quote condivise. Un job con un solo worker o un job batch parallelizzabile in modo indipendente di norma non richiede il gang scheduling.
Configurare i punti di controllo, i tentativi e la terminazione
L'esempio seguente elabora una sequenza di elementi di lavoro e registra l'elemento successivo in un volume permanente File di Azure. Ripristina il checkpoint dopo la sostituzione di un pod e salva lo stato di avanzamento quando il processo riceve SIGTERM:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: batch-checkpoints
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile-csi
resources:
requests:
storage: 10Gi
---
apiVersion: batch/v1
kind: Job
metadata:
name: checkpointed-batch
spec:
backoffLimit: 6
activeDeadlineSeconds: 86400
ttlSecondsAfterFinished: 86400
podFailurePolicy:
rules:
- action: Ignore
onPodConditions:
- type: DisruptionTarget
template:
metadata:
labels:
app: checkpointed-batch
spec:
restartPolicy: Never
terminationGracePeriodSeconds: 120
containers:
- name: worker
image: ubuntu:24.04
command:
- /bin/bash
- -c
- |
set -euo pipefail
CHECKPOINT=/checkpoints/next-item
NEXT_ITEM=1
if [[ -f "${CHECKPOINT}" ]]; then
NEXT_ITEM="$(cat "${CHECKPOINT}")"
echo "Resuming at item ${NEXT_ITEM}."
fi
save_checkpoint() {
printf '%s\n' "${NEXT_ITEM}" > "${CHECKPOINT}.tmp"
mv "${CHECKPOINT}.tmp" "${CHECKPOINT}"
echo "Saved checkpoint for item ${NEXT_ITEM}."
}
terminate() {
echo "Received a termination signal."
save_checkpoint
exit 143
}
trap terminate TERM INT
while (( NEXT_ITEM <= 1000 )); do
echo "Processing item ${NEXT_ITEM}."
sleep 10
NEXT_ITEM=$((NEXT_ITEM + 1))
save_checkpoint
done
echo "Batch completed."
resources:
requests:
cpu: "1"
memory: 1Gi
limits:
cpu: "1"
memory: 1Gi
volumeMounts:
- name: checkpoints
mountPath: /checkpoints
volumes:
- name: checkpoints
persistentVolumeClaim:
claimName: batch-checkpoints
Sostituisci il ciclo di esempio con la tua applicazione batch e seleziona una soluzione di archiviazione che soddisfi i requisiti di throughput e ripristino. Usare l'identità del carico di lavoro anziché le credenziali integrate quando l'applicazione salva direttamente i checkpoint in Archiviazione BLOB di Azure o in un altro servizio Azure.
Applicare questi controlli di affidabilità deliberatamente:
-
Punti di controllo e idempotenza: salvare i progressi a intervalli che soddisfino l'obiettivo di punto di ripristino (RPO). Archiviare i checkpoint e l'output di cui è stato eseguito il commit nell'archiviazione permanente, non nel file system del contenitore,
emptyDiro nell'archiviazione locale del nodo. Usare scritture atomiche, chiavi di idempotenza, scrittura transazionale o deduplicazione perché lo stesso programma Job può talvolta avviarsi più di una volta. -
Comportamento di riavvio: un processo consente
restartPolicy: NeveroOnFailure. ConNever, un contenitore in errore genera un pod in errore e il controller Job crea un pod sostitutivo. ConOnFailure, il kubelet può riavviare il container nello stesso pod. UsareNeverquando tenere separati i pod non riusciti e i log rende più semplice la diagnosi e rende sicura la ripresa di entrambe le opzioni. -
Limiti di ripetizione dei tentativi: impostare
backoffLimitin base al numero di errori temporanei che il carico di lavoro può tollerare. UsarepodFailurePolicyper terminare immediatamente con errore in caso di codici di uscita noti non soggetti a ritentativo o, come nell'esempio, per impedire che le interruzioni volontarie consumino il budget dei tentativi. Un'interruzione può comunque bloccare il pod; la policy modifica solo il modo in cui il Job conteggia quell'errore. -
Scadenze: impostare
activeDeadlineSecondsquando il processo deve essere arrestato dopo un runtime totale massimo. Il termine comprende anche i tentativi e ha la precedenza subackoffLimit. Non impostare una scadenza più breve del runtime previsto, oltre al tempo di ripetizione e ripristino. Un processo non riuscito non viene riavviato automaticamente come nuovo processo. -
Terminazione normale: gestire
SIGTERMnell'applicazione e impostareterminationGracePeriodSecondsun tempo sufficiente per interrompere l'accettazione di nuovi lavori, terminare o abbandonare l'unità corrente in modo sicuro, scaricare l'output e salvare un checkpoint. Kubernetes inviaSIGKILLse il processo supera il periodo di tolleranza, quindi i checkpoint periodici rimangono necessari. -
Pulizia: imposta
ttlSecondsAfterFinishedo configura i limiti della cronologia dei CronJob per evitare che i Job e i pod completati si accumulino. Conservare i record dei processi per un periodo sufficientemente lungo da consentire la raccolta dei log e l'indagine sugli incidenti.
Pianificare le eliminazioni e la manutenzione dei nodi
Non trattare il blocco di rimozione come strategia di ripristino principale per un processo a esecuzione prolungata. Per un processo batch riavviabile, in genere non creare un PodDisruptionBudget (PDB); il controller del job crea un pod sostitutivo dopo un'interruzione volontaria. Un PDB protegge solo dalle espulsioni volontarie e non protegge dal guasto del nodo, dall'espulsione dovuta alla pressione sulle risorse o dalla preemption. Un PDB che non consente alcuna interruzione può anche bloccare il drain dei nodi e ritardare gli aggiornamenti di AKS.
Usare un PDB solo quando un carico di lavoro batch parallelo deve mantenere un numero minimo di processi di lavoro in esecuzione contemporaneamente e ne è stato testato il comportamento durante il drenaggio. Allo stesso modo, usare cluster-autoscaler.kubernetes.io/safe-to-evict: "false" solo per operazioni eccezionali che non possono essere riavviate. L'annotazione può impedire la riduzione delle prestazioni e aumentare i costi, ma non protegge da errori del nodo o da ogni evento di manutenzione.
AKS isola ed esegue il drain dei nodi vecchi prima di sostituirli durante gli aggiornamenti. Configura le finestre di manutenzione pianificata in modo che la manutenzione supportata di AKS coincida con periodi di minore impatto, ma assicurati che il carico di lavoro sia riavviabile perché la pianificazione della manutenzione non elimina le interruzioni non pianificate. Per AKS Standard, eseguire processi batch in un pool di nodi utente dedicato quando richiedono dimensioni di VM separate, limiti di scalabilità, vincoli (taint) o finestre di aggiornamento distinte. Evitare i pool di nodi Spot per carichi di lavoro che non possono riprendersi dalla preemption. Prima della manutenzione dei nodi, verificare che i checkpoint recenti siano utilizzabili e che un altro pool di nodi idoneo abbia quote e capacità sufficienti per eseguire i pod sostitutivi.
Monitora l'avanzamento e il ripristino dei processi
Usa insieme lo stato, gli eventi e i log di Kubernetes quando esamini un job di lunga durata:
kubectl get job checkpointed-batch --watch
kubectl describe job checkpointed-batch
kubectl get pods -l batch.kubernetes.io/job-name=checkpointed-batch
kubectl logs job/checkpointed-batch
Abilitare il servizio gestito di Monitoraggio di Azure per Prometheus e Container Insights per conservare i log e correlare lo stato del processo con i riavvii dei pod, le espulsioni, il tempo di attesa, l'integrità dei nodi e l'utilizzo delle risorse. Instrumentare l'applicazione con segnali di avanzamento aziendale, ad esempio elementi completati, elementi non riusciti, ora dell'ultimo checkpoint riuscito, frequenza di elaborazione, numero di tentativi e tempo di completamento stimato. Avviso per un processo non riuscito, un processo che supera la durata prevista, nessun checkpoint all'interno dell'obiettivo del punto di ripristino, sostituzioni ripetute dei pod, pod in sospeso e velocità effettiva di elaborazione bloccata.
Sicurezza e conformità
Considerazioni chiave: implementare analisi CVE, audit trail e controlli di conformità per proteggere i dati e soddisfare i requisiti normativi, ad esempio SOC 2, HIPAA e GDPR.
La sicurezza e la conformità sono fondamentali per proteggere i dati e garantire che la pipeline di intelligenza artificiale soddisfi i requisiti normativi. Implementando le procedure consigliate per la sicurezza e la conformità, è possibile:
- Integrare l'analisi delle vulnerabilità comuni e delle esposizioni (CVE) per rilevare le vulnerabilità comuni nelle immagini dei contenitori di modelli open source.
- Usa Microsoft Defender for Containers per le immagini del contenitore del modello archiviate in Registro Azure Container.
- Mantenere un audit trail dei dati inseriti, delle modifiche del modello e delle metriche per rimanere conformi ai criteri dell'organizzazione.
- Supportare framework di conformità come SOC 2 (tramite la registrazione di controllo e i controlli di accesso di Azure), HIPAA (tramite crittografia dei dati inattivi e in transito, isolamento della rete) e GDPR (tramite opzioni di residenza dei dati e criteri di gestione degli accessi).
In AKS Automatic, le impostazioni predefinite di sicurezza preconfigurate migliorano il livello di protezione di base, ma i controlli di sicurezza a livello di modello, di dati e di pipeline restano comunque necessari.
Pianificare i carichi di lavoro GPU
Punto chiave: esporre le GPU tramite il plugin per dispositivi NVIDIA, richiedere esplicitamente le GPU e isolare i costosi nodi GPU con etichette, taint e tolleranze.
Kubernetes pianifica le GPU come risorse estese. Dopo che il plug-in del dispositivo di NVIDIA registra le GPU su un nodo, un pod richiede una GPU impostando nvidia.com/gpu sia in resources.requests che in resources.limits. Il pod seguente richiede una GPU e ha come destinazione un pool di nodi con etichetta accelerator=nvidia:
apiVersion: v1
kind: Pod
metadata:
name: gpu-training-pod
labels:
app: gpu-training
spec:
restartPolicy: Never
nodeSelector:
accelerator: nvidia
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: trainer
image: nvcr.io/nvidia/cuda:12.4.1-runtime-ubuntu22.04
command:
- /bin/bash
- -c
- |
set -e
nvidia-smi
echo "GPU is available to the training container."
resources:
requests:
cpu: "1"
memory: 2Gi
nvidia.com/gpu: 1
limits:
cpu: "1"
memory: 2Gi
nvidia.com/gpu: 1
Le risorse estese non vengono sovracommesse. Kubernetes considera un limite di GPU come richiesta GPU quando viene specificato solo il limite, ma l'impostazione di entrambi i campi rende esplicita la finalità del carico di lavoro e consente la convalida dei criteri.
Effettuare il provisioning di un pool di nodi GPU di AKS
Per AKS Standard, creare un pool di nodi utente dedicato con dimensioni di VM NVIDIA GPU supportate. L'esempio seguente di interfaccia della riga di comando di Azure crea un pool di nodi con scalabilità automatica Standard_NC4as_T4_v3, applica l'etichetta utilizzata dal pod precedente e applica un taint ai nodi per respingere i carichi di lavoro che non tollerano esplicitamente i nodi GPU:
RESOURCE_GROUP=myResourceGroup
AKS_CLUSTER=myAKSCluster
az aks nodepool add \
--resource-group "$RESOURCE_GROUP" \
--cluster-name "$AKS_CLUSTER" \
--name gpunp \
--mode User \
--node-vm-size Standard_NC4as_T4_v3 \
--node-count 0 \
--enable-cluster-autoscaler \
--min-count 0 \
--max-count 4 \
--labels accelerator=nvidia workload=training \
--node-taints sku=gpu:NoSchedule
Prima di creare il pool di nodi, verificare che lo SKU della macchina virtuale sia disponibile nell'area del cluster e che la sottoscrizione disponga di una quota sufficiente a livello di area e famiglia di macchine virtuali. Selezionare una dimensione della serie NC in base alla memoria GPU, al numero di GPU, al rapporto CPU-GPU, all'archiviazione locale, alla rete e alle funzionalità CUDA richieste dal framework di training. Ad esempio, le dimensioni NCas T4 v3 sono adatte per molti carichi di lavoro di training a gpu singola e di dimensioni inferiori, mentre le dimensioni NC A100 v4 supportano modelli più grandi e configurazioni GPU a istanze multipla.
AKS Automatic può eseguire il provisioning di capacità GPU idonea in risposta ai pod in sospeso. Il carico di lavoro deve comunque richiedere nvidia.com/gpue tutti i selettori di nodo, le affinità, le tolerazioni, i vincoli di topologia, le quote di sottoscrizione e la disponibilità dello SKU a livello di area devono essere soddisfacenti. Usa AKS Standard se hai bisogno di uno SKU VM fisso, un ciclo di vita del pool di nodi personalizzato o un controllo dettagliato del ridimensionamento e della topologia del pool GPU.
Verificare o installare il plug-in del dispositivo NVIDIA
Le configurazioni GPU di AKS possono fornire driver GPU gestiti e l'integrazione con il plug-in per i dispositivi. Verificare la configurazione effettiva prima di installare un altro plug-in:
kubectl get nodes -L accelerator,kubernetes.azure.com/agentpool
kubectl get daemonsets --all-namespaces | grep -i nvidia
kubectl describe node | grep -A5 -E "Capacity:|Allocatable:|nvidia.com/gpu"
Non eseguire più DaemonSet di plug-in del dispositivo NVIDIA negli stessi nodi. Se la configurazione di AKS non gestisce il plugin, il seguente DaemonSet autonomo registra le GPU NVIDIA con il kubelet. Installare una versione del plug-in del dispositivo supportata dalle versioni di NVIDIA Driver e Kubernetes:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nvidia-device-plugin
namespace: kube-system
labels:
app.kubernetes.io/name: nvidia-device-plugin
spec:
selector:
matchLabels:
app.kubernetes.io/name: nvidia-device-plugin
updateStrategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/name: nvidia-device-plugin
spec:
priorityClassName: system-node-critical
nodeSelector:
accelerator: nvidia
tolerations:
- operator: Exists
containers:
- name: nvidia-device-plugin
image: nvcr.io/nvidia/k8s-device-plugin:v0.17.1
args:
- --fail-on-init-error=false
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
volumeMounts:
- name: device-plugin
mountPath: /var/lib/kubelet/device-plugins
volumes:
- name: device-plugin
hostPath:
path: /var/lib/kubelet/device-plugins
type: Directory
Verificare che nvidia.com/gpu venga visualizzato sotto le risorse allocabili di ogni nodo GPU prima di inviare i processi di training.
Suddividere in partizioni le GPU A100 e H100 con MIG
NVIDIA Multi-Instance GPU (MIG) può partizionare una GPU A100 o H100 supportata in istanze GPU isolate. MIG è utile per l'ottimizzazione degli iperparametri e per i processi di ottimizzazione più piccoli che non richiedono un'intera GPU fisica. Usare GPU complete per i carichi di lavoro che richiedono tutta la memoria GPU, la larghezza di banda massima di interconnessione o un profilo non supportato dalla GPU installata.
Usare l'operatore GPU NVIDIA e MIG Manager quando è necessaria la gestione dichiarativa del ciclo di vita MIG. L'operatore deve possedere il plug-in del dispositivo e la configurazione MIG per i nodi interessati; non combinarlo con un secondo plug-in di dispositivo autonomo. I nomi e il numero di profili esatti dipendono dal modello GPU e dalla capacità di memoria. La configurazione seguente crea sette 1g.10gb istanze nelle configurazioni di 80 GB A100 o H100 supportate:
apiVersion: v1
kind: Namespace
metadata:
name: gpu-operator
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mig-parted-config
namespace: gpu-operator
data:
config.yaml: |
version: v1
mig-configs:
all-disabled:
- devices: all
mig-enabled: false
hptuning-1g10gb:
- devices: all
mig-enabled: true
mig-devices:
"1g.10gb": 7
---
apiVersion: v1
kind: Namespace
metadata:
name: ml-training
---
apiVersion: batch/v1
kind: Job
metadata:
name: mig-hyperparameter-trial
namespace: ml-training
labels:
workload: hyperparameter-tuning
spec:
backoffLimit: 2
template:
metadata:
labels:
workload: hyperparameter-tuning
spec:
restartPolicy: Never
nodeSelector:
accelerator: nvidia
nvidia.com/mig.config: hptuning-1g10gb
nvidia.com/mig.config.state: success
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: trial
image: nvcr.io/nvidia/cuda:12.4.1-runtime-ubuntu22.04
command:
- /bin/bash
- -c
- |
set -e
nvidia-smi
echo "Starting one hyperparameter trial on a MIG instance."
sleep 30
resources:
requests:
cpu: "2"
memory: 8Gi
nvidia.com/mig-1g.10gb: 1
limits:
cpu: "2"
memory: 8Gi
nvidia.com/mig-1g.10gb: 1
Configurare il gestore MIG dell'operatore GPU per utilizzare la ConfigMap mig-parted-config, usare la strategia MIG mixed quando i carichi di lavoro richiedono profili MIG con nome e quindi etichettare i nodi di destinazione:
kubectl label nodes \
-l accelerator=nvidia \
nvidia.com/mig.config=hptuning-1g10gb \
--overwrite
La modifica di un layout MIG interrompe i carichi di lavoro già usando la GPU. Isolare e svuotare il nodo di destinazione, applicare la configurazione durante una finestra di manutenzione e verificare che il profilo richiesto sia presente nelle risorse allocabili del nodo prima di inviare i processi.
Isolare i carichi di lavoro delle GPU con taints e tolerations
Un NoSchedule taint mantiene i pod dell'applicazione ordinari lontano dai costosi nodi GPU. L'esempio di creazione del pool di nodi applica sku=gpu:NoSchedule. Il processo completo seguente include la tollerazione corrispondente e un selettore di nodo:
apiVersion: batch/v1
kind: Job
metadata:
name: isolated-gpu-training
spec:
backoffLimit: 3
template:
metadata:
labels:
app: isolated-gpu-training
spec:
restartPolicy: Never
nodeSelector:
accelerator: nvidia
workload: training
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: trainer
image: nvcr.io/nvidia/cuda:12.4.1-runtime-ubuntu22.04
command:
- /bin/bash
- -c
- |
set -e
nvidia-smi
sleep 60
resources:
requests:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
Una tollerazione consente la pianificazione, ma non impone che il pod venga eseguito su un nodo GPU. Associare le tolleranze a una richiesta di risorse GPU e a un selettore di nodo o all'affinità del nodo. Assicurarsi che i DaemonSet di piattaforma necessari, ad esempio quelli di rete, monitoraggio, archiviazione e il device plugin, tollerino il taint GPU.
Eseguire carichi di lavoro di training distribuiti
Aspetti chiave: usare un operatore di addestramento per gestire le identità dei worker e il ciclo di vita dei job, convalidare la comunicazione di rete tra nodi multipli e usare l'ammissione di gruppo quando tutti i worker devono avviarsi insieme.
Il training distribuito usa più processi per dividere i dati, lo stato del modello o le fasi della pipeline. Su Kubernetes, un operatore può creare pod worker, iniettare la configurazione di rendezvous, monitorare lo stato delle repliche, riavviare i pod worker non riusciti e ripulire il job. Installa e gestisci le versioni degli operatori di training tramite l'IaC della tua piattaforma e il relativo processo di rilascio, invece di consentire ai singoli team di installare CRD a livello di cluster senza governance.
Creare un'immagine CUDA di addestramento portatile
Il Dockerfile seguente espande il modello Dockerfile identificato nella sezione Containerization . L'immagine contiene il runtime CUDA e le librerie PyTorch, mentre il driver NVIDIA compatibile rimane sul nodo GPU di AKS:
FROM pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime
WORKDIR /workspace
COPY requirements.txt .
RUN python -m pip install --no-cache-dir -r requirements.txt
COPY train.py .
ENTRYPOINT ["python", "/workspace/train.py"]
Aggiungere l'immagine di base da un digest non modificabile nell'ambiente di produzione. Mantenere i set di dati e modificare frequentemente i checkpoint all'esterno dell'immagine e analizzare l'immagine risultante prima di eseguirne il push in Registro Azure Container.
Eseguire un PyTorchJob
L'operatore di addestramento Kubeflow fornisce il PyTorchJob CRD. Installare una versione di Training Operator compatibile con la versione di Kubernetes prima di applicare questo manifesto. L'esempio seguente con due repliche esegue un'operazione di all-reduce NCCL tra un nodo master e un nodo worker:
apiVersion: v1
kind: Namespace
metadata:
name: ml-training
labels:
purpose: ml-training
---
apiVersion: kubeflow.org/v1
kind: PyTorchJob
metadata:
name: pytorch-nccl-example
namespace: ml-training
spec:
runPolicy:
cleanPodPolicy: None
pytorchReplicaSpecs:
Master:
replicas: 1
restartPolicy: OnFailure
template:
metadata:
labels:
training-job: pytorch-nccl-example
spec:
nodeSelector:
accelerator: nvidia
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: pytorch
image: pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime
command:
- python
- -c
- |
import os
import torch
import torch.distributed as dist
torch.cuda.set_device(0)
dist.init_process_group(backend="nccl")
value = torch.tensor(
[float(dist.get_rank() + 1)],
device="cuda"
)
dist.all_reduce(value)
print(
f"rank={dist.get_rank()} "
f"world_size={dist.get_world_size()} "
f"all_reduce_sum={value.item()}"
)
dist.destroy_process_group()
env:
- name: NCCL_DEBUG
value: INFO
- name: NCCL_SOCKET_IFNAME
value: eth0
- name: NCCL_IB_DISABLE
value: "1"
- name: TORCH_NCCL_ASYNC_ERROR_HANDLING
value: "1"
resources:
requests:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
Worker:
replicas: 1
restartPolicy: OnFailure
template:
metadata:
labels:
training-job: pytorch-nccl-example
spec:
nodeSelector:
accelerator: nvidia
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: pytorch
image: pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime
command:
- python
- -c
- |
import os
import torch
import torch.distributed as dist
torch.cuda.set_device(0)
dist.init_process_group(backend="nccl")
value = torch.tensor(
[float(dist.get_rank() + 1)],
device="cuda"
)
dist.all_reduce(value)
print(
f"rank={dist.get_rank()} "
f"world_size={dist.get_world_size()} "
f"all_reduce_sum={value.item()}"
)
dist.destroy_process_group()
env:
- name: NCCL_DEBUG
value: INFO
- name: NCCL_SOCKET_IFNAME
value: eth0
- name: NCCL_IB_DISABLE
value: "1"
- name: TORCH_NCCL_ASYNC_ERROR_HANDLING
value: "1"
resources:
requests:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
Per l'addestramento in produzione, sostituisci il test incorporato con l'immagine e lo script di addestramento versionati. Allineare i conteggi delle repliche al numero di GPU e processi richiesti dal framework di training.
Eseguire un TFJob
L'operatore di training fornisce anche il TFJob CRD. L'esempio seguente esegue l'addestramento sincrono di TensorFlow su due worker GPU usando MultiWorkerMirroredStrategy:
apiVersion: v1
kind: Namespace
metadata:
name: ml-training
labels:
purpose: ml-training
---
apiVersion: kubeflow.org/v1
kind: TFJob
metadata:
name: tensorflow-multiworker-example
namespace: ml-training
spec:
runPolicy:
cleanPodPolicy: None
tfReplicaSpecs:
Worker:
replicas: 2
restartPolicy: OnFailure
template:
metadata:
labels:
training-job: tensorflow-multiworker-example
spec:
nodeSelector:
accelerator: nvidia
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: tensorflow
image: tensorflow/tensorflow:2.16.1-gpu
command:
- python
- -c
- |
import tensorflow as tf
strategy = tf.distribute.MultiWorkerMirroredStrategy()
print("workers:", strategy.num_replicas_in_sync)
with strategy.scope():
model = tf.keras.Sequential([
tf.keras.layers.Input(shape=(32,)),
tf.keras.layers.Dense(64, activation="relu"),
tf.keras.layers.Dense(1)
])
model.compile(
optimizer="adam",
loss="mean_squared_error"
)
features = tf.random.normal([4096, 32])
labels = tf.random.normal([4096, 1])
dataset = (
tf.data.Dataset.from_tensor_slices((features, labels))
.shuffle(4096)
.repeat()
.batch(64)
)
model.fit(dataset, epochs=2, steps_per_epoch=32)
resources:
requests:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
Per l'addestramento con server dei parametri, definire i tipi di replica Chief, Worker e PS in base alla strategia di distribuzione di TensorFlow. Misurate i colli di bottiglia della rete e del server dei parametri che ne derivano prima di aumentare il numero di repliche.
Ottimizzare un modello con KAITO
KAITO fornisce un'astrazione del workspace incentrata su AKS per la distribuzione di modelli e il fine-tuning. Abilitare il componente aggiuntivo KAITO o installare una versione KAITO compatibile prima di applicare un Workspace. Verificare che il set di impostazioni selezionato, lo SKU della macchina virtuale e il metodo di ottimizzazione siano supportati dalla versione di KAITO installata.
L'area di lavoro seguente richiede una macchina virtuale GPU A100 e avvia l'ottimizzazione QLoRA per un set di impostazioni Phi-3 supportato usando un set di dati accessibile pubblicamente:
apiVersion: kaito.sh/v1alpha1
kind: Workspace
metadata:
name: workspace-tuning-phi-3-mini
resource:
instanceType: Standard_NC24ads_A100_v4
labelSelector:
matchLabels:
apps: phi-3-mini-tuning
tuning:
preset:
name: phi-3-mini-4k-instruct
method: qlora
input:
urls:
- https://huggingface.co/datasets/yahma/alpaca-cleaned/resolve/main/alpaca_data_cleaned.json
KAITO può coordinare la configurazione predefinita del modello e l'infrastruttura GPU necessaria per l'area di lavoro. Per l’uso in produzione, archiviare il set di dati di addestramento in un account di archiviazione di Azure approvato, usare l’accesso privato e l’identità del carico di lavoro ove supportati e salvare in modo permanente il modello risultante in un registro dei modelli soggetto a governance o in Registro Azure Container. Considera il manifest del workspace, la versione del set di dati di input, la versione del preset, la configurazione dell'adattatore e il digest dell'immagine di output come un unico record di addestramento versionato.
Configurare la comunicazione NCCL con CNI di AKS
NVIDIA Collective Communications Library (NCCL) gestisce operazioni collettive come all-reduce. Per una baseline TCP trasferibile su AKS CNI, usare l'interfaccia di rete del pod, normalmente eth0, e iniziare con NCCL_IB_DISABLE=1. Per le dimensioni di VM supportate abilitate per RDMA, utilizzare la configurazione RDMA di NVIDIA e Azure documentata e convalidarla prima di impostare NCCL_IB_DISABLE=0.
Usare queste variabili di ambiente di base:
-
NCCL_SOCKET_IFNAME=eth0seleziona l'interfaccia di rete del pod. -
NCCL_DEBUG=INFOfornisce informazioni di diagnostica durante la convalida. Ridurre il livello di log dopo l'ottimizzazione. -
NCCL_IB_DISABLE=1seleziona i socket TCP quando RDMA non è configurato. -
TORCH_NCCL_ASYNC_ERROR_HANDLING=1aiuta PyTorch a terminare invece di bloccarsi a tempo indefinito dopo errori di comunicazione asincroni.
Se il criterio di rete è abilitato, consenti tutto il traffico necessario di rendezvous e NCCL tra le repliche. NCCL può negoziare porte dinamiche, quindi un criterio restrittivo sulle porte fisse può causare il blocco dei processi di addestramento. I criteri seguenti consentono la comunicazione da pod a pod senza restrizioni solo tra le repliche del processo PyTorch e consente la risoluzione DNS:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-pytorch-nccl
namespace: ml-training
spec:
podSelector:
matchLabels:
training-job: pytorch-nccl-example
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
training-job: pytorch-nccl-example
egress:
- to:
- podSelector:
matchLabels:
training-job: pytorch-nccl-example
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Esegui il benchmark di NCCL separatamente dall'addestramento del modello prima di passare alla scalabilità orizzontale. Confronta la larghezza di banda dell'all-reduce, la latenza, l'utilizzo della GPU e il throughput di addestramento per ciascun numero di worker. Un numero maggiore di worker può ridurre le prestazioni quando la comunicazione o il caricamento dei dati diventano il collo di bottiglia.
Usare la pianificazione dei gang e le code dei carichi di lavoro
Considerazioni chiave: ammettere i ruoli di lavoro distribuiti come gruppo e applicare quote GPU tenant in modo che i processi parzialmente pianificati non riservano GPU durante l'attesa dei ruoli di lavoro rimanenti.
L'utilità di pianificazione Kubernetes predefinita inserisce i pod singolarmente. Per un processo distribuito che non può fare progressi fino a quando ogni lavoratore non è in esecuzione, il posizionamento parziale può sprecare capacità GPU. Kueue fornisce il controllo di ammissione e la gestione delle quote prima dell'avvio dei pod. Volcano fornisce uno scheduler e un modello di pianificazione all-or-nothing basato su PodGroup.
AKS Automatic fornisce l'utilità di pianificazione predefinita di Kubernetes e il provisioning automatico dei nodi come punto di partenza. Inviare processi di formazione ordinari o processi di training gestiti dall'operatore con richieste di risorse accurate e consentire alla piattaforma di effettuare il provisioning della capacità idonea. Questo comportamento non garantisce l'ammissione atomica per ogni lavoratore. Installare Kueue o Volcano quando un carico di lavoro richiede pianificazione di gruppo, gestione delle code, quote per team, condivisione equa delle risorse o comportamento di preemption personalizzato.
Assegna una quota GPU multi-tenant con Kueue
Installare una versione kueue compatibile con la versione di Kubernetes e abilitare le integrazioni per i tipi di carico di lavoro usati. Il manifesto seguente crea:
- GPU
ResourceFlavorassociata ai nodi con etichettaaccelerator=nvidia. - Quattro GPU
ClusterQueueper il team A. - Una configurazione a due GPU
ClusterQueueper il team B. - Uno
LocalQueuecon ambito del namespace per ogni team. - Un processo a due ruoli di lavoro che Kueue ammette solo quando sono disponibili le risorse richieste.
apiVersion: v1
kind: Namespace
metadata:
name: team-a
---
apiVersion: v1
kind: Namespace
metadata:
name: team-b
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ResourceFlavor
metadata:
name: nvidia-gpu
spec:
nodeLabels:
accelerator: nvidia
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: team-a-gpu
spec:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: team-a
queueingStrategy: BestEffortFIFO
resourceGroups:
- flavors:
- name: nvidia-gpu
resources:
- name: cpu
nominalQuota: "64"
- name: memory
nominalQuota: 256Gi
- name: nvidia.com/gpu
nominalQuota: "4"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: ClusterQueue
metadata:
name: team-b-gpu
spec:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: team-b
queueingStrategy: BestEffortFIFO
resourceGroups:
- flavors:
- name: nvidia-gpu
resources:
- name: cpu
nominalQuota: "32"
- name: memory
nominalQuota: 128Gi
- name: nvidia.com/gpu
nominalQuota: "2"
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
name: gpu-queue
namespace: team-a
spec:
clusterQueue: team-a-gpu
---
apiVersion: kueue.x-k8s.io/v1beta1
kind: LocalQueue
metadata:
name: gpu-queue
namespace: team-b
spec:
clusterQueue: team-b-gpu
---
apiVersion: batch/v1
kind: Job
metadata:
name: team-a-two-gpu-training
namespace: team-a
labels:
kueue.x-k8s.io/queue-name: gpu-queue
spec:
suspend: true
completions: 2
parallelism: 2
backoffLimit: 2
template:
metadata:
labels:
app: team-a-two-gpu-training
spec:
restartPolicy: Never
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: worker
image: nvcr.io/nvidia/cuda:12.4.1-runtime-ubuntu22.04
command:
- /bin/bash
- -c
- |
set -e
nvidia-smi
echo "Kueue admitted this worker."
sleep 120
resources:
requests:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
Una ClusterQueue quota è una quota di pianificazione, non una quota di sottoscrizione Azure. Assicurarsi che il cluster AKS sia in grado di eseguire il provisioning della capacità delle macchine virtuali sottostanti e che la quota GPU di Azure sia sufficiente per il carico di lavoro complessivo ammesso. Utilizzare le coorti e le funzionalità di condivisione equa delle risorse di Kueue quando i team possono prendere in prestito reciprocamente la quota inutilizzata.
Usare il vulcano come alternativa
Volcano è un'alternativa quando si vuole un'utilità di pianificazione batch dedicata con pianificazione, code e criteri relativi al ciclo di vita dei processi. Installare una versione di Volcano compatibile con il cluster prima di applicare i relativi CRD. Il seguente job Volcano richiede che entrambi i worker GPU siano disponibili prima che il job venga eseguito:
apiVersion: batch.volcano.sh/v1alpha1
kind: Job
metadata:
name: volcano-gpu-training
namespace: default
spec:
minAvailable: 2
schedulerName: volcano
policies:
- event: PodEvicted
action: RestartJob
- event: PodFailed
action: RestartJob
tasks:
- replicas: 2
name: worker
template:
metadata:
labels:
app: volcano-gpu-training
spec:
restartPolicy: OnFailure
nodeSelector:
accelerator: nvidia
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: worker
image: nvcr.io/nvidia/cuda:12.4.1-runtime-ubuntu22.04
command:
- /bin/bash
- -c
- |
set -e
nvidia-smi
echo "All Volcano workers were admitted."
sleep 120
resources:
requests:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
limits:
cpu: "4"
memory: 16Gi
nvidia.com/gpu: 1
Adottate un unico sistema primario di accodamento e di scheduling di gruppo, a meno che non disponiate di un design di interoperabilità collaudato. Più controller di ammissione o scheduler possono altrimenti rendere difficili da comprendere il comportamento dello stato di attesa e della preemption.
Configurare le priorità di training e inferenza
L'inferenza sensibile alla latenza richiede in genere una priorità più alta rispetto all'addestramento in batch interrompibile. Le seguenti risorse PriorityClass consentono ai pod di inferenza di estromettere i pod con priorità inferiore, impedendo al contempo ai pod di training batch di estromettere altri carichi di lavoro:
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: training-batch
value: 10000
globalDefault: false
preemptionPolicy: Never
description: Batch training can wait and can be preempted by higher-priority workloads.
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: inference-critical
value: 100000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: Latency-sensitive production inference can preempt lower-priority workloads.
Assegnare la classe tramite spec.priorityClassName nel modello di pod. La priorità dei pod Kubernetes e la priorità del carico di lavoro Kueue influiscono su fasi diverse: Kueue controlla l'ammissione della coda, mentre la priorità di Kubernetes influenza la pianificazione e la precedenza dei pod dopo l'ammissione. Coordinare entrambi i criteri in modo da esprimere la stessa priorità aziendale.
La precedenza termina i pod con priorità inferiore. I carichi di lavoro di training che possono essere interrotti devono salvare punti di controllo nell'archiviazione persistente, tollerare duplicazioni del lavoro e riprendersi senza fare affidamento sui file locali del nodo.
Configurare la memoria condivisa e la gestione delle risorse
Considerazioni chiave: sostituire il piccolo valore predefinito /dev/shmdel runtime del contenitore, impostare le richieste di risorse dall'utilizzo osservato e configurare il ridimensionamento dei nodi in base ai requisiti completi del carico di lavoro GPU.
Aumento /dev/shm per i caricatori di dati di Machine Learning
I caricatori di dati PyTorch, le pipeline di input TensorFlow, NCCL e Python multiprocessore possono usare la memoria condivisa POSIX. La configurazione predefinita del container per /dev/shm è spesso troppo piccola per l'addestramento multiprocesso, il che può causare arresti anomali dei processi worker, errori di bus o apparenti blocchi dell'addestramento.
Montare una memoria supportata emptyDir in /dev/shm e impostare un oggetto esplicito sizeLimit:
apiVersion: batch/v1
kind: Job
metadata:
name: shared-memory-training
spec:
backoffLimit: 2
template:
metadata:
labels:
app: shared-memory-training
spec:
restartPolicy: Never
nodeSelector:
accelerator: nvidia
tolerations:
- key: sku
operator: Equal
value: gpu
effect: NoSchedule
containers:
- name: trainer
image: pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime
command:
- /bin/bash
- -c
- |
set -e
df -h /dev/shm
python -c '
import multiprocessing as mp
import torch
def worker(index):
value = torch.ones(1024, 1024)
print(f"worker={index}, sum={value.sum().item()}")
if __name__ == "__main__":
processes = [mp.Process(target=worker, args=(i,)) for i in range(4)]
for process in processes:
process.start()
for process in processes:
process.join()
if process.exitcode != 0:
raise SystemExit(process.exitcode)
'
volumeMounts:
- name: shared-memory
mountPath: /dev/shm
resources:
requests:
cpu: "8"
memory: 16Gi
nvidia.com/gpu: 1
limits:
cpu: "8"
memory: 16Gi
nvidia.com/gpu: 1
volumes:
- name: shared-memory
emptyDir:
medium: Memory
sizeLimit: 8Gi
L'utilizzo basato sulla memoria emptyDir contribuisce al consumo di memoria del pod. Includere l'utilizzo massimo previsto della memoria condivisa quando si imposta il limite di memoria del contenitore. Se /dev/shm cresce oltre il budget di memoria effettivo, il pod può essere espulso o terminato per il superamento del limite di memoria.
Dimensiona CPU e memoria in base all'utilizzo osservato
Inizia con un benchmark basato su un modello rappresentativo, sulla dimensione del batch, sulla lunghezza della sequenza, sulla concorrenza nel caricamento dei dati, sull'aumento dei dati e sulla gestione dei checkpoint. Usare quindi i dati di monitoraggio per modificare:
- Impostare le richieste cpu sufficientemente elevate per mantenere fornite le pipeline di input GPU. Periodi prolungati di inattività della GPU possono indicare una carenza di risorse della CPU o dello storage.
- Impostare le richieste di memoria vicino all'utilizzo stabile del working set più un margine di sicurezza. Includi
/dev/shm, il comportamento della cache di pagina, il sovraccarico dell'allocatore del framework e i picchi di serializzazione dei checkpoint. - Impostare i limiti di memoria al di sopra del picco osservato. Analizzare
OOMKilledgli eventi anziché aumentare ripetutamente i limiti senza trovare la causa. - Valutare il throttling della CPU prima di utilizzare limiti restrittivi. I limiti della CPU troppo bassi possono ridurre l'utilizzo della GPU anche quando l'utilizzo medio della CPU risulta accettabile.
- Impostare richieste e limiti uguali per i processi di training prevedibili e di alto valore quando la qualità garantita del servizio è più importante rispetto alla compressione dei nodi.
- Esegui il profiling di ogni modifica significativa alla dimensione del modello, alla precisione, alla dimensione del batch, al numero di worker e alla pipeline dei dati.
Usare i percentili sull'intera esecuzione del training anziché una media calcolata su un breve intervallo. Le fasi di avvio, convalida, checkpoint e shuffle dei dati spesso presentano picchi di risorse diversi.
Configurare la scalabilità automatica del cluster per un pool di nodi GPU
Per AKS Standard, abilitare il ridimensionamento automatico del cluster nel pool di nodi utente GPU e definire la capacità minima e massima:
RESOURCE_GROUP=myResourceGroup
AKS_CLUSTER=myAKSCluster
GPU_NODE_POOL=gpunp
az aks nodepool update \
--resource-group "$RESOURCE_GROUP" \
--cluster-name "$AKS_CLUSTER" \
--name "$GPU_NODE_POOL" \
--enable-cluster-autoscaler \
--min-count 0 \
--max-count 8
È possibile ottimizzare le impostazioni del profilo di scalabilità automatica del cluster supportate nell'ambito del cluster. Modifiche del profilo di test sia per il training che per la gestione dei carichi di lavoro:
az aks update \
--resource-group "$RESOURCE_GROUP" \
--name "$AKS_CLUSTER" \
--cluster-autoscaler-profile \
scan-interval=20s \
scale-down-unneeded-time=10m \
scale-down-delay-after-add=15m \
max-graceful-termination-sec=120
Un pod GPU in sospeso attiva l'aumento delle prestazioni solo quando i requisiti di pianificazione completi corrispondono a un modello di pool di nodi. Controlla la richiesta di risorse GPU, la capacità della VM, le etichette, i taint, le tolleranze, l'affinità, i vincoli di topologia, la topologia del volume persistente, il numero massimo di nodi e la quota di Azure quando non si verifica lo scale-up.
La scalabilità fino a zero è indicata per i pool di addestramento interrompibili, ma aggiunge latenza al provisioning delle macchine virtuali, al recupero delle immagini, al montaggio del set di dati e all'inizializzazione del modello. Mantenere un valore minimo diverso da zero quando la latenza di avvio ha un effetto materiale sugli obiettivi del servizio. I budget di interruzione dei pod, i pod non rimossi, l'archiviazione locale e i periodi di tolleranza di terminazione lunghi possono ritardare la riduzione delle prestazioni.
AKS Automatic gestisce il provisioning e il ridimensionamento dei nodi come parte della configurazione di base del servizio. Concentrarsi sulle richieste accurate dei pod e sui vincoli supportati invece di configurare un'utilità di scalabilità automatica del pool di nodi GPU manuale.
Memorizza dataset e checkpoint
Punto chiave: seleziona l'archiviazione in base al modello di accesso, al throughput, alla condivisione e ai requisiti di ripristino, e salva i checkpoint in una posizione esterna al nodo in modo che l'addestramento possa riprendere dopo un'espulsione o una preemption.
Non includere dataset di grandi dimensioni, artefatti del modello e checkpoint nelle immagini container. Scegliere un'interfaccia di archiviazione in base al carico di lavoro:
- Usare Archiviazione BLOB di Azure per set di dati di oggetti di grandi dimensioni, artefatti del modello e repository di dati ad alta capacità.
- Usare File di Azure quando più nodi di lavoro richiedono un file system di tipo POSIX condiviso.
- Usare Azure Disco per carichi di lavoro a prestazioni elevate, checkpoint di lettura/scrittura a nodo singolo o cache in cui
ReadWriteOnceè sufficiente. - Usare l'archiviazione temporanea node-local solo per le cache ricostruibili e i file temporanei.
Accedere a set di dati di grandi dimensioni con il driver CSI BLOB Azure
Abilita il driver CSI di Azure Blob in AKS Standard, se non è già abilitato:
RESOURCE_GROUP=myResourceGroup
AKS_CLUSTER=myAKSCluster
az aks update \
--resource-group "$RESOURCE_GROUP" \
--name "$AKS_CLUSTER" \
--enable-blob-driver
L'esempio seguente crea dinamicamente un contenitore BLOB premium di Azure accessibile tramite NFS e lo monta in un pod di addestramento. Per un set di dati regolamentato esistente, usare un volume definito in modo statico o una configurazione BlobFuse con i controlli di rete privati e di identità appropriati anziché creare un contenitore dinamico vuoto:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ml-azureblob-nfs
provisioner: blob.csi.azure.com
parameters:
protocol: nfs
skuName: Premium_LRS
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
mountOptions:
- -o attr_timeout=120
- -o entry_timeout=120
- -o negative_timeout=120
- -o actimeo=120
- -o noresvport
- -o nconnect=4
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: blob-training-dataset
namespace: default
spec:
accessModes:
- ReadWriteMany
storageClassName: ml-azureblob-nfs
resources:
requests:
storage: 1Ti
---
apiVersion: batch/v1
kind: Job
metadata:
name: inspect-blob-dataset
namespace: default
spec:
backoffLimit: 2
template:
metadata:
labels:
app: inspect-blob-dataset
spec:
restartPolicy: Never
containers:
- name: dataset-reader
image: ubuntu:24.04
command:
- /bin/bash
- -c
- |
set -e
echo "Mounted dataset path:"
df -h /mnt/dataset
find /mnt/dataset -maxdepth 2 -type f | head -100
volumeMounts:
- name: dataset
mountPath: /mnt/dataset
volumes:
- name: dataset
persistentVolumeClaim:
claimName: blob-training-dataset
Eseguire il benchmark delle opzioni di protocollo e montaggio in base alle dimensioni delle partizioni rappresentative e ai modelli di accesso. Molti worker che leggono molti file di piccole dimensioni possono produrre risultati diversi rispetto alla lettura sequenziale in streaming di grandi shard. Valutare la preelaborazione dei set di dati in frammenti di dimensioni appropriate e l'uso dello spazio di cache locale del nodo quando, altrimenti, epoche ripetute scaricherebbero gli stessi oggetti.
Condividere i dati di training con File di Azure
File di Azure supporta ReadWriteMany, che consente ai worker distribuiti su nodi diversi di montare la stessa condivisione file. Il File di Azure Premium è appropriato quando il carico di lavoro richiede prestazioni prevedibili del file system e l'area selezionata supporta l'opzione di ridondanza necessaria.
Il manifesto seguente crea una condivisione File di Azure Premium e la monta in due pod di lavoro paralleli:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ml-azurefile-premium
provisioner: file.csi.azure.com
parameters:
skuName: Premium_LRS
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: Immediate
mountOptions:
- dir_mode=0770
- file_mode=0660
- uid=1000
- gid=1000
- mfsymlinks
- cache=strict
- actimeo=30
- nosharesock
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: shared-training-data
namespace: default
spec:
accessModes:
- ReadWriteMany
storageClassName: ml-azurefile-premium
resources:
requests:
storage: 100Gi
---
apiVersion: batch/v1
kind: Job
metadata:
name: shared-data-workers
namespace: default
spec:
completions: 2
parallelism: 2
completionMode: Indexed
backoffLimitPerIndex: 2
template:
metadata:
labels:
app: shared-data-workers
spec:
restartPolicy: Never
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
containers:
- name: worker
image: ubuntu:24.04
command:
- /bin/bash
- -c
- |
set -e
WORKER_INDEX="${JOB_COMPLETION_INDEX:-0}"
echo "worker=${WORKER_INDEX}" \
> "/mnt/shared/worker-${WORKER_INDEX}.txt"
ls -la /mnt/shared
volumeMounts:
- name: shared-data
mountPath: /mnt/shared
volumes:
- name: shared-data
persistentVolumeClaim:
claimName: shared-training-data
Evitare che ogni worker enumeri ripetutamente una directory contenente milioni di file. Usa un file manifest o un'assegnazione deterministica dei frammenti, in modo che ogni worker sappia quali oggetti leggere.
Punto di controllo nell'archiviazione persistente
Un checkpoint dovrebbe includere uno stato sufficiente per riprendere correttamente, ad esempio i pesi del modello, lo stato dell'ottimizzatore, lo stato dello scheduler, lo stato dello scaler, il numero di epoca o di passo, lo stato del generatore di numeri casuali e la posizione del caricatore dei dati quando supportato. Scrivere checkpoint periodicamente e prima della terminazione normale.
Il processo seguente scrive checkpoint PyTorch in modo atomico in File di Azure, ripristina il checkpoint più recente dopo il riavvio del contenitore o la sostituzione del pod e gestisce SIGTERM in modo che la preemption possa preservare i progressi più recenti:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ml-checkpoints-azurefile
provisioner: file.csi.azure.com
parameters:
skuName: Premium_LRS
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: Immediate
mountOptions:
- dir_mode=0770
- file_mode=0660
- uid=1000
- gid=1000
- mfsymlinks
- cache=strict
- actimeo=30
- nosharesock
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: model-checkpoints
namespace: default
spec:
accessModes:
- ReadWriteMany
storageClassName: ml-checkpoints-azurefile
resources:
requests:
storage: 100Gi
---
apiVersion: batch/v1
kind: Job
metadata:
name: checkpointed-pytorch-training
namespace: default
spec:
backoffLimit: 6
template:
metadata:
labels:
app: checkpointed-pytorch-training
spec:
restartPolicy: OnFailure
terminationGracePeriodSeconds: 120
securityContext:
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
containers:
- name: trainer
image: pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime
command:
- python
- -c
- |
import os
import signal
import sys
import time
import torch
checkpoint_path = "/checkpoints/latest.pt"
temporary_path = "/checkpoints/latest.pt.tmp"
state = {"epoch": 0, "value": torch.tensor([0.0])}
if os.path.exists(checkpoint_path):
state = torch.load(checkpoint_path, map_location="cpu")
print(f"Restored epoch {state['epoch']}", flush=True)
def save_checkpoint():
torch.save(state, temporary_path)
os.replace(temporary_path, checkpoint_path)
print(f"Saved epoch {state['epoch']}", flush=True)
def terminate(signum, frame):
print(f"Received signal {signum}", flush=True)
save_checkpoint()
sys.exit(143)
signal.signal(signal.SIGTERM, terminate)
signal.signal(signal.SIGINT, terminate)
for epoch in range(state["epoch"] + 1, 21):
state["epoch"] = epoch
state["value"] += 1
time.sleep(10)
if epoch % 2 == 0:
save_checkpoint()
save_checkpoint()
print("Training completed.", flush=True)
volumeMounts:
- name: checkpoints
mountPath: /checkpoints
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "1"
memory: 2Gi
volumes:
- name: checkpoints
persistentVolumeClaim:
claimName: model-checkpoints
Usare un Retain criterio di recupero o un account di archiviazione gestito in modo indipendente per i checkpoint di produzione, in modo che l'eliminazione di un PVC non elimini involontariamente l'unico punto di ripristino. Per l’addestramento distribuito data-parallel, in genere si fa scrivere il checkpoint globale al rank zero, oppure si utilizza un formato di checkpoint suddiviso supportato dal framework. Impedire a più rank di scrivere contemporaneamente nello stesso file.
Testare il ripristino eliminando deliberatamente un pod di lavoro durante un'esecuzione non di produzione. Verifica che il controller ricrei il carico di lavoro, che il nuovo pod monti lo stesso volume persistente e che l'addestramento riprenda dalla fase prevista.
Monitorare l'utilizzo della GPU e la velocità effettiva di training
Considerazioni chiave: monitorare il calcolo GPU, la memoria GPU, la velocità effettiva della pipeline di dati, la durata dei passaggi e l'attività di checkpoint insieme, in modo da distinguere la saturazione del calcolo dai colli di bottiglia della CPU, della rete o dell'archiviazione.
Abilitare il servizio gestito di Monitoraggio di Azure per Prometheus e Container Insights per correlare lo stato di Kubernetes, i log dei contenitori, l'integrità dei nodi e le metriche di Prometheus. Usa le procedure consigliate per il monitoraggio di AKS durante la progettazione di avvisi, conservazione dei dati e dashboard operative.
Raccolta delle metriche delle GPU NVIDIA
NVIDIA Data Center GPU Manager (DCGM) Exporter espone le metriche Prometheus delle GPU NVIDIA. Se l'operatore GPU NVIDIA distribuisce già DCGM Exporter, non distribuire un esportatore duplicato. Configurare Prometheus gestito di Monitoraggio di Azure per raccogliere metriche dall'exporter esistente.
Il seguente PodMonitor usa il CRD Prometheus gestito di Monitoraggio di Azure e ha come destinazione i pod di DCGM Exporter nel namespace gpu-operator. Modificare il selettore di etichette in modo che corrisponda alle etichette usate dall'utilità di esportazione installata:
apiVersion: azmonitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: nvidia-dcgm-exporter
namespace: gpu-operator
spec:
selector:
matchLabels:
app: nvidia-dcgm-exporter
podMetricsEndpoints:
- port: metrics
interval: 30s
scrapeTimeout: 10s
Verificare il nome del servizio di esportazione o della porta pod prima di applicare il monitoraggio. Le metriche DCGM comuni includono:
| Metrica | Purpose |
|---|---|
DCGM_FI_DEV_GPU_UTIL |
Percentuale di tempo in cui la GPU è attiva |
DCGM_FI_DEV_FB_USED |
Memoria frame buffer utilizzata |
DCGM_FI_DEV_FB_FREE |
Memoria frame buffer libera |
DCGM_FI_DEV_MEM_COPY_UTIL |
Utilizzo del motore di copia della memoria |
DCGM_FI_DEV_POWER_USAGE |
Consumo di energia GPU |
DCGM_FI_DEV_GPU_TEMP |
Temperatura GPU |
DCGM_FI_DEV_XID_ERRORS |
Eventi di errore NVIDIA XID |
La disponibilità delle metriche dipende dalle versioni della GPU, del driver, di DCGM e dell'exporter.
Esportare le metriche della velocità effettiva del training
Monitorare l'applicazione di addestramento con metriche a livello di carico di lavoro. Le metriche utili includono:
-
ml_training_samples_totalper esempi cumulativi o token elaborati. -
ml_training_steps_totalper i passi completati dell'ottimizzatore. -
ml_training_step_duration_secondsper latenza dei passaggi. -
ml_training_checkpoint_duration_secondsper la latenza del checkpoint. -
ml_training_data_wait_secondsper il tempo in attesa dei dati di input. - Perdita specifica del modello, tasso di apprendimento, norma del gradiente e metriche di validazione.
Nell'esempio eseguibile seguente vengono esposte metriche di training sintetiche sulla porta 8000. Sostituire la simulazione con le metriche generate dal ciclo di training reale:
apiVersion: v1
kind: Namespace
metadata:
name: ml-observability
---
apiVersion: v1
kind: ConfigMap
metadata:
name: training-metrics-server
namespace: ml-observability
data:
server.py: |
import http.server
import threading
import time
state = {
"samples": 0,
"steps": 0,
"last_step_duration": 0.0,
}
def train():
while True:
started = time.time()
time.sleep(1)
state["samples"] += 256
state["steps"] += 1
state["last_step_duration"] = time.time() - started
class MetricsHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path != "/metrics":
self.send_response(404)
self.end_headers()
return
body = (
"# HELP ml_training_samples_total Samples processed.\n"
"# TYPE ml_training_samples_total counter\n"
f"ml_training_samples_total{{job_name=\"metrics-demo\"}} "
f"{state['samples']}\n"
"# HELP ml_training_steps_total Training steps completed.\n"
"# TYPE ml_training_steps_total counter\n"
f"ml_training_steps_total{{job_name=\"metrics-demo\"}} "
f"{state['steps']}\n"
"# HELP ml_training_step_duration_seconds "
"Duration of the most recent training step.\n"
"# TYPE ml_training_step_duration_seconds gauge\n"
f"ml_training_step_duration_seconds"
f"{{job_name=\"metrics-demo\"}} "
f"{state['last_step_duration']}\n"
).encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "text/plain; version=0.0.4")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, format, *args):
return
threading.Thread(target=train, daemon=True).start()
http.server.ThreadingHTTPServer(("0.0.0.0", 8000), MetricsHandler).serve_forever()
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: training-metrics-demo
namespace: ml-observability
spec:
replicas: 1
selector:
matchLabels:
app: training-metrics-demo
template:
metadata:
labels:
app: training-metrics-demo
spec:
containers:
- name: metrics
image: python:3.12-slim
command:
- python
- /app/server.py
ports:
- name: metrics
containerPort: 8000
readinessProbe:
httpGet:
path: /metrics
port: metrics
initialDelaySeconds: 2
periodSeconds: 10
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
volumeMounts:
- name: application
mountPath: /app
readOnly: true
volumes:
- name: application
configMap:
name: training-metrics-server
---
apiVersion: azmonitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: training-metrics-demo
namespace: ml-observability
spec:
selector:
matchLabels:
app: training-metrics-demo
podMetricsEndpoints:
- port: metrics
path: /metrics
interval: 30s
scrapeTimeout: 10s
Per un processo distribuito reale, includere etichette stabili, ad esempio il nome del modello, la versione del modello, il nome del processo, l'ID esecuzione, il ruolo di replica e il team. Non usare etichette non associate, ad esempio ID di esempio, ID richiesta o percorsi di set di dati non elaborati perché le etichette con cardinalità elevata aumentano i costi di monitoraggio e la latenza delle query.
Creare dashboard gpu e velocità effettiva
Usa query PromQL come le seguenti come punto di partenza e verifica le etichette delle metriche nel tuo exporter:
avg by (namespace, pod, gpu) (
avg_over_time(DCGM_FI_DEV_GPU_UTIL[5m])
)
La query seguente calcola l'utilizzo della memoria del buffer di frame come percentuale:
100 *
DCGM_FI_DEV_FB_USED
/
(DCGM_FI_DEV_FB_USED + DCGM_FI_DEV_FB_FREE)
La seguente interrogazione calcola i campioni di addestramento elaborati al secondo:
sum by (job_name) (
rate(ml_training_samples_total[5m])
)
Nella query seguente viene visualizzata la durata media dei passaggi:
avg by (job_name) (
ml_training_step_duration_seconds
)
Interpretare questi segnali insieme:
- L'utilizzo ridotto della GPU e il tempo di attesa dei dati elevato indicano in genere archiviazione, rete, pre-elaborazione o fame della CPU.
- Un utilizzo elevato della GPU con velocità effettiva prevista indica che l'acceleratore viene usato in modo efficace.
- Un uso elevato della memoria GPU e ripetuti errori di esaurimento della memoria indicano che la dimensione del batch, la lunghezza della sequenza, la memoria di attivazione, lo stato dell’ottimizzatore o la frammentazione richiedono un aggiustamento.
- La riduzione della velocità effettiva con un utilizzo stabile della GPU può indicare sequenze più lunghe, sovraccarico di comunicazione, comportamento termico o una modifica nel calcolo del modello.
- Un basso livello di utilizzo della GPU sulle GPU allocate indica la presenza di capacità inutilizzata che potrebbe essere ridimensionata, messa in coda diversamente o partizionata con MIG.
- Una lunga durata del checkpoint può rendere costosa l'interruzione e aumentare la quantità di lavoro da ripetere dopo il ripristino.
Creare avvisi per sottoutilizzo GPU sostenute, memoria GPU quasi a capacità, errori XID, velocità effettiva di training bloccata, ruoli di lavoro non riusciti, carichi di lavoro pianificati gang in sospeso e checkpoint che non sono stati completati entro l'obiettivo previsto del punto di ripristino.
Domande frequenti
Qual è la differenza tra AKS Automatic e AKS Standard per MLOps?
AKS Automatic fornisce configurazioni predefinite per pool di nodi, rete, sicurezza e aggiornamenti, consentendo ai team MLOps di concentrarsi sulle definizioni dei carichi di lavoro e sulla governance. AKS Standard richiede la configurazione manuale di questi componenti della piattaforma, ma offre un maggiore controllo per architetture personalizzate e requisiti di scalabilità.
Come si esegue la versione dei modelli di Machine Learning nel servizio Azure Kubernetes?
Assegna una versione ai modelli impacchettando i pesi, i metadati e le configurazioni del modello in immagini container con tag di versioning semantico. Archiviare queste immagini in Registro Azure Container e fare riferimento a versioni specifiche nei manifesti della distribuzione kubernetes per garantire la coerenza tra gli ambienti.
Come si pianifica i carichi di lavoro GPU in AKS?
Assicurarsi che il plug-in del dispositivo NVIDIA sia disponibile in modo che i nodi GPU pubblicizzino nvidia.com/gpu. In AKS Standard, eseguire il provisioning di un pool di nodi utente GPU dedicato con una dimensione di macchina virtuale supportata, ad esempio uno SKU della serie Standard_NC, e configurare le etichette dei nodi, un elemento taint NoSchedule e i limiti del ridimensionamento automatico del cluster. In ogni pod di addestramento, richiedete nvidia.com/gpu, selezionate un nodo GPU idoneo e aggiungete la tollerazione corrispondente. AKS Automatic può effettuare il provisioning di capacità GPU idonea in base alle richieste dei pod, in funzione delle SKU supportate, della disponibilità a livello di area geografica, dei vincoli di pianificazione e della quota della sottoscrizione Azure.
Come si eseguono processi di training distribuito in AKS?
Installare il Training Operator di Kubeflow e inviare un PyTorchJob o TFJob per gestire le repliche distribuite, la configurazione del rendezvous, il comportamento di riavvio e lo stato del job. KAITO fornisce un'astrazione dello spazio di lavoro incentrata su AKS per i flussi di lavoro supportati per il fine-tuning dei modelli e può coordinare l'infrastruttura GPU con le configurazioni predefinite del modello. Per il training PyTorch multinodo, configurare ed eseguire il benchmark di NCCL sulla rete pod AKS CNI, consentire il traffico tra nodi di lavoro tramite i criteri di rete e usare la configurazione RDMA supportata quando lo SKU della VM selezionata e il carico di lavoro lo richiedono.
Come si gestisce la quota gpu tra più team?
Installare Kueue e definire le risorse ClusterQueue con quote di CPU, memoria e nvidia.com/gpu, quindi associare il namespace di ogni team alla quota assegnata tramite LocalQueue. Utilizza le coorti Kueue o la condivisione equa quando i team possono prendere in prestito della capacità inutilizzata. Il vulcano è un'alternativa quando è necessaria un'utilità di pianificazione batch con ammissione di lavoro all-or-nothing. Coordinare la priorità della coda con le risorse Kubernetes PriorityClass in modo che l'inferenza sensibile alla latenza possa impedire il training interrompibile e garantire il ripristino dei processi di training preemptible dai checkpoint nell'archiviazione permanente.
Quali sono le procedure consigliate per eseguire processi batch di lunga durata in AKS?
Usare un Kubernetes Job per attività limitate e un CronJob per attività pianificate. Mantieni persistenti i checkpoint e l'output sottoposto a commit all'esterno del pod, rendi l'elaborazione idempotente, gestisci SIGTERM e imposta richieste di risorse esplicite, limiti dei tentativi, scadenze e criteri di pulizia. Si presuma che la manutenzione o il guasto del nodo possano causare la sostituzione del pod e si verifichi che il pod sostitutivo ripristini correttamente il proprio checkpoint. Monitorare lo stato del job, gli eventi del pod, i log, l'età del checkpoint, la velocità effettiva e il comportamento dei tentativi di ripetizione. I normali Job riavviabili non richiedono né il gang scheduling né un PDB. Utilizzare questi controlli solo quando i worker paralleli devono avviarsi insieme o mantenere un livello minimo di concorrenza già testato.
Contenuti correlati
Scopri le procedure consigliate per altre aree della distribuzione e delle operazioni dell'applicazione in AKS:
- Confronto tra funzionalità automatiche del servizio Azure Kubernetes e Standard del servizio Azure Kubernetes
- Procedure consigliate per la resilienza e l'affidabilità delle applicazioni
- Procedure consigliate per la gestione delle risorse
- Procedure consigliate per la sicurezza dei pod
- Applicare le procedure consigliate con le misure di sicurezza della distribuzione