Exécutez des conteneurs Docker sur un nœud de calcul Slurm sur HyperPod - Amazon SageMaker

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Exécutez des conteneurs Docker sur un nœud de calcul Slurm sur HyperPod

Pour exécuter des conteneurs Docker avec Slurm activé SageMaker HyperPod, vous devez utiliser Enroot et Pyxis. Le package Enroot permet de convertir les images Docker en un environnement d'exécution compréhensible par Slurm, tandis que le Pyxis permet de planifier l'exécution en tant que tâche Slurm via une commande. srun srun --container-image=docker/image:tag

Astuce

Les packages Docker, Enroot et Pyxis doivent être installés lors de la création du cluster dans le cadre de l'exécution des scripts de cycle de vie comme indiqué dans le manuel. Commencez par les scripts de cycle de vie de base fournis par HyperPod Utilisez les scripts de cycle de vie de base fournis par l'équipe HyperPod de service lors de la création d'un HyperPod cluster. Ces scripts de base sont configurés pour installer les packages par défaut. Dans le config.pyscript, il y a la Config classe avec le paramètre de type booléen pour installer les packages définis sur True ()enable_docker_enroot_pyxis=True. Ceci est appelé et analysé dans le lifecycle_script.pyscript, qui appelle install_docker.sh et écrit des install_enroot_pyxis.sh scripts depuis le utilsdossier. Les scripts d'installation sont l'endroit où les installations réelles des packages ont lieu. En outre, les scripts d'installation identifient s'ils peuvent détecter les chemins de stockage NVMe à partir des instances sur lesquelles ils sont exécutés et configurent les chemins racines vers lesquels Docker et Enroot doivent accéder. /opt/dlami/nvme Le volume racine par défaut de toute nouvelle instance est monté /tmp uniquement sur un volume EBS de 100 Go, qui s'épuise si la charge de travail que vous prévoyez d'exécuter implique la formation de LLM et donc de conteneurs Docker de grande taille. Si vous utilisez des familles d'instances telles que P et G avec un stockage NVMe local, vous devez vous assurer que vous utilisez le stockage NVMe connecté à/opt/dlami/nvme, et les scripts d'installation prennent en charge les processus de configuration.

Pour vérifier si les chemins racines sont correctement configurés

