

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Elastic Fabric Adapter 进行分布式训练
<a name="tutorial-efa"></a>

[Elastic Fabric Adapter](https://aws.amazon.com/hpc/efa/) (EFA) 是一种网络设备，可以将其附加到您的 DLAMI 实例以加快高性能计算 (HPC) 应用程序的速度。借助 AWS 云提供的可扩展性、灵活性和弹性，EFA 使您能够实现本地 HPC 集群的应用程序性能。

以下主题将向您展示如何开始结合使用 EFA 与 DLAMI。

**注意**  
从这个[基础 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>

最新基础 DLAMI 可随时与 EFA 结合使用，并随附所需的驱动程序、内核模块、libfabric、openmpi 和适用于 GPU 实例的 [NCCL OFI 插件](https://github.com/aws/aws-ofi-nccl/tree/aws)。

您可以在[发布说明](appendix-ami-release-notes.md#appendix-ami-release-notes-base)中找到基础 DLAMI 的支持 CUDA 版本。

注意：
+ 在 EFA 上使用 `mpirun` 运行 NCCL 应用程序时，必须将 EFA 支持的安装的完整路径指定为：

  ```
  /opt/amazon/openmpi/bin/mpirun <command>  
  ```
+ 要使您的应用程序能够使用 EFA，请将 `FI_PROVIDER="efa"` 添加到 `mpirun` 命令，如[在 DLAMI 上使用 EFA](tutorial-efa-using.md)中所示。

**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。
   + 选择**创建**。

1. 选择您创建的安全组，然后在**描述** 选项卡上复制**组 ID**。

1. 在**入站**和**出站**选项卡上，执行以下操作：
   + 选择**编辑**。
   + 对于**类型**，请选择**所有流量**。
   + 对于 **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>

目前 AWS Deep Learning AMIs ，以下实例类型和操作系统支持上的 EFA：
+  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 启用的 DLAMI 实例的更多信息，请参阅[在集群置放群组中启动 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 Release Notes Page](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. 在**配置实例详细信息**页面中，执行以下操作：
   + 对于**实例的数量**，请输入要启动的启用了 EFA 的实例数量。
   + 对于**网络** 和**子网**，请选择要在其中启动实例的 VPC 和子网。
   + [可选] 对于**置放群组**，请选择**将实例添加到置放群组**。为获得最佳性能，请在置放群组中启动实例。
   + [可选] 对于**置放群组名称**，请选择**添加到新的置放群组**，输入置放群组的描述性名称，然后对于**置放群组策略**选择**集群**。
   + 请务必在此页面上启用**“Elastic Fabric Adapter”**。如果禁用此选项，请将子网更改为支持所选实例类型的子网。
   + 在**网络接口**部分中，为设备 **eth0** 选择**新网络接口**。您可以选择指定一个主 IPv4 地址和一个或多个辅助 IPv4 地址。如果您要在具有关联 IPv6 CIDR 块的子网中启动实例，则可以选择指定一个主 IPv6 地址和一个或多个辅助 IPv6 地址。
   + 选择**下一步：添加存储**。

1. 在**添加存储**页面上，除了 AMI 指定的卷（如根设备卷）以外，还要指定要附加到实例的卷，然后选择**下一步：添加标签**。

1. 在**添加标签**页面上，为实例指定标签（例如，便于用户识别的名称），然后选择**下一步：配置安全组**。

1. 在**配置安全组**页面上，对于**分配安全组**选择**选择一个现有的安全组**，然后选择先前创建的安全组**。**

1. 选择**审核并启动**。

1. 在**核查实例启动**页面上，检查这些设置，然后选择**启动**以选择一个密钥对并启动您的实例。

## 验证 EFA 附件
<a name="tutorial-efa-verify-attachment"></a>

### 通过控制台
<a name="tutorial-efa-verify-attachment-console"></a>

启动实例后，请在 AWS 控制台中查看实例详细信息。为此，请在 EC2 控制台中选择实例，然后查看页面下部窗格中的 Description (描述) 选项卡。找到参数“Network Interfaces: eth0”，然后单击 eth0，这将弹出一个弹出窗口。确保已启用“Elastic Fabric Adapter”。

如果未启用 EFA，您可以通过以下任一方式解决此问题：
+ 终止 EC2 实例并使用相同步骤启动新实例。确保已附加 EFA。
+ 将 EFA 附加到现有实例。

  1. 在 EC2 控制台中，转到“网络接口”。

  1. 单击“创建虚拟网络接口”。

  1. 选择您的实例所在的相同子网。

  1. 确保启用“Elastic Fabric Adapter”并点击“创建”。

  1. 返回“EC2 实例”选项卡并选择您的实例。

  1. 转到“操作：实例状态”并在附加 EFA 之前停止实例。

  1. 从 “操作”中，选择“网络连接：连接网络接口”。

  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
```

如果它停止响应或未完成，请确保您的安全组具有正确的 inbound/outbound 规则。

# 在 DLAMI 上使用 EFA
<a name="tutorial-efa-using"></a>

以下部分描述如何在 AWS Deep Learning AMIs上使用 EFA 来运行多节点应用程序。

## 使用 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 文件中，禁用 strictHostKey检查并在领导节点上启用代理转发：

   ```
   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 Plugin 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 存储库](https://github.com/NVIDIA/nccl-tests.git)中提供的标准 NCCL 性能测试。DLAMI 附带了这个已经为 CUDA XX.X 构建的测试。您也可以使用 EFA 运行自己的脚本。

构建您自己的脚本时，请参阅以下指南：
+ 当使用 EFA 来运行 NCCL 应用程序时，按照示例所示使用到 mpirun 的完整路径。
+ 根据集群 GPUs 中的实例数量更改参数 np 和 N。
+ 添加 NCCL\$1DEBUG=INFO 标志，并确保日志将 EFA 用法指示为“所选提供程序是 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}"
  ```