

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Elastic Fabric Adapter를 사용한 분산 훈련
<a name="tutorial-efa"></a>

[Elastic Fabric Adapter](https://aws.amazon.com/hpc/efa/)(EFA)는 DLAMI 인스턴스에 연결하여 고성능 컴퓨팅(HPC) 및 기계 학습 애플리케이션의 속도를 높일 수 있는 네트워크 디바이스입니다. EFA를 사용하면 AWS 클라우드에서 제공하는 확장성, 유연성 및 탄력성을 통해 온프레미스 HPC 클러스터의 애플리케이션 성능을 달성할 수 있습니다.

다음 섹션에서는 DLAMI에서 EFA 사용을 시작하는 방법을 보여 줍니다.

**참고**  
이 [기본 GPU DLAMI 목록](appendix-ami-release-notes.md#appendix-ami-release-notes-base)에서 원하는 DLAMI를 선택하세요.

**Topics**
+ [EFA를 사용하여 AWS Deep Learning AMIs 인스턴스 시작](tutorial-efa-launching.md)
+ [DLAMI에서 EFA 사용](tutorial-efa-using.md)

# EFA를 사용하여 AWS Deep Learning AMIs 인스턴스 시작
<a name="tutorial-efa-launching"></a>

최신 버전 Base DLAMI는 EFA와 사용 가능하며, 필수 드라이버, 커널 모듈, libfabric, openmpi 및 GPU 인스턴스용 [NCCL OFI 플러그인](https://github.com/aws/aws-ofi-nccl/tree/aws)이 함께 제공됩니다.

지원되는 Base DLAMI CUDA 버전은 [릴리스 노트](appendix-ami-release-notes.md#appendix-ami-release-notes-base)에서 확인할 수 있습니다.

참고:
+ EFA에서 `mpirun`을 사용하여 NCCL 애플리케이션을 실행할 때 EFA 지원 설치의 전체 경로를 다음과 같이 지정해야 합니다.

  ```
  /opt/amazon/openmpi/bin/mpirun <command>  
  ```
+ 애플리케이션에서 EFA를 사용할 수 있도록 하려면 [DLAMI에서 EFA 사용](tutorial-efa-using.md)에서와 같이 `mpirun` 명령에 `FI_PROVIDER="efa"`를 추가합니다.

**Topics**
+ [EFA 보안 그룹 준비](#tutorial-efa-security-group)
+ [인스턴스 시작](#tutorial-efa-launch)
+ [EFA 연결 확인](#tutorial-efa-verify-attachment)

## EFA 보안 그룹 준비
<a name="tutorial-efa-security-group"></a>

EFA에는 보안 그룹 자체 내의 모든 인바운드 및 아웃바운드 트래픽을 허용하는 보안 그룹이 필요합니다. 자세한 내용은 [EFA 설명서](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-security)를 참조하세요.

1. [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)에서 Amazon EC2 콘솔을 엽니다.

1. 탐색 창에서 **보안 그룹**을 선택한 다음, **보안 그룹 생성**을 선택합니다.

1. **보안 그룹 생성** 창에서 다음을 수행하세요.
   + **보안 그룹 이름**의 경우 `EFA-enabled security group`과 같은 보안 그룹의 고유한 이름을 입력합니다.
   + (선택 사항) **설명**에 보안 그룹에 대한 간략한 설명을 입력합니다.
   + **VPC**에서는 EFA 사용 인스턴스를 시작하려는 VPC를 선택합니다.
   + **생성(Create)**을 선택합니다.

1. 생성한 보안 그룹을 선택하고 **설명** 탭에서 **그룹 ID**를 복사합니다.

1. **인바운드** 및 **아웃바운드** 탭에서 다음을 수행합니다.
   + **편집**을 선택합니다.
   + **유형(Type)**에서 **모든 트래픽(All traffic)**을 선택합니다.
   + **소스(Source)**에서 **사용자 지정(Custom)**을 선택합니다.
   + 복사한 보안 그룹 ID를 필드에 붙여넣습니다.
   + **저장**을 선택합니다.

1. [Linux 인스턴스에 대한 인바운드 트래픽 권한 부여](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html)를 참조하여 인바운드 트래픽을 활성화합니다. 이 단계를 건너뛰면 DLAMI 인스턴스와 통신할 수 없습니다.

## 인스턴스 시작
<a name="tutorial-efa-launch"></a>

의 EFA AWS Deep Learning AMIs 는 현재 다음 인스턴스 유형 및 운영 체제에서 지원됩니다.
+  P3dn: Amazon Linux 2, Ubuntu 20.04
+  P4d, P4de: Amazon Linux 2, Amazon Linux 2023, Ubuntu 20.04, Ubuntu 22.04
+  P5, P5e, P5en: Amazon Linux 2, Amazon Linux 2023, Ubuntu 20.04, Ubuntu 22.04

다음 섹션에서는 EFA 활성화 DLAMI 인스턴스를 시작하는 방법을 설명합니다. EFA 활성화 인스턴스 실행에 대한 자세한 내용은 [클러스터 배치 그룹으로 EFA 활성화 인스턴스 실행](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html#efa-start-instances)을 참조하세요.

1. [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/)에서 Amazon EC2 콘솔을 엽니다.

1. **인스턴스 시작**을 선택합니다.

1. **AMI 선택** 페이지에서 [DLAMI 릴리스 노트 페이지](https://docs.aws.amazon.com/dlami/latest/devguide/appendix-ami-release-notes)에 있는 지원되는 DLAMI를 선택합니다.

1. **인스턴스 유형 선택** 페이지에서 다음과 같이 지원되는 인스턴스 유형 중 하나를 선택하고 **다음: 인스턴스 세부 정보 구성**을 선택합니다. 지원되는 인스턴스 목록은 [EFA 및 MPI 시작](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/efa-start.html) 링크를 참조하세요.

1. [**Configure Instance Details**] 페이지에서 다음을 수행합니다.
   + **인스턴스 수**에 시작할 EFA를 사용한 인스턴스 수를 입력합니다.
   + **네트워크** 및 **서브넷**에서 인스턴스를 시작할 VPC와 서브넷을 선택합니다.
   + [선택 사항] **배치 그룹**에서 **배치 그룹에 인스턴스 추가**를 선택합니다. 최상의 성능을 위해 배치 그룹 내에서 인스턴스를 시작합니다.
   + [선택 사항] **배치 그룹 이름**에서 **새 배치 그룹 추가**를 선택하고 배치 그룹을 설명하는 이름을 입력한 뒤 **배치 그룹 전략**에서 **클러스터**를 선택합니다.
   + 이 페이지에서 **“Elastic Fabric Adapter”**를 활성화해야 합니다. 이 옵션이 비활성화된 경우 선택한 인스턴스 유형을 지원하는 서브넷으로 서브넷을 변경합니다.
   + **네트워크 인터페이스** 항목의 디바이스 **eth0**에서 **새 네트워크 인터페이스**를 선택합니다. 하나의 기본 IPv4 주소와 하나 이상의 보조 IPv4 주소를 입력할 수도 있습니다. 연결된 IPv6 CIDR 블록이 있는 서브넷에서 인스턴스를 시작하는 경우 기본 IPv6 주소 및 하나 이상의 보조 IPv6 주소를 입력할 수도 있습니다.
   + **다음: 스토리지 추가**를 선택합니다.

1. **스토리지 추가** 페이지에서 인스턴스를 연결할 볼륨과 AMI로 지정한 볼륨(루트 디바이스 볼륨 등)을 지정하고 **다음: 태그 추가**를 선택합니다.

1. **태그 추가** 페이지에서 사용자에게 친숙한 이름 등의 인스턴스 태그를 지정한 후 **다음: 보안 그룹 구성(Next: Configure Security Group)**을 선택합니다.

1. **보안 그룹 구성** 페이지의 **보안 그룹 할당**에서 **기존 보안 그룹 선택**을 선택하고 이전에 생성한 보안 그룹을 선택합니다**.**

1. [**검토 및 시작(Review and Launch)**]를 선택합니다.

1. **인스턴스 시작 검토** 페이지에서 설정을 검토한 후 **시작**을 선택하여 키 페어를 선택하고 인스턴스를 시작합니다.

## EFA 연결 확인
<a name="tutorial-efa-verify-attachment"></a>

### 콘솔에서
<a name="tutorial-efa-verify-attachment-console"></a>

인스턴스를 시작한 후 AWS 콘솔에서 인스턴스 세부 정보를 확인합니다. 이렇게 하려면 EC2 콘솔에서 인스턴스를 선택하고 페이지의 아래쪽 창에 있는 설명 탭을 확인합니다. ‘Network Interfaces: eth0’ 매개 변수를 찾아 eth0을 클릭하면 팝업이 열립니다. 'Elastic Fabric Adapter'가 활성화되어 있는지 확인합니다.

EFA가 활성화되지 않은 경우 다음 중 하나를 사용하여 이 문제를 해결할 수 있습니다.
+ EC2 인스턴스를 종료하고 동일한 단계로 새 인스턴스를 시작합니다. EFA가 연결되어 있는지 확인합니다.
+ 기존 인스턴스에 EFA를 연결합니다.

  1. EC2 콘솔에서 네트워크 인터페이스로 이동합니다.

  1. Create a Network Interface(네트워크 인터페이스 생성)를 클릭합니다.

  1. 인스턴스가 있는 서브넷과 동일한 서브넷을 선택합니다.

  1. ‘Elastic Fabric Adapter’를 활성화하고 생성을 클릭합니다.

  1. EC2 인스턴스 탭으로 돌아가서 인스턴스를 선택합니다.

  1. 작업: 인스턴스 상태로 이동하여 EFA를 연결하기 전에 인스턴스를 중지합니다.

  1. 작업에서 네트워킹: Networking: Attach Network Interface(네트워크 인터페이스 연결)를 선택합니다.

  1. 방금 생성한 인터페이스를 선택하고 연결을 클릭합니다.

  1. 인스턴스를 재시작합니다.

### 인스턴스에서
<a name="tutorial-efa-verify-attachment-instance"></a>

다음 테스트 스크립트가 DLAMI에 이미 표시됩니다. 이를 실행하여 커널 모듈이 올바르게 로드되었는지 확인합니다.

```
$ fi_info -p efa
```

출력은 다음과 비슷한 형태가 됩니다.

```
provider: efa
    fabric: EFA-fe80::e5:56ff:fe34:56a8
    domain: efa_0-rdm
    version: 2.0
    type: FI_EP_RDM
    protocol: FI_PROTO_EFA
provider: efa
    fabric: EFA-fe80::e5:56ff:fe34:56a8
    domain: efa_0-dgrm
    version: 2.0
    type: FI_EP_DGRAM
    protocol: FI_PROTO_EFA
provider: efa;ofi_rxd
    fabric: EFA-fe80::e5:56ff:fe34:56a8
    domain: efa_0-dgrm
    version: 1.0
    type: FI_EP_RDM
    protocol: FI_PROTO_RXD
```

### 보안 그룹 구성 확인
<a name="tutorial-efa-verify-attachment-security"></a>

다음 테스트 스크립트가 DLAMI에 이미 표시됩니다. 이를 실행하여 생성한 보안 그룹이 올바르게 구성되었는지 확인합니다.

```
$ cd /opt/amazon/efa/test/ 
$ ./efa_test.sh
```

출력은 다음과 비슷한 형태가 됩니다.

```
Starting server...
Starting client...
bytes   #sent   #ack     total       time     MB/sec    usec/xfer   Mxfers/sec
64      10      =10      1.2k        0.02s      0.06    1123.55       0.00
256     10      =10      5k          0.00s     17.66      14.50       0.07
1k      10      =10      20k         0.00s     67.81      15.10       0.07
4k      10      =10      80k         0.00s    237.45      17.25       0.06
64k     10      =10      1.2m        0.00s    921.10      71.15       0.01
1m      10      =10      20m         0.01s   2122.41     494.05       0.00
```

응답이 중단되거나 작업이 완료되지 않으면 보안 그룹에 올바른 인바운드/아웃바운드 규칙이 있는지 확인합니다.

# DLAMI에서 EFA 사용
<a name="tutorial-efa-using"></a>

다음 섹션에서는 EFA를 사용하여 AWS Deep Learning AMIs에서 다중 노드 애플리케이션을 실행하는 방법에 대해 설명합니다.

## EFA를 사용하여 다중 노드 애플리케이션 실행
<a name="tutorial-efa-using-multi-node"></a>

노드 클러스터에서 애플리케이션을 실행하려면 다음 구성이 필요합니다.

**Topics**
+ [암호 없는 SSH 사용](#tutorial-efa-using-multi-node-ssh)
+ [호스트 파일 생성](#tutorial-efa-using-multi-node-hosts)
+ [NCCL 테스트](#tutorial-efa-using-2node)

### 암호 없는 SSH 사용
<a name="tutorial-efa-using-multi-node-ssh"></a>

클러스터의 노드 하나를 리더 노드로 선택합니다. 나머지 노드들을 멤버 노드라고 합니다.

1. 리더 노드에서 RSA 키 페어를 생성합니다.

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

1. 리더 노드에서 프라이빗 키의 사용 권한을 변경합니다.

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

1. 퍼블릭 키를 `~/.ssh/id_rsa.pub`에 복사하고 클러스터 멤버 노드의 `~/.ssh/authorized_keys`에 추가합니다.

1. 이제 프라이빗 IP를 사용하여 리더 노드에서 멤버 노드에 직접 로그인 할 수 있습니다.

   ```
   ssh <member private ip>
   ```

1. 리더 노드에서 \$1 /.ssh/config 파일을 추가하여 strictHostKeyChecking을 비활성화하고 리더 노드에서 에이전트 전달을 활성화합니다.

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

1. Amazon Linux 2 인스턴스의 리더 노드에서 다음 명령을 실행하여 구성 파일에 올바른 권한을 제공합니다.

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

### 호스트 파일 생성
<a name="tutorial-efa-using-multi-node-hosts"></a>

리더 노드에서 클러스터의 노드를 식별하기 위한 호스트 파일을 생성합니다. 호스트 파일에는 클러스터의 각 노드에 대한 항목이 있어야 합니다. 파일 \$1/hosts를 생성하고 다음과 같이 프라이빗 IP를 사용하여 각 노드를 추가합니다.

```
localhost slots=8
<private ip of node 1> slots=8
<private ip of node 2> slots=8
```

### NCCL 테스트
<a name="tutorial-efa-using-2node"></a>

**참고**  
이러한 테스트는 EFA 버전 1.38.0 및 OFI NCCL 플러그인 1.13.2를 사용하여 실행되었습니다.

 다음은 여러 컴퓨팅 노드의 기능과 성능을 모두 테스트하도록 Nvidia에서 제공하는 NCCL 테스트의 하위 집합입니다.

 **지원되는 인스턴스: P3dn, P4, P5, P5e, P5en** 

#### 성능 테스트
<a name="tutorial-efa-using-multinode"></a>

##### P4d.24xlarge에 대한 다중 노드 NCCL 성능 테스트
<a name="tutorial-efa-using-multi-node-performance"></a>

EFA에서 NCCL 성능을 확인하려면 공식 [NCCL-Tests Repo](https://github.com/NVIDIA/nccl-tests.git)에서 사용할 수 있는 표준 NCCL 성능 테스트를 실행합니다. DLAMI는 CUDA XX.X용으로 이미 구축된 이 테스트와 함께 제공됩니다. 마찬가지로 EFA를 사용하여 자체 스크립트를 실행할 수 있습니다.

자체 스크립트를 작성할 때 다음 지침을 참조하세요.
+ EFA에서 NCCL 애플리케이션을 실행하는 동안 예제에서와 같이 mpirun으로의 전체 경로를 사용합니다.
+ 클러스터의 인스턴스 및 GPU 개수에 따라 매개 변수 np와 N을 변경합니다.
+ NCCL\$1DEBUG=INFO 플래그를 추가하고 로그에 EFA 사용법이 "Selected Provider is "EFA로 표시되어 있는지 확인합니다.
+  검증을 위해 구문 분석할 훈련 로그 위치 설정 

  ```
  TRAINING_LOG="testEFA_$(date +"%N").log"
  ```

멤버 노드에서 명령 `watch nvidia-smi`을 사용하여 GPU 사용을 모니터링합니다. 다음 `watch nvidia-smi` 명령은 일반 CUDA xx.x 버전에서만 사용할 수 있으며 인스턴스의 운영 체제에 따라 달라질 수 있습니다. 스크립트에서 CUDA 버전을 교체하여 Amazon EC2 인스턴스에서 사용 가능한 모든 CUDA 버전에 대해 명령을 실행할 수 있습니다.
+ Amazon Linux 2, Amazon Linux 2023:

  ```
   $ /opt/amazon/openmpi/bin/mpirun -n 16 -N 8 \
  -x NCCL_DEBUG=INFO --mca pml ^cm \
  -x LD_LIBRARY_PATH=/usr/local/cuda-xx.x/efa/lib:/usr/local/cuda-xx.x/lib:/usr/local/cuda-xx.x/lib64:/usr/local/cuda-xx.x:/opt/amazon/efa/lib64:/opt/amazon/openmpi/lib64:$LD_LIBRARY_PATH \
  --hostfile hosts --mca btl tcp,self --mca btl_tcp_if_exclude lo,docker0 --bind-to none \
  /usr/local/cuda-xx.x/efa/test-cuda-xx.x/all_reduce_perf -b 8 -e 1G -f 2 -g 1 -c 1 -n 100 | tee ${TRAINING_LOG}
  ```
+ Ubuntu 20.04, Ubuntu 20.04:

  ```
  $ /opt/amazon/openmpi/bin/mpirun -n 16 -N 8 \
  -x NCCL_DEBUG=INFO --mca pml ^cm \
  -x LD_LIBRARY_PATH=/usr/local/cuda-xx.x/efa/lib:/usr/local/cuda-xx.x/lib:/usr/local/cuda-xx.x/lib64:/usr/local/cuda-xx.x:/opt/amazon/efa/lib:/opt/amazon/openmpi/lib:$LD_LIBRARY_PATH \
  --hostfile hosts --mca btl tcp,self --mca btl_tcp_if_exclude lo,docker0 --bind-to none \
  /usr/local/cuda-xx.x/efa/test-cuda-xx.x/all_reduce_perf -b 8 -e 1G -f 2 -g 1 -c 1 -n 100 | tee ${TRAINING_LOG}
  ```

출력은 다음과 같아야 합니다.

```
# nThread 1 nGpus 1 minBytes 8 maxBytes 1073741824 step: 2(factor) warmup iters: 5 iters: 100 agg iters: 1 validation: 1 graph: 0
#
# Using devices
#  Rank  0 Group  0 Pid  33378 on ip-172-31-42-25 device  0 [0x10] NVIDIA A100-SXM4-40GB
#  Rank  1 Group  0 Pid  33379 on ip-172-31-42-25 device  1 [0x10] NVIDIA A100-SXM4-40GB
#  Rank  2 Group  0 Pid  33380 on ip-172-31-42-25 device  2 [0x20] NVIDIA A100-SXM4-40GB
#  Rank  3 Group  0 Pid  33381 on ip-172-31-42-25 device  3 [0x20] NVIDIA A100-SXM4-40GB
#  Rank  4 Group  0 Pid  33382 on ip-172-31-42-25 device  4 [0x90] NVIDIA A100-SXM4-40GB
#  Rank  5 Group  0 Pid  33383 on ip-172-31-42-25 device  5 [0x90] NVIDIA A100-SXM4-40GB
#  Rank  6 Group  0 Pid  33384 on ip-172-31-42-25 device  6 [0xa0] NVIDIA A100-SXM4-40GB
#  Rank  7 Group  0 Pid  33385 on ip-172-31-42-25 device  7 [0xa0] NVIDIA A100-SXM4-40GB
#  Rank  8 Group  0 Pid  30378 on ip-172-31-43-8 device  0 [0x10] NVIDIA A100-SXM4-40GB
#  Rank  9 Group  0 Pid  30379 on ip-172-31-43-8 device  1 [0x10] NVIDIA A100-SXM4-40GB
#  Rank 10 Group  0 Pid  30380 on ip-172-31-43-8 device  2 [0x20] NVIDIA A100-SXM4-40GB
#  Rank 11 Group  0 Pid  30381 on ip-172-31-43-8 device  3 [0x20] NVIDIA A100-SXM4-40GB
#  Rank 12 Group  0 Pid  30382 on ip-172-31-43-8 device  4 [0x90] NVIDIA A100-SXM4-40GB
#  Rank 13 Group  0 Pid  30383 on ip-172-31-43-8 device  5 [0x90] NVIDIA A100-SXM4-40GB
#  Rank 14 Group  0 Pid  30384 on ip-172-31-43-8 device  6 [0xa0] NVIDIA A100-SXM4-40GB
#  Rank 15 Group  0 Pid  30385 on ip-172-31-43-8 device  7 [0xa0] NVIDIA A100-SXM4-40GB
ip-172-31-42-25:33385:33385 [7] NCCL INFO cudaDriverVersion 12060
ip-172-31-43-8:30383:30383 [5] NCCL INFO Bootstrap : Using ens32:172.31.43.8
ip-172-31-43-8:30383:30383 [5] NCCL INFO NCCL version 2.23.4+cuda12.5
...
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Initializing aws-ofi-nccl 1.13.2-aws
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Using Libfabric version 1.22
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Using CUDA driver version 12060 with runtime 12050
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Configuring AWS-specific options
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting provider_filter to efa
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting FI_EFA_FORK_SAFE environment variable to 1
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting NCCL_NVLSTREE_MAX_CHUNKSIZE to 512KiB
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Setting NCCL_NVLS_CHUNKSIZE to 512KiB
ip-172-31-42-25:33384:33451 [6] NCCL INFO NET/OFI Running on p4d.24xlarge platform, Setting NCCL_TOPO_FILE environment variable to /opt/amazon/ofi-nccl/share/aws-ofi-nccl/xml/p4d-24xl-topo.xml
...
-----------------------------some output truncated-----------------------------------
#                                                              out-of-place                       in-place          
#       size         count      type   redop    root     time   algbw   busbw #wrong     time   algbw   busbw #wrong
#        (B)    (elements)                               (us)  (GB/s)  (GB/s)            (us)  (GB/s)  (GB/s)       
           8             2     float     sum      -1    180.3    0.00    0.00      0    179.3    0.00    0.00      0
          16             4     float     sum      -1    178.1    0.00    0.00      0    177.6    0.00    0.00      0
          32             8     float     sum      -1    178.5    0.00    0.00      0    177.9    0.00    0.00      0
          64            16     float     sum      -1    178.8    0.00    0.00      0    178.7    0.00    0.00      0
         128            32     float     sum      -1    178.2    0.00    0.00      0    177.8    0.00    0.00      0
         256            64     float     sum      -1    178.6    0.00    0.00      0    178.8    0.00    0.00      0
         512           128     float     sum      -1    177.2    0.00    0.01      0    177.1    0.00    0.01      0
        1024           256     float     sum      -1    179.2    0.01    0.01      0    179.3    0.01    0.01      0
        2048           512     float     sum      -1    181.3    0.01    0.02      0    181.2    0.01    0.02      0
        4096          1024     float     sum      -1    184.2    0.02    0.04      0    183.9    0.02    0.04      0
        8192          2048     float     sum      -1    191.2    0.04    0.08      0    190.6    0.04    0.08      0
       16384          4096     float     sum      -1    202.5    0.08    0.15      0    202.3    0.08    0.15      0
       32768          8192     float     sum      -1    233.0    0.14    0.26      0    232.1    0.14    0.26      0
       65536         16384     float     sum      -1    238.6    0.27    0.51      0    235.1    0.28    0.52      0
      131072         32768     float     sum      -1    237.2    0.55    1.04      0    236.8    0.55    1.04      0
      262144         65536     float     sum      -1    248.3    1.06    1.98      0    247.0    1.06    1.99      0
      524288        131072     float     sum      -1    309.2    1.70    3.18      0    307.7    1.70    3.20      0
     1048576        262144     float     sum      -1    408.7    2.57    4.81      0    404.3    2.59    4.86      0
     2097152        524288     float     sum      -1    613.5    3.42    6.41      0    607.9    3.45    6.47      0
     4194304       1048576     float     sum      -1    924.5    4.54    8.51      0    914.8    4.58    8.60      0
     8388608       2097152     float     sum      -1   1059.5    7.92   14.85      0   1054.3    7.96   14.92      0
    16777216       4194304     float     sum      -1   1269.9   13.21   24.77      0   1272.0   13.19   24.73      0
    33554432       8388608     float     sum      -1   1642.7   20.43   38.30      0   1636.7   20.50   38.44      0
    67108864      16777216     float     sum      -1   2446.7   27.43   51.43      0   2445.8   27.44   51.45      0
   134217728      33554432     float     sum      -1   4143.6   32.39   60.73      0   4142.4   32.40   60.75      0
   268435456      67108864     float     sum      -1   7351.9   36.51   68.46      0   7346.7   36.54   68.51      0
   536870912     134217728     float     sum      -1    13717   39.14   73.39      0    13703   39.18   73.46      0
  1073741824     268435456     float     sum      -1    26416   40.65   76.21      0    26420   40.64   76.20      0
...
# Out of bounds values : 0 OK
# Avg bus bandwidth    : 15.5514
```

#### 검증 테스트
<a name="tutorial-efa-validation"></a>

EFA 테스트가 유효한 결과를 반환했는지 검증하려면 다음 테스트를 사용하여 확인합니다.
+ EC2 인스턴스 메타데이터를 사용하여 인스턴스 유형 가져오기:

  ```
  TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
  INSTANCE_TYPE=$(curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-type)
  ```
+ [성능 테스트](#tutorial-efa-using-multinode) 실행 
+  다음 파라미터 설정 

  ```
  CUDA_VERSION
  CUDA_RUNTIME_VERSION
  NCCL_VERSION
  ```
+  다음과 같이 결과 검증: 

  ```
  RETURN_VAL=`echo $?`
  if [ ${RETURN_VAL} -eq 0 ]; then
  
      # [0] NCCL INFO NET/OFI Initializing aws-ofi-nccl 1.13.2-aws
      # [0] NCCL INFO NET/OFI Using CUDA driver version 12060 with runtime 12010
  
      # cudaDriverVersion 12060  --> This is max supported cuda version by nvidia driver
      # NCCL version 2.23.4+cuda12.5 --> This is NCCL version compiled with cuda version
  
      # Validation of logs
      grep "NET/OFI Configuring AWS-specific options" ${TRAINING_LOG} || { echo "AWS-specific options text not found"; exit 1; } 
      grep "busbw" ${TRAINING_LOG} || { echo "busbw text not found"; exit 1; } 
      grep "Avg bus bandwidth " ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; } 
      grep "NCCL version $NCCL_VERSION" ${TRAINING_LOG} || { echo "Text not found: NCCL version $NCCL_VERSION"; exit 1; }
      if [[ ${INSTANCE_TYPE} == "p4d.24xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Text not found: NET/Libfabric/0/GDRDMA"; exit 1; }  
          grep "NET/OFI Selected Provider is efa (found 4 nics)" ${TRAINING_LOG} || { echo "Selected Provider is efa text not found"; exit 1; }   
      elif [[ ${INSTANCE_TYPE} == "p4de.24xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 4 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
      elif [[ ${INSTANCE_TYPE} == "p5.48xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 32 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; } 
      elif [[ ${INSTANCE_TYPE} == "p5e.48xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 32 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
      elif [[ ${INSTANCE_TYPE} == "p5en.48xlarge" ]]; then
          grep "NET/Libfabric/0/GDRDMA" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
          grep "NET/OFI Selected Provider is efa (found 16 nics)" ${TRAINING_LOG} || { echo "Avg bus bandwidth text not found"; exit 1; }
      elif [[ ${INSTANCE_TYPE} == "p3dn.24xlarge" ]]; then
          grep "NET/OFI Selected Provider is efa (found 4 nics)" ${TRAINING_LOG} || { echo "Selected Provider is efa text not found"; exit 1; }  
      fi
      echo "***************************** check_efa_nccl_all_reduce passed for cuda version ${CUDA_VERSION} *****************************"
  else
      echo "***************************** check_efa_nccl_all_reduce failed for cuda version ${CUDA_VERSION} *****************************"
  fi
  ```
+ 벤치마크 데이터에 액세스하기 위해 다중 노드 all\$1reduce 테스트에서 테이블 출력의 마지막 행을 구문 분석할 수 있습니다.

  ```
  benchmark=$(sudo cat ${TRAINING_LOG} | grep '1073741824' | tail -n1 | awk -F " " '{{print $12}}' | sed 's/ //' | sed  's/  5e-07//')
  if [[ -z "${benchmark}" ]]; then
    echo "benchmark variable is empty"
    exit 1
  fi
  
  echo "Benchmark throughput: ${benchmark}"
  ```