Formazione del Machine learning utilizzando Elastic Fabric Adapter - Amazon EKS

Formazione del Machine learning utilizzando Elastic Fabric Adapter

In questo argomento viene descritto come integrare Elastic Fabric Adapter (EFA) con i pod implementati nel cluster Amazon EKS. Elastic Fabric Adapter (EFA) è un'interfaccia di rete per le istanze Amazon EC2 che consente di eseguire applicazioni che richiedono livelli elevati di comunicazioni internodale su larga scala in AWS. La sua interfaccia hardware di bypass del sistema operativo personalizzata migliora le prestazioni delle comunicazioni tra istanze, che è fondamentale per dimensionare queste applicazioni. Con EFA, le applicazioni High Performance Computing (HPC) che utilizzano le applicazioni MPI (Message Passing Interface) e Machine Learning (ML) e che utilizzano NVIDIA Collective Communications Library (NCCL) possono dimensionare fino a migliaia di CPU o GPU. Di conseguenza, si ottengono le prestazioni delle applicazioni dei cluster HPC on-premise con l'elasticità e la flessibilità on demand del cloud AWS. L'integrazione di EFA con le applicazioni in esecuzione su cluster Amazon EKS può ridurre il tempo necessario per completare carichi di lavoro di formazione distribuiti su larga scala senza dover aggiungere ulteriori istanze al cluster. Per ulteriori informazioni su EFA, consultare Elastic Fabric Adapter.

Il plug-in EFA descritto in questo argomento supporta pienamente istanze Amazon EC2 P4d, che rappresentano l'attuale stato dell'arte nel machine learning distribuito nel cloud. Ciascun istanza p4d.24xlarge ha otto GPU NVIDIA A100 e GPUDirectRDMA a 400 Gbps su EFA. GPUDirectRDMA consente di avere una comunicazione diretta da GPU a GPU tra i nodi con bypass della CPU, aumentando la larghezza di banda di comunicazione collettiva e riducendo la latenza. L'integrazione di Amazon EKS e EFA con istanze P4d offre un metodo senza soluzione di continuità per sfruttare l'istanza di elaborazione Amazon EC2 dalle prestazioni più elevate per la formazione del machine learning distribuito.

Prerequisiti

  • Cluster Amazon EKS esistente aggiornato alla versione 1.19 o successive. Se non disponi di un cluster esistente, consultare una delle guide Guida introduttiva ad Amazon EKS per crearne uno. Il cluster deve essere implementato in un VPC con almeno una sottorete privata con indirizzi IP disponibili sufficienti in cui implementare i nodi. La sottorete privata deve disporre di un accesso Internet in uscita fornito da un dispositivo esterno, ad esempio un gateway NAT.

    Se si prevede di utilizzare eksctl per creare il gruppo di nodi, eksctl può anche creare un cluster 1.19 per l'utente.

  • La versione 2.4.9 o successiva o la versione 1.22.30 o successiva della AWS CLI installata e configurata sul computer o nella AWS CloudShell. Per ulteriori informazioni, consulta le sezioni Installazione, aggiornamento e disinstallazione della AWS CLI e Configurazione rapida con aws configure nella Guida per l'utente di AWS Command Line Interface.

  • Lo strumento a riga di comando kubectl installato sul computer o AWS CloudShell. La versione deve essere la stessa o fino a due versioni successive rispetto alla versione del cluster. Per installare o aggiornare kubectl, consulta Installazione di kubectl.

  • Prima di avviare i nodi di lavoro che supportano più di un Elastic Fabric Adapter, come ad esempio p4d.24xlarge, è necessario disporre della versione 1.7.10 di CNI VPC. Per ulteriori informazioni sull'aggiornamento della versione di CNI, consultare Aggiornamento del componente aggiuntivo autogestito CNI di Amazon VPC.

Creazione di un gruppo di nodi

