Führen Sie Docker-Container auf einem Slurm-Rechenknoten aus auf SageMaker HyperPod - Amazon SageMaker

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Führen Sie Docker-Container auf einem Slurm-Rechenknoten aus auf SageMaker HyperPod

Um Docker-Container mit aktiviertem Slurm auszuführen SageMaker HyperPod, müssen Sie Enroot und Pyxis verwenden. Das Enroot-Paket hilft dabei, Docker-Images in eine Runtime zu konvertieren, die Slurm verstehen kann, während Pyxis es ermöglicht, die Laufzeit über einen Befehl als Slurm-Job zu planen. srun srun --container-image=docker/image:tag

Tipp

Die Docker-, Enroot- und Pyxis-Pakete sollten während der Clustererstellung als Teil der Ausführung der Lifecycle-Skripte wie in der Anleitung beschrieben installiert werden. Beginnen Sie mit den grundlegenden Lebenszyklusskripten von HyperPod Verwenden Sie bei der Erstellung eines Clusters die vom HyperPod Serviceteam bereitgestellten grundlegenden Lebenszyklusskripte. HyperPod Diese Basisskripte sind standardmäßig so eingerichtet, dass sie die Pakete installieren. Im config.pySkript gibt es die Config Klasse mit dem booleschen Typparameter für die Installation der Pakete, der auf True () enable_docker_enroot_pyxis=True gesetzt ist. Dies wird vom Skript aufgerufen und im Skript analysiert, das lifecycle_script.pySkripts aus dem Ordner install_docker.sh install_enroot_pyxis.sh aufruft. utils In den Installationsskripten finden die eigentlichen Installationen der Pakete statt. Darüber hinaus identifizieren die Installationsskripten, ob sie NVMe-Speicherpfade von den Instanzen, auf denen sie ausgeführt werden, erkennen können, und richten die Root-Pfade für Docker und Enroot ein. /opt/dlami/nvme Das Standard-Root-Volume jeder neuen Instance wird /tmp nur mit einem 100-GB-EBS-Volume gemountet. Dieses Volume läuft aus, wenn der Workload, den Sie ausführen möchten, das Training von LLMs und damit von großen Docker-Containern beinhaltet. Wenn Sie Instance-Familien wie P und G mit lokalem NVMe-Speicher verwenden, müssen Sie sicherstellen, dass Sie den NVMe-Speicher verwenden, der unter angehängt ist/opt/dlami/nvme, und die Installationsskripts kümmern sich um die Konfigurationsprozesse.

Um zu überprüfen, ob die Root-Pfade richtig eingerichtet sind

Führen Sie auf einem Rechenknoten Ihres Slurm-Clusters die folgenden Befehle aus SageMaker HyperPod, um sicherzustellen, dass das Lifecycle-Skript ordnungsgemäß funktioniert hat und das Root-Volume jedes Knotens auf /opt/dlami/nvme/* eingestellt ist. Die folgenden Befehle zeigen Beispiele für die Überprüfung des Enroot-Laufzeitpfads und des Datenstammpfads für 8 Rechenknoten eines Slurm-Clusters.

$ 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

Nachdem Sie sich vergewissert haben, dass die Laufzeitpfade richtig eingestellt sind/opt/dlami/nvme/*, können Sie Docker-Container mit Enroot und Pyxis erstellen und ausführen.

Um Docker mit Slurm zu testen

  1. Probieren Sie auf Ihrem Rechenknoten die folgenden Befehle aus, um zu überprüfen, ob Docker und Enroot ordnungsgemäß installiert sind.

    $ docker --help $ enroot --help
  2. Testen Sie, ob Pyxis und Enroot korrekt installiert wurden, indem Sie eines der NVIDIA CUDA Ubuntu-Images ausführen.

    $ 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 | +-----------------------------------------------------------------------------+

    Sie können es auch testen, indem Sie ein Skript erstellen und einen sbatch Befehl wie folgt ausführen.

    $ 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 | +-----------------------------------------------------------------------------+

Um einen Test-Slurm-Job mit Docker auszuführen

Nachdem Sie die Einrichtung von Slurm mit Docker abgeschlossen haben, können Sie alle vorgefertigten Docker-Images mitbringen und mit eingeschaltetem Slurm ausführen. SageMaker HyperPod Im Folgenden finden Sie ein Beispiel für einen Anwendungsfall, der Ihnen zeigt, wie Sie einen Trainingsjob mit Docker und eingeschaltetem Slurm ausführen. SageMaker HyperPod Es zeigt ein Beispiel für das modellparallele Training des Llama-2-Modells mit der SageMaker Modellparallelismus (SMP) -Bibliothek.

  1. Wenn Sie eines der vorgefertigten ECR-Images verwenden möchten, die von SageMaker oder DLC vertrieben werden, stellen Sie sicher, dass Sie Ihrem HyperPod Cluster die Berechtigungen zum Abrufen von ECR-Images über den geben. IAM-Rolle für SageMaker HyperPod Wenn Sie Ihr eigenes oder ein Open-Source-Docker-Image verwenden, können Sie diesen Schritt überspringen. Fügen Sie dem die folgenden Berechtigungen hinzu. IAM-Rolle für SageMaker HyperPod In diesem Tutorial verwenden wir das SMP-Docker-Image, das im Lieferumfang der SMP-Bibliothek enthalten ist.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ecr:BatchCheckLayerAvailability", "ecr:BatchGetImage", "ecr-public:*", "ecr:GetDownloadUrlForLayer", "ecr:GetAuthorizationToken", "sts:*" ], "Resource": "*" } ] }
  2. Klonen Sie auf dem Rechenknoten das Repository und wechseln Sie zu dem Ordner, der die Beispielskripte für das Training mit SMP enthält.

    $ git clone https://github.com/aws-samples/awsome-distributed-training/ $ cd awsome-distributed-training/3.test_cases/17.SM-modelparallelv2
  3. Führen Sie in diesem Tutorial das Beispielskript aus docker_build.sh, das das SMP-Docker-Image abruft, den Docker-Container erstellt und ihn als Enroot-Laufzeit ausführt. Sie können dies nach Belieben ändern.

    $ 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. Erstellen Sie ein Batch-Skript, mit dem Sie einen Trainingsjob starten könnensbatch. In diesem Tutorial launch_training_enroot.shstartet das mitgelieferte Beispielskript einen modellparallelen Trainingsjob des Llama-2-Modells mit 70 Milliarden Parametern und einem synthetischen Datensatz auf 8 Rechenknoten. Eine Reihe von Trainingsskripten wird unter bereitgestellt und launch_training_enroot.sh dient als 3.test_cases/17.SM-modelparallelv2/scriptsEinstiegsskript. train_external.py

    Wichtig

    Um einen Docker-Container zu verwenden SageMaker HyperPod, müssen Sie das /var/log Verzeichnis vom Host-Computer, der in diesem Fall der HyperPod Rechenknoten ist, in das /var/log Verzeichnis im Container mounten. Sie können es einrichten, indem Sie die folgende Variable für Enroot hinzufügen.

    "${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

Die herunterladbaren Codebeispiele finden Sie unter Ausführen eines modellparallelen Trainingsjobs mithilfe der SageMaker Modellparallelismusbibliothek, Docker und Enroot mit Slurm im Awsome Distributed Training Repository. GitHub Weitere Informationen zu verteiltem Training mit eingeschaltetem Slurm-Cluster finden Sie im nächsten Thema unter. SageMaker HyperPod Führen Sie verteilte Trainingsworkloads mit aktiviertem Slurm aus SageMaker HyperPod