

# Conceitos básicos do EFA e NIXL para workloads de inferência no Amazon EC2
<a name="efa-start-nixl"></a>

A NVIDIA Inference Xfer Library (NIXL) é uma biblioteca de comunicação de alto throughput e baixa latência projetada especificamente para workloads de inferência desagregadas. O NIXL pode ser usado junto com o EFA e o Libfabric para oferecer suporte à transferência de KV-cache entre os nós de pré-preenchimento e decodificação, além de permitir a movimentação eficiente do KV-cache entre várias camadas de armazenamento. Para obter mais informações, acesse o site da [NIXL](https://github.com/ai-dynamo/nixl).

**Requisitos**
+ Apenas as AMIs básicas do Ubuntu 24.04 e do Ubuntu 22.04 são compatíveis.
+ O EFA é compatível somente com a NIXL 1.0.0 e posteriores.

**Topics**

## Etapa 1: Preparar um grupo de segurança habilitado para EFA
<a name="nixl-start-base-setup"></a>

Um EFA requer um grupo de segurança que permita todo o tráfego de entrada e saída do grupo de segurança e para ele próprio. O procedimento a seguir cria um grupo de segurança que permite todo o tráfego de entrada e saída de e para si mesmo e que permite tráfego SSH de entrada de qualquer endereço IPv4 para conectividade SSH.

**Importante**  
Esse grupo de segurança deve ser usado apenas para fins de teste. Para seus ambientes de produção, recomendamos que você crie uma regra SSH de entrada que permita o tráfego somente do endereço IP do qual você está se conectando, como o endereço IP do seu computador ou uma variedade de endereços IP na sua rede local.

Para outros cenários, consulte [Regras de grupo de segurança para diferentes casos de uso](security-group-rules-reference.md).

**Para criar um grupo de segurança habilitado para EFA**

1. Abra o console do Amazon EC2 em [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. No painel de navegação, escolha **Security Groups** (Grupos de segurança) e, em seguida, **Create Security Group** (Criar grupo de segurança).

1. Na janela **Security group** (Grupo de segurança), faça o seguinte:

   1. Em **Security group name** (Nome do grupo de segurança), insira um nome descritivo para o grupo de segurança, como `EFA-enabled security group`.

   1. (Opcional) Em **Description** (Descrição), insira uma breve descrição do grupo de segurança.

   1. Em **VPC**, selecione a VPC na qual você pretende executar suas instâncias habilitadas para EFA.

   1. Escolha **Criar grupo de segurança**.

1. Selecione o grupo de segurança que você criou e, na guia **Details** (Detalhes), copie o **Security group** (Grupo de segurança).

1. Com o grupo de segurança ainda selecionado, escolha **Actions** (Ações), **Edit inbound rules** (Editar regras de entrada), e faça o seguinte:

   1. Escolha **Adicionar regra**.

   1. Para **Tipo**, escolha **Todo o tráfego**.

   1. Para **Source type** (Tipo de origem), escolha **Custom** (Personalizado) e cole o ID do grupo de segurança que você copiou no campo.

   1. Escolha **Adicionar regra**.

   1. Para **Tipo**, escolha **SSH**.

   1. Para **Source type** (Tipo de origem), escolha **Anywhere-IPv4** (IPv4 em qualquer lugar).

   1. Selecione **Salvar regras**.

1. Na lista, selecione o grupo de segurança e escolha **Actions** (Ações), **Edit outbound rules** (Editar regras de saída), e faça o seguinte:

   1. Escolha **Adicionar regra**.

   1. Para **Tipo**, escolha **Todo o tráfego**.

   1. Para **Destination** (Destino), escolha **Custom** (Personalizado) e cole o ID do grupo de segurança que você copiou no campo.

   1. Selecione **Salvar regras**.

## Etapa 2: Iniciar uma instância temporária
<a name="nixl-start-base-temp"></a>

Execute uma instância temporária que é possível usar para instalar e configurar os componentes do software EFA. Você usa essa instância para criar um AMI habilitado para EFA a partir do qual é possível executar suas instâncias habilitadas para EFA.

**Para executar uma instância temporária**

1. Abra o console do Amazon EC2 em [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. No painel de navegação, selecione **Instances** (Instâncias) e, depois, escolha **Launch Instances** (Iniciar instâncias) para abrir o novo assistente de inicialização de instância.

1. (*Opcional*) Na seção **Name and tags** (Nome e etiquetas), forneça um nome para a instância, como `EFA-instance`. O nome é atribuído à instância como uma etiqueta de recurso (`Name={{EFA-instance}}`).

1. Na seção **Application and OS Images** (Imagens de aplicação e sistema operacional), selecione uma AMI para um dos sistemas operacionais compatíveis. Você também pode selecionar uma DLAMI compatível encontrada na [Página de notas de versão de DLAMIs](https://docs.aws.amazon.com/dlami/latest/devguide/appendix-ami-release-notes).

1. Na seção **Instance type** (Tipo de instância), selecione um tipo de instância compatível.

1. Na seção **Key pair** (Par de chaves), selecione o par de chaves a ser usado na instância.

1. Na seção **Network settings** (Configurações da rede), escolha **Edit** (Editar) e faça o seguinte:

   1. Em **Subnet (Sub-rede)**, escolha a sub-rede na qual deseja iniciar a instância. Se você não selecionar uma sub-rede, não será possível habilitar a instância para o EFA.

   1. Para **Firewall (security groups)** (Firewall/grupos de segurança), escolha **Select existing security group** (Selecione grupo de segurança existente) e, em seguida, selecione o grupo de segurança que você criou na etapa anterior.

   1. Expanda a seção **Configuração de rede avançada**.

      Para **Interface de rede 1**, selecione **Índice da placa de rede = 0**, **Índice do dispositivo = 0** e **Tipo de interface = EFA com ENA**.

      **(*Opcional*) Se você estiver usando um tipo de instância com várias placas, como `p4d.24xlarge` ou`p5.48xlarge`, para cada interface de rede adicional necessária, escolha **Adicionar interface de rede**, em **Índice da placa de rede, selecione o próximo índice** não utilizado e, em seguida, selecione **Índice do dispositivo = 1** e **Tipo de interface = EFA com ENA** ou somente EFA.**.

1. Na seção **Storage** (Armazenamento), configure os volumes conforme necessário.
**nota**  
É necessário provisionar um armazenamento adicional de 10 a 20 GiB para o Toolkit Nvidia CUDA. Se você não provisionar armazenamento suficiente, você receberá uma mensagem de erro `insufficient disk space` ao tentar instalar os drivers Nvidia e o Toolkit CUDA.

1. No painel **Summary** (Resumo) painel, escolha **Launch instance** (Iniciar instância).

**Importante**  
Pule a etapa 3 se sua AMI já incluir drivers de GPU da Nvidia, o kit de ferramentas CUDA e o cuDNN, ou se você estiver usando uma instância sem GPU.

## Etapa 3: Instalar drivers de GPU Nvidia, o toolkit Nvidia CUDA e o cuDNN
<a name="nixl-start-base-drivers"></a>

**Para instalar os drivers de GPU Nvidia, o toolkit Nvidia CUDA e o cuDNN**

1. Para garantir que todos os pacotes de software estejam atualizados, execute uma atualização rápida de software em sua instância.

   ```
   $ sudo apt-get update && sudo apt-get upgrade -y
   ```

1. Instale os utilitários necessários para instalar os drivers de GPU Nvidia e o toolkit Nvidia CUDA.

   ```
   $ sudo apt-get install build-essential -y
   ```

1. Para usar o driver de GPU Nvidia, é necessário primeiro desabilitar os drivers de código aberto `nouveau`.

   1. Instale os utilitários necessários e o pacote de cabeçalhos kernel para a versão do kernel que está sendo executada.

      ```
      $ sudo apt-get install -y gcc make linux-headers-$(uname -r)
      ```

   1. Adicione `nouveau` ao arquivo de lista de negação `/etc/modprobe.d/blacklist.conf `.

      ```
      $ cat << EOF | sudo tee --append /etc/modprobe.d/blacklist.conf
      blacklist vga16fb
      blacklist nouveau
      blacklist rivafb
      blacklist nvidiafb
      blacklist rivatv
      EOF
      ```

   1. Abra o `/etc/default/grub` usando o editor de texto de sua preferência e adicione o seguinte.

      ```
      GRUB_CMDLINE_LINUX="rdblacklist=nouveau"
      ```

   1. Recompile a configuração do Grub.

      ```
      $ sudo update-grub
      ```

1. Reinicialize a instância e reconecte-se a ela.

1. Adicione o repositório CUDA e instale os drivers de GPU Nvidia, o toolkit Nvidia CUDA e o cuDNN.

   ```
   $ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2004/x86_64/7fa2af80.pub \
   && wget -O /tmp/deeplearning.deb http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2004/x86_64/nvidia-machine-learning-repo-ubuntu2004_1.0.0-1_amd64.deb \
   && sudo dpkg -i /tmp/deeplearning.deb \
   && wget -O /tmp/cuda.pin https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pin \
   && sudo mv /tmp/cuda.pin /etc/apt/preferences.d/cuda-repository-pin-600 \
   && sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub \
   && sudo add-apt-repository 'deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/ /' \
   && sudo apt update \
   && sudo apt install nvidia-dkms-535 \
   && sudo apt install -o Dpkg::Options::='--force-overwrite' cuda-drivers-535 cuda-toolkit-12-3 libcudnn8 libcudnn8-dev -y
   ```

1. Reinicialize a instância e reconecte-se a ela.

1. (Somente `p4d.24xlarge` e `p5.48xlarge`) Instale o Nvidia Fabric Manager.

   1. É necessário instalar a versão do Nvidia Fabric Manager que corresponde à versão do módulo do kernel Nvidia que você instalou na etapa anterior.

      Execute o seguinte comando para determinar a versão do módulo do kernel Nvidia.

      ```
      $ cat /proc/driver/nvidia/version | grep "Kernel Module"
      ```

      A seguir está um exemplo de saída.

      ```
      NVRM version: NVIDIA UNIX x86_64 Kernel Module  450.42.01  Tue Jun 15 21:26:37 UTC 2021
      ```

      No exemplo acima, a versão principal`450`do módulo do kernel foi instalado. Isso significa que você precisa instalar a versão do Nvidia Fabric Manager `450`.

   1. Instale o Nvidia Fabric Manager. Execute o seguinte comando e especifique a versão principal identificada na etapa anterior.

      ```
      $ sudo apt install -o Dpkg::Options::='--force-overwrite' nvidia-fabricmanager-{{major_version_number}}
      ```

      Por exemplo, se a versão principal`450`do módulo do kernel foi instalado, use o seguinte comando para instalar a versão correspondente do Nvidia Fabric Manager.

      ```
      $ sudo apt install -o Dpkg::Options::='--force-overwrite' nvidia-fabricmanager-450
      ```

   1. Inicie o serviço e certifique-se de que ele seja iniciado automaticamente quando a instância for executada. O Nvidia Fabric Manager é necessário para o gerenciamento do NV Switch.

      ```
      $ sudo systemctl start nvidia-fabricmanager && sudo systemctl enable nvidia-fabricmanager
      ```

1. Certifique-se de que os caminhos do CUDA sejam definidos cada vez que a instância for executada.
   + Em shells *bash*, adicione as seguintes instruções a `/home/{{username}}/.bashrc` e `/home/{{username}}/.bash_profile`.

     ```
     export PATH=/usr/local/cuda/bin:$PATH
     export LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH
     ```
   + Em shells *tcsh*, adicione as seguintes instruções a `/home/{{username}}/.cshrc`.

     ```
     setenv PATH=/usr/local/cuda/bin:$PATH
     setenv LD_LIBRARY_PATH=/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH
     ```

1. Para verificar se os drivers de GPU Nvidia estão funcionando, execute o comando a seguir.

   ```
   $ nvidia-smi -q | head
   ```

   O comando deve retornar informações sobre os as GPUs Nvidia, sobre os drivers de GPU Nvidia e sobre o toolkit Nvidia CUDA.

**Importante**  
Pule a etapa 4 se sua AMI já incluir o GDRCopy ou se você estiver usando uma instância sem GPU.

## Etapa 4: instalar o GDRCopy
<a name="nixl-start-base-gdrcopy"></a>

Instale o GDRCopy para melhorar a performance do Libfabric em plataformas baseadas em GPU. Para obter mais informações sobre a GDRCopy, consulte o [repositório do GDRCopy](https://github.com/NVIDIA/gdrcopy).

**Para instalar o GDRCopy**

1. Instale as dependências necessárias.

   ```
   $ sudo apt -y install build-essential devscripts debhelper check libsubunit-dev fakeroot pkg-config dkms
   ```

1. Baixe e extraia o pacote do GDRCopy.

   ```
   $ wget https://github.com/NVIDIA/gdrcopy/archive/refs/tags/v2.4.tar.gz \
   && tar xf v2.4.tar.gz \
   && cd gdrcopy-2.4/packages
   ```

1. Compile os pacotes DEB do GDRCopy.

   ```
   $ CUDA=/usr/local/cuda ./build-deb-packages.sh
   ```

1. Instale os pacotes DEB do GDRCopy.

   ```
   $ sudo dpkg -i gdrdrv-dkms_2.4-1_amd64.*.deb \
   && sudo dpkg -i libgdrapi_2.4-1_amd64.*.deb \
   && sudo dpkg -i gdrcopy-tests_2.4-1_amd64.*.deb \
   && sudo dpkg -i gdrcopy_2.4-1_amd64.*.deb
   ```

**Importante**  
Pule a etapa 5 se sua AMI já incluir o instalador mais recente do EFA.

## Etapa 5: instalar o software EFA
<a name="nixl-start-base-enable"></a>

Instale o kernel habilitado para EFA, os drivers EFA, e a pilha do Libfabric necessários para oferecer suporte a EFA em sua instância.

**Como instalar o software EFA**

1. Conecte à instância que você iniciou. Para obter mais informações, consulte [Conectar-se à instância do Linux usando SSH](connect-to-linux-instance.md).

1. Faça download dos arquivos de instalação do software do EFA. Os arquivos de instalação do software são empacotados em um arquivo compactado tarball (`.tar.gz`). Para fazer download da última versão *estável*, use o seguinte comando:

   ```
   $ curl -O https://efa-installer.amazonaws.com/aws-efa-installer-1.48.0.tar.gz
   ```

1. Extraia os arquivos do arquivo `.tar.gz` compactado e navegue para o diretório extraído.

   ```
   $ tar -xf aws-efa-installer-1.48.0.tar.gz && rm -rf aws-efa-installer-1.48.0.tar.gz && cd aws-efa-installer
   ```

1. (*Opcional*) Verifique as assinaturas de pacotes individuais durante a instalação.

   A partir do EFA 1.48.0, o instalador inclui pacotes individuais RPM e DEB assinados com GPG. Para verificar a autenticidade e a integridade de cada pacote individual durante a instalação, use o sinalizador `--check-signatures`. Quando você habilita esse sinalizador, o instalador verifica primeiro todas as assinaturas de pacotes e prossegue com a instalação somente se cada pacote for aprovado na verificação. Se algum pacote não for aprovado na verificação, o instalador sairá imediatamente sem instalar nada.

   1. Baixe a chave pública.

      ```
      $ wget https://efa-installer.amazonaws.com/aws-efa-installer.key
      ```

   1. Exporte o caminho principal. Em seguida, na próxima etapa, anexe `--check-signatures` ao comando de instalação e use `sudo -E` em vez de `sudo` para preservar a variável de ambiente.

      ```
      $ export EFA_INSTALLER_KEY=$(pwd)/aws-efa-installer.key
      ```

   Em sistemas baseados em RPM (Amazon Linux, RHEL, Rocky Linux e SUSE), o instalador verifica cada RPM usando `rpm --checksig`. Em sistemas baseados em DEB (Ubuntu, Debian), o instalador verifica cada DEB usando a verificação de assinatura GPG.

   Se houver falha na verificação de algum pacote, a instalação será interrompida imediatamente, protegendo seu sistema contra pacotes danificados ou maliciosos.
**nota**  
O sinalizador `--check-signatures` é opcional. Sem isso, o instalador não realiza a verificação de assinaturas individuais.

1. Execute o script de instalação do software EFA.
**nota**  
Se você concluiu a etapa opcional anterior para configurar a verificação de assinaturas de pacotes, acrescente `--check-signatures` ao comando de instalação e use `sudo -E` em vez de `sudo`. Por exemplo: `sudo -E ./efa_installer.sh -y --check-signatures`.

   ```
   $ sudo ./efa_installer.sh -y
   ```

   O **Libfabric** está instalado no diretório `/opt/amazon/efa`.

1. Se o instalador do EFA solicitar que você reinicialize a instância, faça-o e, em seguida, reconecte-se à instância. Caso contrário, faça logout da instância e faça login novamente para concluir a instalação.

1. Confirme se os componentes do software EFA foram instalados com sucesso.

   ```
   $ fi_info -p efa -t FI_EP_RDM
   ```

   O comando deve retornar informações sobre as interfaces EFA Libfabric. O exemplo a seguir mostra a saída do comando.
   + `p3dn.24xlarge` com interface de rede única

     ```
     provider: efa
     fabric: EFA-fe80::94:3dff:fe89:1b70
     domain: efa_0-rdm
     version: 2.0
     type: FI_EP_RDM
     protocol: FI_PROTO_EFA
     ```
   + `p4d.24xlarge` e `p5.48xlarge` com várias interfaces de rede

     ```
     provider: efa
     fabric: EFA-fe80::c6e:8fff:fef6:e7ff
     domain: efa_0-rdm
     version: 111.0
     type: FI_EP_RDM
     protocol: FI_PROTO_EFA
     provider: efa
     fabric: EFA-fe80::c34:3eff:feb2:3c35
     domain: efa_1-rdm
     version: 111.0
     type: FI_EP_RDM
     protocol: FI_PROTO_EFA
     provider: efa
     fabric: EFA-fe80::c0f:7bff:fe68:a775
     domain: efa_2-rdm
     version: 111.0
     type: FI_EP_RDM
     protocol: FI_PROTO_EFA
     provider: efa
     fabric: EFA-fe80::ca7:b0ff:fea6:5e99
     domain: efa_3-rdm
     version: 111.0
     type: FI_EP_RDM
     protocol: FI_PROTO_EFA
     ```

## Etapa 6: instalar a NIXL
<a name="nixl-start-base-nixl"></a>

Instale a NIXL. Para obter mais informações sobre a NIXL, consulte o [Repositório da NCCL](https://github.com/ai-dynamo/nixl).

------
#### [ Pre-built distributions ]

**Para instalar a NIXL usando PyPI**

1. Instale as dependências necessárias.

   ```
   $ sudo apt install pip
   ```

1. Instale a NIXL.

   ```
   $ pip install nixl
   ```

------
#### [ Build from source ]

**Para compilar e instalar usando o código-fonte**

1. Instale as dependências necessárias.

   ```
   $ sudo apt install cmake pkg-config meson pybind11-dev libaio-dev nvidia-cuda-toolkit pip libhwloc-dev \
   && pip install meson ninja pybind11
   ```

1. Navegue até o diretório inicial.

   ```
   $ cd $HOME
   ```

1. Clone o repositório oficial da NIXL para a instância e navegue até o repositório local clonado.

   ```
   $ sudo git clone https://github.com/ai-dynamo/nixl.git && cd nixl
   ```

1. Compile e instale a NIXL e especifique o caminho para o diretório de instalação do Libfabric.

   ```
   $ sudo meson setup . nixl --prefix=/usr/local/nixl -Dlibfabric_path=/opt/amazon/efa
   $ cd nixl && sudo ninja && sudo ninja install
   ```

------

## Etapa 7: instalar o NIXL Benchmark e testar sua configuração de EFA e NIXL
<a name="nixl-start-base-tests"></a>

Instale o NIXL Benchmark e execute um teste para verificar se a instância temporária está configurada adequadamente para o EFA e para a NIXL. O NIXL Benchmark permite confirmar se a NIXL está instalada adequadamente se ela está funcionando conforme esperado. Para obter mais informações, consulte o [Repositório do nixlbench](https://github.com/ai-dynamo/nixl/tree/main/benchmark/nixlbench).

O NIXL Benchmark (nixlbench) requer ETCD para coordenação entre cliente e servidor. Para usar o ETCD com NIXL, é necessário o ETCD Server and Client e a API ETCD CPP.

------
#### [ Build from Docker ]

**Para instalar e testar o NIXL Benchmark usando o Docker**

1. Clone o repositório oficial da NIXL para a instância e navegue até o diretório de compilação do nixlbench.

   ```
   $ git clone https://github.com/ai-dynamo/nixl.git
   $ cd nixl/benchmark/nixlbench/contrib
   ```

1. Crie o contêiner.

   ```
   $ ./build.sh
   ```

   Para obter mais informações sobre as opções de compilação do Docker, consulte o [Repositório do nixlbench](https://github.com/ai-dynamo/nixl/tree/main/benchmark/nixlbench).

1. Instalar o Docker.

   ```
   $ sudo apt install docker.io -y
   ```

1. Inicie o servidor ETCD para coordenação.

   ```
   $ docker run -d --name etcd-server \
       -p 2379:2379 -p 2380:2380 \
       quay.io/coreos/etcd:v3.5.18 \
       /usr/local/bin/etcd \
       --data-dir=/etcd-data \
       --listen-client-urls=http://0.0.0.0:2379 \
       --advertise-client-urls=http://0.0.0.0:2379 \
       --listen-peer-urls=http://0.0.0.0:2380 \
       --initial-advertise-peer-urls=http://0.0.0.0:2380 \
       --initial-cluster=default=http://0.0.0.0:2380
   ```

1. Valide se o servidor ETCD está em execução.

   ```
   $ curl -L http://localhost:2379/health
   ```

   Saída esperada:

   ```
   {"health":"true"}
   ```

1. Abra dois terminais para a instância. Em ambos os terminais, execute o comando a seguir para verificar a instalação. O comando usa o servidor ETCD na mesma instância, usa o Libfabric como backend e opera usando memória da GPU.

   ```
   $ docker run -it --gpus all --network host nixlbench:latest \
       nixlbench --etcd_endpoints http://localhost:2379 \
       --backend LIBFABRIC \
       --initiator_seg_type VRAM \
       --target_seg_type VRAM
   ```
**nota**  
Use o valor `DRAM` em vez de `VRAM` para instâncias sem GPU.

------
#### [ Build from source ]

**Importante**  
Siga essa guia somente se você escolher **Compilar do código-fonte** na Etapa 6.

**Para instalar o NIXL Benchmark**

1. Instale as dependências do sistema necessárias.

   ```
   $ sudo apt install libgflags-dev
   ```

1. Instale o servidor e o cliente ETCD.

   ```
   $ sudo apt install -y etcd-server etcd-client
   ```

1. Instale a API ETCD CPP.

   1. Instale as dependências necessárias para a API ETCD CPP.

      ```
      $ sudo apt install libboost-all-dev libssl-dev libgrpc-dev libgrpc++-dev libprotobuf-dev protobuf-compiler-grpc libcpprest-dev
      ```

   1. Clone e instale a API ETCD CPP.

      ```
      $ cd $HOME
      $ git clone https://github.com/etcd-cpp-apiv3/etcd-cpp-apiv3.git
      $ cd etcd-cpp-apiv3
      $ mkdir build && cd build
      $ cmake ..
      $ sudo make -j$(nproc) && sudo make install
      ```

1. Compile e instale o nixlbench.

   ```
   $ sudo meson setup . $HOME/nixl/benchmark/nixlbench -Dnixl_path=/usr/local/nixl/
   $ sudo ninja && sudo ninja install
   ```

**Como testar a configuração do EFA e da NIXL**

1. Inicie o servidor ETCD na instância.

   ```
   $ etcd --listen-client-urls "http://0.0.0.0:2379" \
       --advertise-client-urls "http://localhost:2379" &
   ```

1. Valide se o servidor ETCD está em execução.

   ```
   $ curl -L http://localhost:2379/health
   ```

   Saída esperada:

   ```
   {"health":"true"}
   ```

1. Abra dois terminais para a instância. Em ambos os terminais, conclua as etapas a seguir para executar o nixlbench.

   1. Navegue até o diretório em que o nixlbench está instalado.

      ```
      $ cd /usr/local/nixlbench/bin/
      ```

   1. Execute o teste e especifique o backend, o endereço do servidor ETCD e o tipo de segmento iniciador. O comando a seguir usa o servidor ETCD na mesma instância, usa o Libfabric como backend e opera usando memória da GPU. As variáveis de ambiente configuram o seguinte:
      + `NIXL_LOG_LEVEL=INFO`: habilita a saída de depuração detalhada. Também é possível especificar `WARN` para receber somente mensagens de erro.
      + `LD_LIBRARY_PATH`: define o caminho para a biblioteca NIXL.

      Para obter mais informações sobre os argumentos de NIXL Benchmark, consulte o [README do NIXLbench](https://github.com/ai-dynamo/nixl/blob/main/benchmark/nixlbench/README.md) no repositório oficial do nixlbench.

      ```
      $ export NIXL_LOG_LEVEL=INFO
      $ export LD_LIBRARY_PATH=/usr/local/nixl/lib/$(gcc -dumpmachine):$LD_LIBRARY_PATH
      
      $ nixlbench --etcd-endpoints 'http://localhost:2379' \
          --backend 'LIBFABRIC' \
          --initiator_seg_type 'VRAM' \
          --target_seg_type 'VRAM'
      ```
**nota**  
Use o valor `DRAM` em vez de `VRAM` para instâncias sem GPU.

------

## Etapa 8: Instalar os aplicativos de machine learning
<a name="nixl-start-base-app"></a>

Instale as aplicações de machine learning na instância temporária. O procedimento de instalação varia dependendo da aplicação de machine learning específica.

**nota**  
Talvez seja necessário consultar a documentação da aplicação de machine learning para obter instruções de instalação.

## Etapa 9: criar um EFA e uma AMI habilitada para NIXL
<a name="nixl-start-base-ami"></a>

Depois de instalar os componentes de software necessários, crie uma AMI que possa ser reutilizada para executar suas instâncias habilitadas para o EFA.

**Para criar uma AMI a partir de sua instância temporária**

1. Abra o console do Amazon EC2 em [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. No painel de navegação, escolha **Instances (Instâncias)**.

1. Selecione a instância, escolha **Actions** (Ações), **Image** (Imagem), **Create image** (Criar imagem).

1. Em **Create image (Criar imagem)**, faça o seguinte:

   1. Em **Image name (Nome da imagem)**, insira um nome descritivo para a AMI.

   1. (Opcional) Em **Image description (Descrição da imagem)**, informe a descrição do propósito da AMI.

   1. Escolha **Create Image (Criar imagem)**.

1. No painel de navegação, selecione **AMIs**.

1. Encontre a AMI que você criou na lista. Aguarde até que o status mude de `pending` para `available` antes de continuar para a próxima etapa.

## Etapa 10: Encerrar a instância temporária
<a name="nixl-start-base-terminate"></a>

Neste ponto, você não precisa mais da instância temporária que você executou. É possível encerrar a instância para não incorrer mais em cobranças desnecessárias.

**Para encerrar a instância temporária**

1. Abra o console do Amazon EC2 em [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. No painel de navegação, escolha **Instances (Instâncias)**.

1. Selecione a instância temporária, escolha **Actions (Ações)**, selecione **Instance state (Estado da instância)**, **Terminate instance (Encerrar instance)**.

1. Quando a confirmação for solicitada, escolha **Terminate (Encerrar)**.

## Etapa 11: executar instâncias habilitadas para EFA e NIXL
<a name="nixl-start-base-cluster"></a>

Execute as instâncias habilitadas para EFA e NIXL usando a AMI habilitada para EFA que você criou na **Etapa 9** e o grupo de segurança habilitado para EFA que você criou na **Etapa 1**.

**Para executar as instâncias habilitadas para EFA e NIXL**

1. Abra o console do Amazon EC2 em [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/).

1. No painel de navegação, selecione **Instances** (Instâncias) e, depois, escolha **Launch Instances** (Iniciar instâncias) para abrir o novo assistente de inicialização de instância.

1. (*Opcional*) Na seção **Name and tags** (Nome e etiquetas), forneça um nome para a instância, como `EFA-instance`. O nome é atribuído à instância como uma etiqueta de recurso (`Name={{EFA-instance}}`).

1. Na seção **Application and OS Images** (Imagens de aplicações e SO), selecione **My AMIs** (Minhas AMIs) e, em seguida, selecione a AMI que você criou na etapa anterior.

1. Na seção **Instance type** (Tipo de instância), selecione um tipo de instância compatível.

1. Na seção **Key pair** (Par de chaves), selecione o par de chaves a ser usado na instância.

1. Na seção **Network settings** (Configurações da rede), escolha **Edit** (Editar) e faça o seguinte:

   1. Em **Subnet (Sub-rede)**, escolha a sub-rede na qual deseja iniciar a instância. Se você não selecionar uma sub-rede, não será possível habilitar a instância para o EFA.

   1. Em **Firewall (grupos de segurança)**, escolha **Selecionar grupo de segurança existente** e, em seguida, selecione o grupo de segurança que você criou na **Etapa 1**.

   1. Expanda a seção **Configuração de rede avançada**.

      Para **Interface de rede 1**, selecione **Índice da placa de rede = 0**, **Índice do dispositivo = 0** e **Tipo de interface = EFA com ENA**.

      (*Opcional*) Caso esteja usando um tipo de instância com várias placas, como `p4d.24xlarge` ou `p5.48xlarge`, para cada interface de rede adicional necessária, selecione **Adicionar interface de rede**, em **Índice da placa de rede**, selecione o próximo índice não utilizado e, em seguida, selecione **Índice do dispositivo = 1** e **Tipo de interface = EFA com ENA** ou **exclusivamente EFA**.

1. (*Opcional*) Na seção **Storage** (Armazenamento), configure os volumes conforme necessário.

1. No painel **Summary** (Resumo) à direita, em **Number of instances** (Número de instâncias), insira o número de instâncias habilitadas para EFA que você deseja iniciar e escolha **Launch instance** (Iniciar instância).

## Etapa 12: habilitar SSH sem senha
<a name="nixl-start-base-passwordless"></a>

Para permitir que suas aplicações sejam executadas em todas as instâncias do cluster, é necessário habilitar o acesso SSH sem senha do nó líder para os nós membros. O nó líder é a instância a partir da qual você executa suas aplicações. As instâncias restantes no cluster são os nós membros.

**Para habilitar SSH sem senha entre as instâncias no cluster**

1. Selecione uma instância no cluster como o nó líder e conecte-se a ela.

1. Desabilite `strictHostKeyChecking` e habilite `ForwardAgent` no nó líder. Abra o `~/.ssh/config` usando o editor de texto de sua preferência e adicione o seguinte.

   ```
   Host *
       ForwardAgent yes
   Host *
       StrictHostKeyChecking no
   ```

1. Gere um par de chaves RSA.

   ```
   $ ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
   ```

   O par de chaves é criado no diretório do `$HOME/.ssh/`.

1. Altere as permissões da chave privada no nó líder.

   ```
   $ chmod 600 ~/.ssh/id_rsa
   chmod 600 ~/.ssh/config
   ```

1. Abra `~/.ssh/id_rsa.pub` usando seu editor de texto preferido e copie a chave.

1. Para cada nó de membro no cluster, faça o seguinte:

   1. Conecte-se à instância.

   1. Abra `~/.ssh/authorized_keys` usando o editor de texto de sua preferência e adicione a chave pública que você copiou anteriormente.

1. Para testar se o SSH sem senha está funcionando como esperado, conecte-se ao seu nó líder e execute o comando a seguir.

   ```
   $ ssh {{member_node_private_ip}}
   ```

   É necessário se conectar ao nó membro sem receber uma solicitação para inserir uma chave ou senha.

**Importante**  
Siga a Etapa 13 somente se você seguiu a Etapa 7.

## Etapa 13: testar a configuração do EFA e da NIXL em todas as instâncias
<a name="nixl-start-base-test-multi"></a>

Execute um teste para verificar se as instâncias estão configuradas adequadamente para EFA e para NIXL.

------
#### [ Build from Docker ]

**Para testar a configuração do EFA e da NIXL em todas as instâncias usando o Docker**

1. Selecione dois hosts para executar o nixlbench benchmark. Use o endereço IP do primeiro host como o IP do servidor ETCD para troca de metadados.

1. Inicie o servidor ETCD no host 1.

   ```
   $ docker run -d --name etcd-server \
       -p 2379:2379 -p 2380:2380 \
       quay.io/coreos/etcd:v3.5.18 \
       /usr/local/bin/etcd \
       --data-dir=/etcd-data \
       --listen-client-urls=http://0.0.0.0:2379 \
       --advertise-client-urls=http://0.0.0.0:2379 \
       --listen-peer-urls=http://0.0.0.0:2380 \
       --initial-advertise-peer-urls=http://0.0.0.0:2380 \
       --initial-cluster=default=http://0.0.0.0:2380
   ```

1. Valide se o servidor ETCD está em execução.

   ```
   $ curl -L http://localhost:2379/health
   ```

   ```
   {"health":"true"}
   ```

1. Execute o nixlbench benchmark no host 1.

   ```
   $ docker run -it --gpus all --network host nixlbench:latest \
       nixlbench --etcd_endpoints http://localhost:2379 \
       --backend LIBFABRIC \
       --initiator_seg_type VRAM
   ```

1. Execute o nixlbench benchmark no host 2.

   ```
   $ docker run -it --gpus all --network host nixlbench:latest \
       nixlbench --etcd_endpoints http://{{ETCD_SERVER_IP}}:2379 \
       --backend LIBFABRIC \
       --initiator_seg_type VRAM
   ```

------
#### [ Build from source ]

**Importante**  
Siga essa guia somente se você escolher **Compilar do código-fonte** na Etapa 6.

**Para testar a configuração do EFA e da NIXL em todas as instâncias**

1. Selecione dois hosts para executar o nixlbench benchmark. Use o endereço IP do primeiro host como o IP do servidor ETCD para troca de metadados.

1. Execute o servidor ETCD no host 1.

   ```
   $ etcd --listen-client-urls "http://0.0.0.0:2379" \
       --advertise-client-urls "http://localhost:2379" &
   ```

1. Valide se o servidor ETCD está em execução.

   ```
   $ curl -L http://localhost:2379/health
   ```

   ```
   {"health":"true"}
   ```

1. Execute o nixlbench benchmark no host 1.

   ```
   $ export NIXL_LOG_LEVEL=INFO
   $ export LD_LIBRARY_PATH=$HOME/nixl/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
   
   $ nixlbench \
       --etcd-endpoints http://localhost:2379 \
       --backend LIBFABRIC \
       --initiator_seg_type VRAM
   ```

1. Execute o nixlbench benchmark no host 2.

   ```
   $ export NIXL_LOG_LEVEL=INFO
   $ export LD_LIBRARY_PATH=$HOME/nixl/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
   
   $ nixlbench \
       --etcd-endpoints http://{{ETCD_SERVER_IP}}:2379 \
       --backend LIBFABRIC \
       --initiator_seg_type VRAM
   ```

------

## *Etapa 14: testar o serviço de inferência desagregado no vLLM (opcional)*
<a name="nixl-start-base-serve"></a>

Depois que a NIXL for instalada, você poderá usar a NIXL por meio de inferência e estruturas de serviço do LLM, como vLLM, SGLang e Tensorrt-LLM.

**Para atender à sua workload de inferência usando o vLLM**

1. Instale o vLLM.

   ```
   $ pip install vllm
   ```

1. Execute o servidor vLLM com NIXL. Os exemplos de comandos a seguir criam uma instância de pré-preenchimento (produtor) e uma instância de decodificação (consumidor) para conexão de handshake NIXL, conector KV, perfil KV e backend de transporte. Para exemplos e scripts detalhados, consulte o [Guia de uso do NIXLConnector](https://github.com/vllm-project/vllm/blob/2d977a7a9ead3179fde9ed55d69393ef7b6cec47/docs/features/nixl_connector_usage.md).

   Para usar NIXL com o EFA, defina as variáveis de ambiente com base em sua configuração e caso de uso.
   + Configuração do produtor (pré-preenchedor)

     ```
     $ vllm serve {{your-application}} \
         --port 8200 \
         --enforce-eager \
         --kv-transfer-config '{"kv_connector":"NixlConnector","kv_role":"kv_both","kv_buffer_device":"cuda","kv_connector_extra_config":{"backends":["LIBFABRIC"]}}'
     ```
   + Configuração do consumidor (decodificador)

     ```
     $ vllm serve {{your-application}} \
         --port 8200 \
         --enforce-eager \
         --kv-transfer-config '{"kv_connector":"NixlConnector","kv_role":"kv_both","kv_buffer_device":"cuda","kv_connector_extra_config":{"backends":["LIBFABRIC"]}}'
     ```

   O exemplo de configuração anterior define o seguinte:
   + `kv_role` como `kv_both`, que permite uma funcionalidade simétrica em que o conector pode atuar como produtor e consumidor. Isso fornece flexibilidade para configurações e cenários experimentais em que a distinção de perfis não é predeterminada.
   + `kv_buffer_device` a `cuda`, o que permite o uso da memória da GPU.
   + Backend NIXL para `LIBFABRIC`, o que permite que o tráfego NIXL passe pelo EFA.