La procedura seguente consente di creare un gruppo di nodi con un gruppo di nodi supportato da p4d.24xlarge con interfacce EFA e GPUDirect RDMA, e di eseguire un test di esempio NVIDIA Collective Communications Library (NCCL) per prestazioni NCCL multi-nodo utilizzando più EFA. L'esempio può essere utilizzato come un modello per la formazione del deep learning distribuito su Amazon EKS utilizzando più EFA.

  1. Determinare in quali zone di disponibilità sono disponibili le istanze di Amazon EC2 che supportano EFA per la Regione in cui si trova il cluster

    1. Determina quali tipi di istanza Amazon EC2 che supportano EFA sono disponibili nella Regione AWS in cui si trova il cluster.

      aws ec2 describe-instance-types \ --region us-west-2 \ --filters Name=network-info.efa-supported,Values=true \ --query "InstanceTypes[*].[InstanceType]" \ --output text
    2. Determinare in quali zone di disponibilità è disponibile l'istanza selezionata dall'output precedente.

      aws ec2 describe-instance-type-offerings \ --location-type availability-zone \ --filters Name=instance-type,Values=p4d.24xlarge \ --region us-west-2 \ --output table

      Il nome della zona di disponibilità è elencato nella colonna Location dell'output restituito dal comando precedente.

  2. Creare un gruppo di nodi utilizzando eksctl o la AWS CLI e AWS CloudFormation.

    eksctl

    Prerequisito

    La versione 0.84.0 o successive dello strumento a riga di comando eksctl deve essere installata sul computer o nella AWS CloudShell. Per installare o aggiornare eksctl, consulta Installazione di eksctl.

    1. Copiare i contenuti seguenti in un file denominato efa-cluster.yaml. Sostituire i valori di esempio con i propri valori. È possibile sostituire p4d.24xlarge con un'istanza diversa, assicurarsi però che i valori per availabilityZones corrispondano a zone di disponibilità restituite per il tipo di istanza nel passaggio 1.

      apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-efa-cluster region: us-west-2 version: "1.19" iam: withOIDC: true availabilityZones: ["us-west-2a", "us-west-2c"] managedNodeGroups: - name: my-efa-ng instanceType: p4d.24xlarge minSize: 1 desiredCapacity: 2 maxSize: 3 availabilityZones: ["us-west-2a"] volumeSize: 300 privateNetworking: true efaEnabled: true
    2. Creare un gruppo di nodi gestito in un cluster esistente.

      eksctl create nodegroup -f efa-cluster.yaml

      Se non si dispone di un cluster esistente, è possibile eseguire il comando seguente per creare un cluster e il gruppo di nodi.

      eksctl create cluster -f efa-cluster.yaml
    AWS CLI and AWS CloudFormation

    Esistono diversi requisiti per le reti EFA, tra cui la creazione di un gruppo di sicurezza specifico EFA, la creazione di un gruppo di collocamento Amazon EC2 e la creazione di un modello di avvio che specifica una o più interfacce EFA e include l'installazione dei driver EFA come parte dei dati utente Amazon EC2. Per ulteriori informazioni sui requisiti EFA, consultare Nozioni di base su EFA e MPI nella Guida per l'utente di Amazon EC2 per le istanze Linux. I seguenti passaggi permettono di creare tutto questo per conto dell'utente. Sostituire i valori di esempio con i propri valori.

    1. Impostare alcune variabili utilizzate nei passaggi successivi. Sostituire il example values con i valori in proprio possesso. Sostituire tutte le stringhe my-cluster con il nome del cluster esistente. Il valore per node_group_resources_name viene utilizzato in seguito per creare una pila AWS CloudFormation. Il valore per node_group_name viene utilizzato in seguito per creare il gruppo di nodi nel cluster.

      cluster_name="my-cluster" cluster_region="us-west-2" node_group_resources_name="my-efa-nodegroup-resources" node_group_name="my-efa-nodegroup"
    2. Identificare una sottorete privata nel VPC, e verificare che si trovi e sia disponibile nella stessa zona di disponibilità in cui si desidera implementare il tipo di istanza.

      1. Recuperare la versione del cluster e memorizzarla in una variabile da utilizzare in un passaggio successivo.

        cluster_version=$(aws eks describe-cluster \ --name $cluster_name \ --query "cluster.version" \ --output text)
      2. Recuperare l'ID VPC in cui si trova il cluster e memorizzarlo in una variabile per utilizzarlo in un passaggio successivo.

        vpc_id=$(aws eks describe-cluster \ --name $cluster_name \ --query "cluster.resourcesVpcConfig.vpcId" \ --output text)
      3. Recuperare l'ID del gruppo di sicurezza del piano di controllo per il cluster e memorizzarlo in una variabile da utilizzare in un passaggio successivo.

        control_plane_security_group=$(aws eks describe-cluster \ --name $cluster_name \ --query "cluster.resourcesVpcConfig.clusterSecurityGroupId" \ --output text)
      4. Ottenere l'elenco degli ID sottorete nel VPC che si trovano in una zona di disponibilità restituita al passaggio 1.

        aws ec2 describe-subnets \ --filters "Name=vpc-id,Values=$vpc_id" "Name=availability-zone,Values=us-west-2a" \ --query 'Subnets[*].SubnetId' \ --output text

        Se non viene restituito alcun output, provare con una zona di disponibilità diversa nel passaggio 1. Se nessuna delle sottoreti si trova in una zona di disponibilità restituita al passaggio 1, è necessario creare una sottorete in una zona di disponibilità restituita al passaggio 1. Se nel VPC non è disponibile spazio per creare un'altra sottorete, potrebbe essere necessario creare un nuovo cluster in un nuovo VPC.

      5. Controllando la tabella di routing per la sottorete, verificare se la sottorete è privata.

        aws ec2 describe-route-tables \ --filter Name=association.subnet-id,Values=subnet-0d403852a65210a29 \ --query "RouteTables[].Routes[].GatewayId" \ --output text

        Output

        local

        Se l'output è local igw-02adc64c1b72722e2, la sottorete è pubblica. È necessario selezionare una sottorete privata in una zona di disponibilità restituita al passaggio 1. Dopo aver identificato una sottorete privata, annotare il relativo ID da utilizzare in un passaggio successivo.

      6. Impostare una variabile con l'ID della sottorete privata del passaggio precedente per utilizzarla nei passaggi successivi.

        subnet_id=your-subnet-id
    3. Eseguire il download del modello AWS CloudFormation.

      curl -o efa-p4d-managed-nodegroup.yaml https://raw.githubusercontent.com/aws-samples/aws-efa-eks/main/cloudformation/efa-p4d-managed-nodegroup.yaml
    4. Copiare il testo seguente sul computer. Sostituisci p4d.24xlarge con un tipo di istanza dal passaggio 1. Sostituisci sottorete-0d403852a65210a29 con l'ID della sottorete privata identificata nella fase 2.b.v. Sostituisci path-to-downloaded-cfn-template con il percorso per il efa-p4d-managed-nodegroup.yaml scaricato nella fase precedente. Sostituisci nome-pubblico-chiave con il nome della chiave pubblica. Dopo aver effettuato le sostituzioni, eseguire il comando modificato.

      aws cloudformation create-stack \ --stack-name ${node_group_resources_name} \ --capabilities CAPABILITY_IAM \ --template-body file://path-to-downloaded-cfn-template \ --parameters \ ParameterKey=ClusterName,ParameterValue=${cluster_name} \ ParameterKey=ClusterControlPlaneSecurityGroup,ParameterValue=${control_plane_security_group} \ ParameterKey=VpcId,ParameterValue=${vpc_id} \ ParameterKey=SubnetId,ParameterValue=${subnet_id} \ ParameterKey=NodeGroupName,ParameterValue=${node_group_name} \ ParameterKey=NodeImageIdSSMParam,ParameterValue=/aws/service/eks/optimized-ami/${cluster_version}/amazon-linux-2-gpu/recommended/image_id \ ParameterKey=KeyName,ParameterValue=your-public-key-name \ ParameterKey=NodeInstanceType,ParameterValue=p4d.24xlarge
    5. Determinare il momento in cui la pila implementata nel passaggio precedente viene implementato.

      aws cloudformation wait stack-create-complete --stack-name $node_group_resources_name

      Non c'è output dal comando precedente, ma il prompt della shell non viene restituito fino a quando non viene creara la pila.

    6. Creare il gruppo di nodi utilizzando le risorse create dalla pila AWS CloudFormation nel passaggio precedente.

      1. Recuperare le informazioni dalla pila AWS CloudFormation implementata e memorizzarle in variabili.

        node_instance_role=$(aws cloudformation describe-stacks \ --stack-name $node_group_resources_name \ --query='Stacks[].Outputs[?OutputKey==`NodeInstanceRole`].OutputValue' \ --output text) launch_template=$(aws cloudformation describe-stacks \ --stack-name $node_group_resources_name \ --query='Stacks[].Outputs[?OutputKey==`LaunchTemplateID`].OutputValue' \ --output text)
      2. Creare un gruppo di nodi gestiti che utilizzi il modello di avvio e il ruolo IAM del nodo creati nel passaggio precedente.

        aws eks create-nodegroup \ --cluster-name $cluster_name \ --nodegroup-name $node_group_name \ --node-role $node_instance_role \ --subnets $subnet_id \ --launch-template id=$launch_template,version=1
      3. Confermare che i nodi siano stati creati.

        aws eks describe-nodegroup \ --cluster-name ${cluster_name} \ --nodegroup-name ${node_group_name} | jq -r .nodegroup.status

        Non continuare finché lo stato restituito dal comando precedente non è ACTIVE. Possono essere necessari diversi minuti prima che i nodi siano pronti.

    7. Implementare il plug-in per dispositivi EFA Kubernetes.

      Il plug-in per dispositivi EFA Kubernetes rileva e pubblicizza le interfacce EFA come risorse allocabili a Kubernetes. Un'applicazione può consumare il tipo di risorsa estesa vpc.amazonaws.com/efa in una specifica di richiesta pod proprio come CPU e memoria. Per ulteriori informazioni, consultare Consumo di risorse estese nella documentazione su Kubernetes. Una volta richiesto, il plug-in assegna e monta automaticamente un'interfaccia EFA al pod. L'utilizzo del plug-in per dispositivi semplifica la configurazione EFA e non richiede l'esecuzione di un pod in modalità privilegiata.

      kubectl apply -f https://raw.githubusercontent.com/aws-samples/aws-efa-eks/main/manifest/efa-k8s-device-plugin.yml
    8. Se è stato implementato un tipo di istanza con una GPU, implementare il plug-in per dispositivi NVIDIA Kubernetes.

      kubetl apply -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.9.0/nvidia-device-plugin.yml

