Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Uso del EFA en la DLAMI
En la siguiente sección se describe cómo utilizar EFA para ejecutar aplicaciones de varios nodos en AWS Deep Learning AMIs.
Ejecución de aplicaciones de varios nodos con EFA
Para ejecutar una aplicación a través de un clúster de nodos, es necesario realizar los siguientes ajustes.
Habilitar SSH sin contraseña
Seleccione un nodo del clúster como nodo principal. Los nodos restantes se denominan nodos miembro.
En el nodo principal, genere el par de claves RSA.
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
Cambie los permisos de la clave privada en el nodo principal.
chmod 600 ~/.ssh/id_rsa
Copie la clave pública
~/.ssh/id_rsa.pub
y añádala a~/.ssh/authorized_keys
para los nodos miembro del clúster.Ahora debe poder iniciar sesión directamente en los nodos miembro desde el nodo principal mediante la ip privada.
ssh <member private ip>
Inhabilite la strictHostKey verificación y habilite el reenvío de agentes en el nodo principal añadiendo lo siguiente al archivo ~/.ssh/config del nodo líder:
Host * ForwardAgent yes Host * StrictHostKeyChecking no
En las instancias de Amazon Linux 2, ejecute el siguiente comando en el nodo principal para proporcionar los permisos correctos al archivo de configuración:
chmod 600 ~/.ssh/config
Creación de archivo de hosts
En el nodo principal, cree un archivo de hosts para identificar los nodos del clúster. El archivo de hosts debe tener una entrada para cada nodo del clúster. Cree un archivo ~/hosts y añada cada nodo mediante la ip privada de la siguiente manera:
localhost slots=8 <private ip of node 1> slots=8 <private ip of node 2> slots=8
Pruebas de NCCL
nota
Estas pruebas se han realizado con la versión 1.38.0 de EFA y el complemento OFI NCCL 1.13.2.
A continuación, se muestra un subconjunto de pruebas de NCCL realizadas por Nvidia para comprobar tanto la funcionalidad como el rendimiento en varios nodos de cómputo
Instancias compatibles: P3dn, P4, P5, P5e, P5en
Prueba de rendimiento NCCL de varios nodos en P4d.24xlarge
Para comprobar el rendimiento de NCCL con EFA, ejecute la prueba de rendimiento de NCCL estándar que está disponible en el repositorio oficial de pruebas de NCCL
Cuando cree su propio script, siga estas directrices:
-
Utilice la ruta completa a mpirun, tal y como se muestra en el ejemplo, mientras ejecuta aplicaciones NCCL con EFA.
-
Cambie los parámetros np y N en función del número de instancias y del clúster. GPUs
-
Añada el indicador NCCL_DEBUG=INFO y asegúrese de que los registros indiquen el uso del EFA como “El proveedor seleccionado es EFA”.
-
Defina la ubicación del registro de entrenamiento para analizarla para su validación.
TRAINING_LOG="testEFA_$(date +"%N").log"
Utilice el comando watch nvidia-smi
en cualquiera de los nodos miembro para monitorizar el uso de la GPU. Los siguientes comandos watch nvidia-smi
son para la versión xx.x de CUDA y dependen del sistema operativo de la instancia. Puedes ejecutar los comandos para cualquier versión de CUDA disponible en tu EC2 instancia de Amazon sustituyendo la versión de CUDA en el script.
-
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}
El resultado debería tener el siguiente aspecto:
# 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
Para validar que las pruebas de EFA han arrojado un resultado válido, utilice las siguientes pruebas para confirmarlo:
-
Obtenga el tipo de instancia mediante los metadatos de la EC2 instancia:
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)
-
Ejecute la Pruebas de rendimiento
-
Establezca los siguientes parámetros:
CUDA_VERSION CUDA_RUNTIME_VERSION NCCL_VERSION
-
Valide los resultados como se muestra:
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
-
Para acceder a los datos de referencia, podemos analizar la última fila del resultado de la tabla de la prueba all_reduce de varios nodos:
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}"