

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.

# Docker-Container auf einem Slurm-Rechenknoten ausführen auf HyperPod
<a name="sagemaker-hyperpod-run-jobs-slurm-docker"></a>

[https://github.com/NVIDIA/enroot](https://github.com/NVIDIA/enroot) Das Enroot-Paket hilft dabei, Docker-Images in eine Laufzeitumgebung zu konvertieren, die Slurm verstehen kann, während Pyxis die Planung der Laufzeitumgebung als Slurm-Auftrag über einen `srun`-Befehl, `srun --container-image={{docker/image:tag}}`, ermöglicht. 

**Tipp**  
Die Docker-, Enroot- und Pyxis-Pakete sollten während der Clustererstellung als Teil der Ausführung der Lebenszyklusskripte wie in der Anleitung [Die grundlegenden Lebenszyklusskripte werden bereitgestellt von HyperPod](sagemaker-hyperpod-lifecycle-best-practices-slurm-slurm-base-config.md) beschrieben installiert werden. Verwenden Sie bei der Erstellung [eines Clusters die vom HyperPod Serviceteam bereitgestellten Basis-Lebenszyklus-Skripte](https://github.com/aws-samples/awsome-distributed-training/tree/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config). HyperPod Diese Basisskripte sind standardmäßig so eingerichtet, dass sie die Pakete installieren. Im [https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/config.py](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/config.py)-Skript 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 [https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/lifecycle_script.py](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/lifecycle_script.py)-Skript aufgerufen und analysiert, das `install_docker.sh`- und `install_enroot_pyxis.sh`-Skripte aus dem [https://github.com/aws-samples/awsome-distributed-training/tree/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/utils](https://github.com/aws-samples/awsome-distributed-training/tree/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/utils)-Ordner aufruft und ausführt. In den Installationsskripten finden die eigentlichen Installationen der Pakete statt. Darüber hinaus erkennen die Installationsskripte, ob sie NVMe-Speicherpfade von den Instances, auf denen sie ausgeführt werden, erkennen können, und richten die Stammpfade für Docker und Enroot auf `/opt/dlami/nvme`. Das Standard-Root-Volume einer neuen Instance wird nur mit einem 100 GB großen EBS-Volume unter `/tmp` gemountet, das nicht ausreicht, wenn die von Ihnen geplante Workload das Training von LLMs und damit große Docker-Container umfasst. Wenn Sie Instance-Familien wie P und G mit lokalem NVMe-Speicher verwenden, müssen Sie sicherstellen, dass Sie den unter angeschlossenen NVMe-Speicher verwenden, und die Installationsskripte kümmern sich um die Konfigurationsprozesse.

**So überprüfen Sie, 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 Daten-Root-Pfads 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 überprüft haben, dass die Laufzeitpfade korrekt auf `/opt/dlami/nvme/*` festgelegt sind, können Sie Docker-Container mit Enroot und Pyxis erstellen und ausführen.

**So testen Sie Docker mit Slurm**

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

1. Testen Sie, ob Pyxis und Enroot korrekt installiert wurden, indem Sie eines der Images von [NVIDIA CUDA Ubuntu](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cuda) ausführen.

   ```
   $ srun --container-image=nvidia/cuda:{{XX.Y.Z}}-base-ubuntu{{XX.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-ubuntu{{XX.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                                                 |
   +-----------------------------------------------------------------------------+
   ```

**So führen Sie einen Test-Slurm-Auftrag mit Docker aus**

Nachdem Sie die Einrichtung von Slurm mit Docker abgeschlossen haben, können Sie alle vorgefertigten Docker-Images verwenden und mit Slurm on 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 AI-Bibliothek für Modellparallelismus (SMP).

1. Wenn Sie eines der vorgefertigten ECR-Images verwenden möchten, die von SageMaker AI oder DLC vertrieben werden, stellen Sie sicher, dass Sie Ihrem HyperPod Cluster die Berechtigungen zum Abrufen von ECR-Bildern über die geben. [IAM-Rolle für SageMaker HyperPod](sagemaker-hyperpod-prerequisites-iam.md#sagemaker-hyperpod-prerequisites-iam-role-for-hyperpod) Wenn Sie ein eigenes oder ein Docker-Image (Open Source) verwenden, können Sie diesen Schritt überspringen. Fügen Sie [IAM-Rolle für SageMaker HyperPod](sagemaker-hyperpod-prerequisites-iam.md#sagemaker-hyperpod-prerequisites-iam-role-for-hyperpod) die folgenden Berechtigungen hinzu. In diesem Tutorial verwenden wir das [SMP-Docker-Image](distributed-model-parallel-support-v2.md#distributed-model-parallel-supported-frameworks-v2), das mit der SMP-Bibliothek vorinstalliert ist.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "ecr:BatchCheckLayerAvailability",
                   "ecr:BatchGetImage",
                   "ecr-public:*",
                   "ecr:GetDownloadUrlForLayer",
                   "ecr:GetAuthorizationToken",
                   "sts:*"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

------

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

1. Führen Sie in diesem Tutorial das Beispielskript-[https://github.com/aws-samples/awsome-distributed-training/blob/main/3.test_cases/17.SM-modelparallelv2/docker_build.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/3.test_cases/17.SM-modelparallelv2/docker_build.sh) aus, das das SMP-Docker-Image abruft, den Docker-Container erstellt und ihn als Enroot-Laufzeitumgebung 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
   ```

1. Erstellen Sie ein Batch-Skript, um einen Trainingsjob mit `sbatch` zu starten. In diesem Tutorial startet das bereitgestellte Beispielskript [https://github.com/aws-samples/awsome-distributed-training/blob/main/3.test_cases/17.SM-modelparallelv2/launch_training_enroot.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/3.test_cases/17.SM-modelparallelv2/launch_training_enroot.sh) einen modellparallelen Trainingsjob des Llama 2-Modells mit 70 Milliarden Parametern und einem synthetischen Datensatz auf 8 Rechenknoten. Eine Reihe von Trainingsskripten wird unter [https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/17.SM-modelparallelv2/scripts](https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/17.SM-modelparallelv2/scripts) bereitgestellt und `launch_training_enroot.sh` nimmt `train_external.py` als Einstiegsskript.
**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 Verzeichnis im Container mounten. `/var/log` Sie können ihn 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 AI-Modellparallelismusbibliothek, Docker und Enroot mit Slurm](https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/17.SM-modelparallelv2#option-2----run-training-using-docker-and-enroot) im Awsome Distributed Training Repository. GitHub * Weitere Informationen zu verteiltem Training mit eingeschaltetem Slurm-Cluster finden Sie im nächsten Thema unter. SageMaker HyperPod [Ausführung verteilter Trainingsworkloads mit aktiviertem Slurm HyperPod](sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload.md)