

 **Ajudar a melhorar esta página** 

Para contribuir com este guia de usuário, escolha o link **Editar esta página no GitHub**, disponível no painel direito de cada página.

# Execute o treinamento de machine learning no Amazon EKS com o Elastic Fabric Adapter
<a name="node-efa"></a>

Este tópico descreve como integrar o Elastic Fabric Adapter (EFA) com pods implantados no cluster do Amazon EKS. O Elastic Fabric Adapter (EFA) é uma interface de rede para instâncias do Amazon EC2 que permite que você execute aplicações que exigem altos níveis de comunicações entre nós em escala na AWS. Sua interface de hardware de bypass do sistema operacional personalizada melhora a performance das comunicações entre instâncias, o que é essencial para escalar essas aplicações. Com a EFA, as aplicações de Computação de Alta Performance (HPC) que usam a Interface de Passagem de Mensagens (MPI) e as aplicações de machine learning (ML) que usam a NVIDIA Collective Communications Library (NCCL) podem ser escaladas para milhares de CPUs ou GPUs. Como resultado, você obtém a performance da aplicação de clusters de HPC on-premises, com a elasticidade e a flexibilidade sob demanda da nuvem AWS. A integração da EFA com aplicações executadas em clusters do Amazon EKS pode reduzir o tempo para concluir workloads de treinamento distribuídas em grande escala sem precisar adicionar instâncias adicionais ao cluster. Para obter mais informações sobre o EFA, consulte [Elastic Fabric Adapter](https://aws.amazon.com/hpc/efa/).

## Tipos de instância com EFA
<a name="efa-instances"></a>

O *plug-in de dispositivo EFA Kubernetes da AWS* é compatível com todos os tipos de instância do Amazon EC2 que têm EFA. Para ver uma lista de tipos de instância que oferecem suporte a EFAs, consulte [Tipos de instância compatíveis](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html#efa-instance-types) no *Guia do usuário do Amazon EC2*. No entanto, para executar aplicações de ML rapidamente, recomendamos que uma instância tenha chips de aceleração de hardware, como GPUs nVidia, chips do [AWS Inferentia](https://aws.amazon.com/machine-learning/inferentia/) ou chips do [AWS Trainium](https://aws.amazon.com/machine-learning/trainium/), além do EFA. Para ver uma lista de tipos de instância equipadas com chips de aceleração de hardware e EFA, consulte [Computação acelerada](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa.html#efa-instance-types) no *Guia do usuário do Amazon EC2*.

Ao comparar os tipos de instância para escolher entre eles, considere o número de placas de rede EFA disponíveis para esse tipo de instância, bem como o número de placas aceleradoras, a quantidade de CPU e a quantidade de memória. É possível atribuir até uma EFA por placa de rede. Um EFA conta como uma interface de rede. Para ver quantos EFA estão disponíveis para cada tipo de instância equipada com EFA, consulte a lista [Placas de rede](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#network-cards) no *Guia do usuário do Amazon EC2*.

## Interfaces EFA e somente EFA
<a name="efa-only-interfaces"></a>

Um *Elastic Fabric Adapter (EFA)* é uma interface de rede que combina os recursos de um Adaptador de Rede Elástica (ENA) e uma interface de desvio de sistema operacional, alimentada pelo protocolo AWS Scalable Reliable Datagram (SRD). As funcionalidades do EFA permitem que as aplicações se comuniquem diretamente com o hardware para transporte de baixa latência. É possível acessar exclusivamente os recursos do EFA usando interfaces *somente EFA*, limitando a comunicação às interfaces dentro da mesma zona de disponibilidade.

Para criar nós que possam ter interfaces somente EFA, você deve usar um modelo de inicialização do EC2 personalizado e definir `InterfaceType` como `efa-only`. No modelo de inicialização personalizado, não é possível definir a placa de rede `0` como uma interface somente EFA, pois essa é a placa de rede principal e a interface de rede da instância do EC2. Você deve ter o CNI da VPC versão `1.18.5` ou posterior para interfaces somente do tipo EFA. Se você estiver usando o Amazon Linux 2, a versão da ami deve ser `v20240928` ou posterior para interfaces somente do tipo EFA.

O procedimento a seguir orienta você a criar um cluster do EKS com o `eksctl` com nós que têm GPUs nVidia e interfaces do EFA. Não é possível usar o `eksctl` para criar nós e grupos de nós que usam interfaces somente EFA.

## Pré-requisitos
<a name="efa-prereqs"></a>
+ Um cluster do existente do Amazon EKS. Se você não tiver um cluster existente, crie um usando o [Começar a usar o Amazon EKS](getting-started.md). O cluster dove ser implantado em uma VPC que tenha pelo menos uma sub-rede privada com endereços IP disponíveis suficientes para implantar nós. A sub-rede privada deve ter acesso de saída à Internet fornecido por um dispositivo externo, como um gateway NAT.

  Se você planeja usar o `eksctl` para criar o grupo de nós, o `eksctl` também pode criar um cluster para você.
+ Versão `2.12.3` ou posterior ou versão `1.27.160` ou posterior da AWS Command Line Interface (AWS CLI) instalada e configurada no seu dispositivo ou no AWS CloudShell. Para verificar sua versão atual, use `aws --version | cut -d / -f2 | cut -d ' ' -f1`. Os gerenciadores de pacotes, como `yum`, `apt-get` ou Homebrew para macOS, geralmente estão várias versões atrás da versão mais recente da AWS CLI. Para instalar a versão mais recente, consulte [Installing](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) e [Quick configuration with aws configure](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-config), no *Guia do usuário da AWS Command Line Interface*. A versão da AWS CLI instalada no AWS CloudShell também pode estar várias versões atrás da versão mais recente. Para atualizá-lo, consulte [Instalar a AWS CLI no seu diretório pessoal](https://docs.aws.amazon.com/cloudshell/latest/userguide/vm-specs.html#install-cli-software), no * Guia do usuário do AWS CloudShell*.
+ A ferramenta da linha de comando `kubectl` está instalada no seu dispositivo ou no AWS CloudShell. A versão pode ser a mesma ou até uma versão secundária anterior ou posterior à versão do Kubernetes do seu cluster. Por exemplo, se a versão do cluster for a `1.29`, você poderá usar o `kubectl` versão `1.28`, `1.29` ou `1.30` com ele. Para instalar ou atualizar o `kubectl`, consulte [Configurar o `kubectl` e o `eksctl`](install-kubectl.md).
+ Você deve ter a versão `1.7.10` ou mais recente do plug-in CNI da Amazon VPC para Kubernetes instalada para que possa executar os nós de processamento que sejam compatíveis com vários Elastic Fabric Adapters, como o `p4d` ou `p5`. Para obter mais informações sobre como atualizar a versão do plug-in CNI da Amazon VPC para Kubernetes, consulte [Atribuir IPs a pods com a CNI da Amazon VPC](managing-vpc-cni.md).
+ Para instâncias p6-b200, você deve usar o plug-in do dispositivo EFA versão v0.5.6 ou posterior.

**Importante**  
Uma consideração importante, necessária para adotar o EFA com o Kubernetes, é configurar e gerenciar páginas enormes como um recurso no cluster. Para obter mais informações, consulte [Manage Huge Pages](https://kubernetes.io/docs/tasks/manage-hugepages/scheduling-hugepages/) (Gerenciar páginas grandes) na documentação do Kubernetes. As instâncias do Amazon EC2 com o driver EFA instalado pré-alocam 5128 páginas enormes de 2 MiB, as quais você pode solicitar como recursos para consumir em suas especificações de trabalho.

## Crie grupos de nós.
<a name="efa-create-nodegroup"></a>

O procedimento a seguir ajuda você a criar um grupo de nós que conta com o suporte do `p4d.24xlarge` e interfaces EFA e GPUDirect RDMA, além de executar um exemplo de teste NVIDIA Collective Communications Library (NCCL) para a performance do NCCL de vários nós usando EFAs. O exemplo pode ser usado em um modelo para treinamento de aprendizado profundo distribuído no Amazon EKS usando EFAs.

1. Determine quais tipos de instância do Amazon EC2 com suporte para EFA estão disponíveis na região da AWS em que você deseja implantar os nós. Substitua *region-code* pela região da AWS em que deseja implantar os grupo de nós.

   ```
   aws ec2 describe-instance-types --region region-code \
       --filters Name=network-info.efa-supported,Values=true \
       --query "InstanceTypes[*].[InstanceType]" --output text
   ```

   Quando você implanta nós, o tipo de instância que deseja implantar deve estar disponível na região AWS em que o cluster se encontra.

1. Determine em quais zonas de disponibilidade o tipo de instância que você deseja implantar está disponível. Neste tutorial, o tipo de instância `p5.48xlarge` é usado e deve ser retornado na saída para a região AWS que você especificou na etapa anterior. Ao implantar nós em um cluster do produção, substitua *p5.48xlarge* por qualquer tipo de instância retornado na etapa anterior.

   ```
   aws ec2 describe-instance-type-offerings --region region-code \
       --location-type availability-zone --filters Name=instance-type,Values=p4d.24xlarge,p5.48xlarge \
       --query 'InstanceTypeOfferings[*].Location' --output text
   ```

   Veja abaixo um exemplo de saída.

   ```
   us-west-2a    us-west-2c    us-west-2b
   ```

   Observe as zonas de disponibilidade retornadas para uso em etapas posteriores. Quando você implanta nós em um cluster, a VPC deve ter sub-redes com endereços IP disponíveis em uma das zonas de disponibilidade retornadas na saída.

1. Crie um grupo de nós usando `eksctl`. Você precisa da versão `0.215.0` ou posterior da ferramenta de linha de comando `eksctl` instalada em seu dispositivo ou do AWS CloudShell. Para instalar ou atualizar o `eksctl`, consulte [Instalação](https://eksctl.io/installation) na documentação do `eksctl`.

   1. Copie o conteúdo a seguir em um arquivo chamado *efa-cluster.yaml*. Substitua os valores de exemplo pelos seus próprios. É possível substituir `p5.48xlarge` por uma instância diferente mas, se fizer isso, certifique-se de que os valores de `availabilityZones` sejam as zonas de disponibilidade que foram retornadas para o tipo de instância na etapa 1.

      ```
      apiVersion: eksctl.io/v1alpha5
      kind: ClusterConfig
      
      metadata:
        name: my-efa-cluster
        region: region-code
        version: "1.XX"
      
      iam:
        withOIDC: true
      
      availabilityZones: ["us-west-2a", "us-west-2c"]
      
      managedNodeGroups:
        - name: my-efa-ng
          instanceType: p5.48xlarge
          minSize: 1
          desiredCapacity: 2
          maxSize: 3
          availabilityZones: ["us-west-2a"]
          volumeSize: 300
          privateNetworking: true
          efaEnabled: true
      ```

   1. Crie um grupo de nós gerenciados em um cluster existente.

      ```
      eksctl create nodegroup -f efa-cluster.yaml
      ```

      Se você não tiver um cluster existente, recomendamos que siga um dos comandos a seguir para criar um cluster e o grupo de nós.

      ```
      eksctl create cluster -f efa-cluster.yaml
      ```
**nota**  
Como o tipo de instância usado neste exemplo tem GPUs, o `eksctl` instala automaticamente o plug-in de dispositivo NVIDIA para Kubernetes em cada instância para você ao usar o Amazon Linux 2. Isso não é necessário para o Bottlerocket, pois o plug-in do dispositivo NVIDIA está integrado na variante NVIDIA do Bottlerocket. Quando `efaEnabled` é definido como `true` na configuração do grupo de nós, o `eksctl` também implantará automaticamente o plug-in do dispositivo EFA nos nós.

### Como usar o Bottlerocket com o EFA
<a name="efa-bottlerocket"></a>

A versão 1.28.0 e posteriores da AMI do Bottlerocket incluem suporte oficial para o EFA. Para usar o Bottlerocket para nós habilitados para o EFA, especifique `amiFamily: Bottlerocket` em sua configuração. Caso precise usar um ID de AMI personalizado, você deverá usar o padrão `nodeGroups` em vez de `managedNodeGroups`.

Confira um exemplo de configuração:

```
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: my-efa-bottlerocket-cluster
  region: region-code
  version: "1.XX"

iam:
  withOIDC: true

availabilityZones: ["us-west-2a", "us-west-2c"]

managedNodeGroups:
  - name: my-efa-bottlerocket-ng
    instanceType: p5.48xlarge
    minSize: 1
    desiredCapacity: 2
    maxSize: 3
    availabilityZones: ["us-west-2a"]
    volumeSize: 300
    privateNetworking: true
    efaEnabled: true
    amiFamily: Bottlerocket
    bottlerocket:
      enableAdminContainer: true
      settings:
        kernel:
          sysctl:
            "vm.nr_hugepages": "3000"  # Configures 3000 * 2Mi = 6000Mi hugepages
```

A configuração `vm.nr_hugepages` de sysctl acima configura o número de hugepages de 2Mi. Neste exemplo, 3000 significa 3000 \$1 2Mi = 6000Mi de hugepages.

### Verificar a instalação do plug-in do dispositivo EFA
<a name="verify-efa-device-plugin"></a>

Quando você cria um grupo de nós com `efaEnabled: true`, o `eksctl` implanta automaticamente o plug-in do dispositivo EFA para Kubernetes para você. Você pode verificar se o plug-in do dispositivo está instalado e funcionando corretamente:

1. Verifique o status do DaemonSet:

   ```
   kubectl get daemonsets -n kube-system
   ```

   Exemplo de resultado:

   ```
   NAME                                  DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
   aws-efa-k8s-device-plugin-daemonset   2         2         2       2            2           <none>          6m16s
   ...
   ```

   Aqui, o DaemonSet do plug-in do dispositivo EFA está sendo executado em dois nós. Ambos estão READY e AVAILABLE.

1. Em seguida, verifique os pods criados pelo DaemonSet:

   ```
   kubectl get pods -n kube-system -l name=aws-efa-k8s-device-plugin
   ```

   Exemplo de resultado:

   ```
   NAME                                        READY   STATUS    RESTARTS   AGE
   aws-efa-k8s-device-plugin-daemonset-d68bs   1/1     Running   0          6m16s
   aws-efa-k8s-device-plugin-daemonset-w4l8t   1/1     Running   0          6m16s
   ```

   Os pods do plug-in do dispositivo EFA estão no estado Running, confirmando que o plug-in foi implantado com êxito e está operacional.

1. Verifique o registro do recurso:

   Você pode confirmar se o recurso `vpc.amazonaws.com/efa` está registrado no kubelet descrevendo os nós:

   ```
   kubectl describe nodes
   ```

   Se o recurso EFA estiver registrado corretamente, você o verá listado sob os recursos Capacidade e Alocável do nó. Por exemplo:

   ```
   Capacity:
     ...
     vpc.amazonaws.com/efa:  4
   Allocatable:
     ...
     vpc.amazonaws.com/efa:  4
   ```

   Essa saída confirma que o nó reconhece o recurso EFA, tornando-o disponível para pods que o solicitarem.

## (Opcional) Testar a performance do EFA
<a name="efa-application"></a>

Recomendamos testar a configuração de EFA. Você pode usar os [Testes NCCL](https://github.com/aws-samples/awsome-distributed-training/tree/main/micro-benchmarks/nccl-tests) no repositório `aws-samples/awsome-distributed-training` no GitHub. Os [Testes NCCL](https://github.com/NVIDIA/nccl-tests) avaliam a performance da rede usando a Nvidia Collective Communication Library. As etapas a seguir enviam testes de NCCL no Amazon EKS.

1. Implantar o operador Kubeflow MPI:

   Para os testes NCCL, você pode aplicar o Kubeflow MPI Operator. O MPI Operator facilita a execução do treinamento distribuído no estilo AllReduce no Kubernetes. Para obter mais informações, consulte [MPI Operator](https://github.com/kubeflow/mpi-operator) no GitHub.

1. Execute o teste de performance NCCL em vários nós para verificar o GPUDirectRDMA/EFA:

   Para verificar a performance do NCCL com o GPUDirectRDMA no EFA, execute o teste de performance padrão do NCCL. Para obter mais informações, consulte o respositório [NCCL-Tests](https://github.com/NVIDIA/nccl-tests.git) (Testes de NCCL) no GitHub.

   Conclua as etapas a seguir para executar um teste de performance do NCCL de dois nós. No trabalho de exemplo de teste do NCCL, cada operador solicita oito GPUs, 5.210 Mi de `hugepages-2Mi`, quatro EFAs e 8.000 Mi de memória, o que significa efetivamente que cada operador consome todos os recursos de uma instância `p5.48xlarge`.

   1. Criar o manifesto MPIJob:

      Copie o seguinte para um arquivo chamado `nccl-tests.yaml`:

      ```
      apiVersion: kubeflow.org/v2beta1
      kind: MPIJob
      metadata:
        name: nccl-tests
      spec:
        runPolicy:
          cleanPodPolicy: Running
          backoffLimit: 20
        slotsPerWorker: 8
        mpiReplicaSpecs:
          Launcher:
            replicas: 1
            template:
               spec:
                restartPolicy: OnFailure
                containers:
                - image: public.ecr.aws/hpc-cloud/nccl-tests:latest
                  imagePullPolicy: IfNotPresent
                  name: test-nccl-launcher
                  env:
                   - name: PATH
                     value: $PATH:/opt/amazon/efa/bin:/usr/bin
                  command:
                  - /opt/amazon/openmpi/bin/mpirun
                  - --allow-run-as-root
                  - --tag-output
                  - -np
                  - "16"
                  - -N
                  - "8"
                  - --bind-to
                  - none
                  - -x
                  - PATH
                  - -x
                  - LD_LIBRARY_PATH
                  - -x
                  - NCCL_DEBUG=INFO
                  - -x
                  - NCCL_BUFFSIZE=8388608
                  - -x
                  - NCCL_P2P_NET_CHUNKSIZE=524288
                  - -x
                  - NCCL_TUNER_PLUGIN=/opt/amazon/ofi-nccl/lib/x86_64-linux-gnu/libnccl-ofi-tuner.so
                  - --mca
                  - pml
                  - ^cm,ucx
                  - --mca
                  - btl
                  - tcp,self
                  - --mca
                  - btl_tcp_if_exclude
                  - lo,docker0,veth_def_agent
                  - /opt/nccl-tests/build/all_reduce_perf
                  - -b
                  - "8"
                  - -e
                  - "16G"
                  - -f
                  - "2"
                  - -g
                  - "1"
                  - -c
                  - "1"
                  - -n
                  - "100"
          Worker:
            replicas: 2
            template:
              spec:
                nodeSelector:
                  node.kubernetes.io/instance-type: "p5.48xlarge"
                containers:
                - image: public.ecr.aws/hpc-cloud/nccl-tests:latest
                  imagePullPolicy: IfNotPresent
                  name: nccl-tests-worker
                  volumeMounts:
                  - name: shmem
                    mountPath: /dev/shm
                  resources:
                    limits:
                      nvidia.com/gpu: 8
                      hugepages-2Mi: 5120Mi
                      vpc.amazonaws.com/efa: 32
                      memory: 32000Mi
                    requests:
                      nvidia.com/gpu: 8
                      hugepages-2Mi: 5120Mi
                      vpc.amazonaws.com/efa: 32
                      memory: 32000Mi
                volumes:
                - name: shmem
                  hostPath:
                    path: /dev/shm
      ```

   1. Aplicar MPIJob NCCL-tests:

      Envie o `MPIJob` aplicando o manifesto. Isso criará duas instâncias `p5.48xlarge` do Amazon EC2.

      ```
      kubectl apply -f nccl-tests.yaml
      ```

      Veja abaixo um exemplo de saída.

      ```
      mpijob.kubeflow.org/nccl-tests created
      ```

   1. Verifique se o trabalho iniciou os pods:

      Visualize os pods em execução.

      ```
      kubectl get pods
      ```

      Veja abaixo um exemplo de saída.

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

      O MPI Operator cria um pod inicializador e dois pods de operador (um em cada nó).

   1. Verifique se o trabalho está sendo executado com êxito com os logs:

      Visualize o log do pod `nccl-tests-launcher`. Substitua *nbql9* pelo valor de sua saída.

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

Se o teste for concluído com êxito, você poderá implantar as aplicações que usam a Nvidia Collective Communication Library.