(Facoltativo) Implementare un'applicazione compatibile EFA di esempio

Implementare l'operatore MPI Kubeflow

Per i test NCCL è possibile applicare l'operatore Kubeflow MPI. L'operatore MPI semplifica l'esecuzione della formazione distribuita AllReduce-style su Kubernetes. Per ulteriori informazioni, consultare Operatore MPI su GitHub.

kubectl apply -f https://raw.githubusercontent.com/kubeflow/mpi-operator/master/deploy/v1alpha2/mpi-operator.yaml

Eseguire il test delle prestazioni NCCL a più nodi per verificare GPUDirectrDMA/EFA

Per verificare le prestazioni NCCL con GPUDirectRDMA su EFA, esegui il test delle prestazioni NCCL standard. Per ulteriori informazioni consultare il repository Test NCCL su GitHub. È possibile utilizzare l'esempio Dockerfile che viene fornito con questo test già creato per CUDA 11.2 e per l'ultima versione di EFA.

In alternativa, è possibile eseguire il download di AWS un'immagine Docker disponibile da un repository di Amazon ECR.

Importante

Un'importante considerazione necessaria per l'adozione di EFA con Kubernetes è la configurazione e la gestione di Huge Pages come risorsa nel cluster. Per ulteriori informazioni, consultare Gestione di Huge Pages nella documentazione Kubernetes. Le istanze Amazon EC2 con il driver EFA installato pre-allocano 5128 Huge Pages da 2M, che possono essere richieste come risorse da utilizzare nelle specifiche del processo.