Sur un nœud de calcul de votre cluster Slurm activé SageMaker HyperPod, exécutez les commandes suivantes pour vous assurer que le script de cycle de vie fonctionne correctement et que le volume racine de chaque nœud est défini sur. /opt/dlami/nvme/* Les commandes suivantes montrent des exemples de vérification du chemin d'exécution Enroot et du chemin racine des données pour 8 nœuds de calcul d'un cluster Slurm.

$ srun -N 8 cat /etc/enroot/enroot.conf | grep "ENROOT_RUNTIME_PATH" ENROOT_RUNTIME_PATH /opt/dlami/nvme/tmp/enroot/user-$(id -u) ... // The same or similar lines repeat 7 times
$ srun -N 8 cat /etc/docker/daemon.json { "data-root": "/opt/dlami/nvme/docker/data-root" } ... // The same or similar lines repeat 7 times

Après avoir confirmé que les chemins d'exécution sont correctement définis sur/opt/dlami/nvme/*, vous êtes prêt à créer et à exécuter des conteneurs Docker avec Enroot et Pyxis.

Pour tester Docker avec Slurm

  1. Sur votre nœud de calcul, essayez les commandes suivantes pour vérifier si Docker et Enroot sont correctement installés.

    $ docker --help $ enroot --help
  2. Testez si Pyxis et Enroot sont correctement installés en exécutant l'une des images NVIDIA CUDA Ubuntu.

    $ srun --container-image=nvidia/cuda:XX.Y.Z-base-ubuntuXX.YY nvidia-smi pyxis: importing docker image: nvidia/cuda:XX.Y.Z-base-ubuntuXX.YY pyxis: imported docker image: nvidia/cuda:XX.Y.Z-base-ubuntuXX.YY DAY MMM DD HH:MM:SS YYYY +-----------------------------------------------------------------------------+ | NVIDIA-SMI 470.141.03 Driver Version: 470.141.03 CUDA Version: XX.YY | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 Tesla T4 Off | 00000000:00:1E.0 Off | 0 | | N/A 40C P0 27W / 70W | 0MiB / 15109MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+

    Vous pouvez également le tester en créant un script et en exécutant une sbatch commande comme suit.

    $ cat <<EOF >> container-test.sh #!/bin/bash #SBATCH --container-image=nvidia/cuda:XX.Y.Z-base-ubuntuXX.YY nvidia-smi EOF $ sbatch container-test.sh pyxis: importing docker image: nvidia/cuda:XX.Y.Z-base-ubuntuXX.YY pyxis: imported docker image: nvidia/cuda:XX.Y.Z-base-ubuntuXX.YY DAY MMM DD HH:MM:SS YYYY +-----------------------------------------------------------------------------+ | NVIDIA-SMI 470.141.03 Driver Version: 470.141.03 CUDA Version: XX.YY | |-------------------------------+----------------------+----------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |===============================+======================+======================| | 0 Tesla T4 Off | 00000000:00:1E.0 Off | 0 | | N/A 40C P0 27W / 70W | 0MiB / 15109MiB | 0% Default | | | | N/A | +-------------------------------+----------------------+----------------------+ +-----------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+

Pour exécuter une tâche de test Slurm avec Docker

Une fois que vous avez terminé de configurer Slurm avec Docker, vous pouvez apporter toutes les images Docker prédéfinies et exécuter avec Slurm on. SageMaker HyperPod Voici un exemple de cas d'utilisation qui explique comment exécuter une tâche de formation à l'aide de Docker et de Slurm on. SageMaker HyperPod Il montre un exemple de travail d'apprentissage parallèle du modèle Llama 2 avec la bibliothèque de parallélisme des SageMaker modèles (SMP).

  1. Si vous souhaitez utiliser l'une des images ECR prédéfinies distribuées par SageMaker le DLC, assurez-vous d'autoriser votre HyperPod cluster à extraire des images ECR via le. Rôle IAM pour SageMaker HyperPod Si vous utilisez votre propre image Docker ou une image open source, vous pouvez ignorer cette étape. Ajoutez les autorisations suivantes auRôle IAM pour SageMaker HyperPod. Dans ce didacticiel, nous utilisons l'image SMP Docker préemballée avec la bibliothèque SMP.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr-public:*", "ecr:GetDownloadUrlForLayer", "ecr:GetAuthorizationToken", "sts:*" ], "Resource": "*" } ] }
  2. Sur le nœud de calcul, clonez le référentiel et accédez au dossier contenant les exemples de scripts d'entraînement avec SMP.

    $ git clone https://github.com/aws-samples/awsome-distributed-training/ $ cd awsome-distributed-training/3.test_cases/17.SM-modelparallelv2
  3. Dans ce didacticiel, exécutez l'exemple de script docker_build.shqui extrait l'image Docker SMP, crée le conteneur Docker et l'exécute en tant qu'environnement d'exécution Enroot. Vous pouvez le modifier comme vous le souhaitez.

    $ cat docker_build.sh #!/usr/bin/env bash region=us-west-2 dlc_account_id=658645717510 aws ecr get-login-password --region $region | docker login --username AWS --password-stdin $dlc_account_id.dkr.ecr.$region.amazonaws.com docker build -t smpv2 . enroot import -o smpv2.sqsh dockerd://smpv2:latest
    $ bash docker_build.sh
  4. Créez un script batch pour lancer une tâche de formation à l'aide desbatch. Dans ce didacticiel, l'exemple de script fourni launch_training_enroot.shlance une tâche d'entraînement parallèle au modèle Llama 2 de 70 milliards de paramètres avec un ensemble de données synthétique sur 8 nœuds de calcul. Un ensemble de scripts de formation est fourni sur 3.test_cases/17.SM-modelparallelv2/scripts, et launch_training_enroot.sh prend train_external.py comme point d'entrée de jeu.

    Important

    Pour utiliser un conteneur Docker sur SageMaker HyperPod, vous devez monter le /var/log répertoire depuis la machine hôte, qui est le nœud de HyperPod calcul dans ce cas, sur le /var/log répertoire du conteneur. Vous pouvez le configurer en ajoutant la variable suivante pour Enroot.

    "${HYPERPOD_PATH:="/var/log/aws/clusters":"/var/log/aws/clusters"}"
    $ cat launch_training_enroot.sh #!/bin/bash # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 #SBATCH --nodes=8 # number of nodes to use, 2 p4d(e) = 16 A100 GPUs #SBATCH --job-name=smpv2_llama # name of your job #SBATCH --exclusive # job has exclusive use of the resource, no sharing #SBATCH --wait-all-nodes=1 set -ex; ########################### ###### User Variables ##### ########################### ######################### model_type=llama_v2 model_size=70b # Toggle this to use synthetic data use_synthetic_data=1 # To run training on your own data set Training/Test Data path -> Change this to the tokenized dataset path in Fsx. Acceptable formats are huggingface (arrow) and Jsonlines. # Also change the use_synthetic_data to 0 export TRAINING_DIR=/fsx/path_to_data export TEST_DIR=/fsx/path_to_data export CHECKPOINT_DIR=$(pwd)/checkpoints # Variables for Enroot : "${IMAGE:=$(pwd)/smpv2.sqsh}" : "${HYPERPOD_PATH:="/var/log/aws/clusters":"/var/log/aws/clusters"}" # This is needed for validating its hyperpod cluster : "${TRAIN_DATA_PATH:=$TRAINING_DIR:$TRAINING_DIR}" : "${TEST_DATA_PATH:=$TEST_DIR:$TEST_DIR}" : "${CHECKPOINT_PATH:=$CHECKPOINT_DIR:$CHECKPOINT_DIR}" ########################### ## Environment Variables ## ########################### #export NCCL_SOCKET_IFNAME=en export NCCL_ASYNC_ERROR_HANDLING=1 export NCCL_PROTO="simple" export NCCL_SOCKET_IFNAME="^lo,docker" export RDMAV_FORK_SAFE=1 export FI_EFA_USE_DEVICE_RDMA=1 export NCCL_DEBUG_SUBSYS=off export NCCL_DEBUG="INFO" export SM_NUM_GPUS=8 export GPU_NUM_DEVICES=8 export FI_EFA_SET_CUDA_SYNC_MEMOPS=0 # async runtime error ... export CUDA_DEVICE_MAX_CONNECTIONS=1 ######################### ## Command and Options ## ######################### if [ "$model_size" == "7b" ]; then HIDDEN_WIDTH=4096 NUM_LAYERS=32 NUM_HEADS=32 LLAMA_INTERMEDIATE_SIZE=11008 DEFAULT_SHARD_DEGREE=8 # More Llama model size options elif [ "$model_size" == "70b" ]; then HIDDEN_WIDTH=8192 NUM_LAYERS=80 NUM_HEADS=64 LLAMA_INTERMEDIATE_SIZE=28672 # Reduce for better perf on p4de DEFAULT_SHARD_DEGREE=64 fi if [ -z "$shard_degree" ]; then SHARD_DEGREE=$DEFAULT_SHARD_DEGREE else SHARD_DEGREE=$shard_degree fi if [ -z "$LLAMA_INTERMEDIATE_SIZE" ]; then LLAMA_ARGS="" else LLAMA_ARGS="--llama_intermediate_size $LLAMA_INTERMEDIATE_SIZE " fi if [ $use_synthetic_data == 1 ]; then echo "using synthetic data" declare -a ARGS=( --container-image $IMAGE --container-mounts $HYPERPOD_PATH,$CHECKPOINT_PATH ) else echo "using real data...." declare -a ARGS=( --container-image $IMAGE --container-mounts $HYPERPOD_PATH,$TRAIN_DATA_PATH,$TEST_DATA_PATH,$CHECKPOINT_PATH ) fi declare -a TORCHRUN_ARGS=( # change this to match the number of gpus per node: --nproc_per_node=8 \ --nnodes=$SLURM_JOB_NUM_NODES \ --rdzv_id=$SLURM_JOB_ID \ --rdzv_backend=c10d \ --rdzv_endpoint=$(hostname) \ ) srun -l "${ARGS[@]}" torchrun "${TORCHRUN_ARGS[@]}" /path_to/train_external.py \ --train_batch_size 4 \ --max_steps 100 \ --hidden_width $HIDDEN_WIDTH \ --num_layers $NUM_LAYERS \ --num_heads $NUM_HEADS \ ${LLAMA_ARGS} \ --shard_degree $SHARD_DEGREE \ --model_type $model_type \ --profile_nsys 1 \ --use_smp_implementation 1 \ --max_context_width 4096 \ --tensor_parallel_degree 1 \ --use_synthetic_data $use_synthetic_data \ --training_dir $TRAINING_DIR \ --test_dir $TEST_DIR \ --dataset_type hf \ --checkpoint_dir $CHECKPOINT_DIR \ --checkpoint_freq 100 \ $ sbatch launch_training_enroot.sh

Pour trouver les exemples de code téléchargeables, voir Exécuter une tâche d'entraînement parallèle à un SageMaker modèle à l'aide de la bibliothèque de parallélisme de modèles, Docker et Enroot with Slurm dans le référentiel Awsome Distributed Training. GitHub Pour plus d'informations sur l'entraînement distribué avec un cluster Slurm activé SageMaker HyperPod, passez à la rubrique suivante à l'adresse. Exécutez des charges de travail de formation distribuées avec Slurm on HyperPod