Completa i seguenti passaggi per eseguire un test delle prestazioni NCCL a due nodi. Nel processo di test NCCL di esempio, ogni worker richiede otto GPU, 5210Mi di HugePages-2Mi, quattro EFA e 8000Mi di memoria, il che significa che ogni worker consuma tutte le risorse di un'istanza p4d.24xlarge.

  1. Creare il processo di test NCCL.

    kubectl apply -f https://raw.githubusercontent.com/aws-samples/aws-efa-eks/main/examples/simple/nccl-efa-tests.yaml

    Output

    mpijob.kubeflow.org/nccl-tests-efa creato

  2. Visualizza i pod in esecuzione.

    kubectl get pods

    Output

    NAME READY STATUS RESTARTS AGE nccl-tests-efa-launcher-nbql9 0/1 Init:0/1 0 2m49s nccl-tests-efa-worker-0 1/1 Running 0 2m49s nccl-tests-efa-worker-1 1/1 Running 0 2m49s

    L'operatore MPI crea un pod di avvio e 2 pod di lavoro (uno su ciascun nodo).

  3. Visualizzare il log per il pod efa-launcher. Sostituisci wzr8j con il valore dell'output.

    kubectl logs -f nccl-tests-efa-launcher-nbql9

Per altri esempi, consultare il repository Amazon EKS Esempi di EFA su GitHub.