

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# HyperPod の Slurm コンピューティングノードでの Docker コンテナの実行
<a name="sagemaker-hyperpod-run-jobs-slurm-docker"></a>

SageMaker HyperPod で Slurm で Docker コンテナを実行するには、[Enroot](https://github.com/NVIDIA/enroot) と [Pyxis](https://github.com/NVIDIA/pyxis) を使用する必要があります。Enroot パッケージは、Docker イメージを Slurm が理解できるランタイムに変換するのに役立ちます。一方、Pyxis では、`srun` コマンド `srun --container-image={{docker/image:tag}}` を使用してランタイムを Slurm ジョブとしてスケジュールできます。

**ヒント**  
Docker、Enroot、Pyxis パッケージは、「[HyperPod が提供する基本ライフサイクルスクリプト](sagemaker-hyperpod-lifecycle-best-practices-slurm-slurm-base-config.md)」で説明されているライフサイクルスクリプトの実行の一環として、クラスターの作成時にインストールする必要があります。HyperPod クラスターを作成するときは、HyperPod サービスチームが提供する[基本ライフサイクルスクリプト](https://github.com/aws-samples/awsome-distributed-training/tree/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config)を使用します。これらの基本スクリプトは、デフォルトでパッケージをインストールするよう設定されています。[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) スクリプトには、`True` (`enable_docker_enroot_pyxis=True`) に設定されたパッケージをインストールするためのブール型パラメータを持つ `Config` クラスがあります。これは、[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) スクリプトによって呼び出され、このスクリプトで解析されます。このスクリプトは、[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) フォルダから `install_docker.sh` および `install_enroot_pyxis.sh` スクリプトを呼び出します。インストールスクリプトは、パッケージの実際のインストールが行われる場所です。さらに、インストールスクリプトは、実行されるインスタンスから NVMe ストアパスを検出できるかどうかを識別し、Docker と Enroot のルートパスを `/opt/dlami/nvme` に設定します。新しいインスタンスのデフォルトのルートボリュームは、100GB EBS ボリュームの場合のみ `/tmp` にマウントされます。これは、実行する予定のワークロードに LLM のトレーニングが含まれている場合、つまり、大きいサイズの Docker コンテナがある場合に実行されます。ローカル NVMe ストレージで P や G などのインスタンスファミリーを使用する場合、`/opt/dlami/nvme` にアタッチされている NVMe ストレージを使用し、インストールスクリプトが設定プロセスを処理する必要があります。

**ルートパスが正しく設定されているかどうかを確認するには**

SageMaker HyperPod の Slurm クラスターのコンピューティングノードで、次のコマンドを実行して、ライフサイクルスクリプトが正常に動作し、各ノードのルートボリュームが `/opt/dlami/nvme/*` に設定されていることを確認します。次のコマンドは、Slurm クラスターの 8 つのコンピューティングノードの Enroot ランタイムパスとデータルートパスを確認する例を示しています。

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

ランタイムパスが `/opt/dlami/nvme/*` に正しく設定されていることを確認したら、Enroot と Pyxis を使用して Docker コンテナを構築および実行する準備が整います。

**Slurm で Docker をテストするには**

1. コンピューティングノードで、次のコマンドを試して、Docker と Enroot が正しくインストールされているかどうかを確認します。

   ```
   $ docker --help
   $ enroot --help
   ```

1. [NVIDIA CUDA Ubuntu](https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cuda) イメージのいずれかを実行することにより、Pyxis と Enroot が正しくインストールされているかどうかをテストします。

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

   次のようにスクリプトを作成して`sbatch` コマンドを実行することによりテストすることもできます。

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

**Docker でテスト Slurm ジョブを実行するには**

Docker で Slurm の設定が完了したら、構築済み Docker イメージを持ち込み、SageMaker HyperPod で Slurm を使用して実行することができます。以下に、SageMaker HyperPod で Docker と Slurm を使用してトレーニングジョブを実行する方法を説明するユースケースの例を示します。これは、SageMaker AI モデル並列処理 (SMP) ライブラリを使用した Llama 2 モデルのモデル並列トレーニングのサンプルジョブです。

1. SageMaker AI または DLC によって配布されるビルド済み ECR イメージのいずれかを使用する場合は、[SageMaker HyperPod の IAM ロール](sagemaker-hyperpod-prerequisites-iam.md#sagemaker-hyperpod-prerequisites-iam-role-for-hyperpod) 経由で ECR イメージをプルするアクセス許可を HyperPod クラスターに付与します。独自のイメージまたはオープンソースの Docker イメージを使用する場合、このステップをスキップできます。[SageMaker HyperPod の IAM ロール](sagemaker-hyperpod-prerequisites-iam.md#sagemaker-hyperpod-prerequisites-iam-role-for-hyperpod) に次のアクセス許可を追加します。このチュートリアルでは、SMP ライブラリを使用してパッケージ化された [SMP Docker イメージ](distributed-model-parallel-support-v2.md#distributed-model-parallel-supported-frameworks-v2)を使用します。

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

****  

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

------

1. コンピューティングノードで、リポジトリのクローンを作成し、SMP を使用したトレーニングのスクリプト例を提供するフォルダに移動します。

   ```
   $ git clone https://github.com/aws-samples/awsome-distributed-training/
   $ cd awsome-distributed-training/3.test_cases/17.SM-modelparallelv2
   ```

1. このチュートリアルでは、SMP Docker イメージをプルして、Docker コンテナを構築し、Enroot ランタイムとして実行するサンプルスクリプト [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) を実行します。これは、必要に応じて変更できます。

   ```
   $ 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. `sbatch` を使用してトレーニングジョブを起動するバッチスクリプトを作成します。このチュートリアルでは、提供されたサンプルスクリプト [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) が、8 つのコンピューティングノードに合成データセットを持つ、パラメータ数が 700 億の Llama 2 モデルのモデル並列トレーニングジョブを起動します。トレーニングスクリプトのセットは [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) で提供されており、`launch_training_enroot.sh` はエントリポイントスクリプトとして `train_external.py` を使用します。
**重要**  
SageMaker HyperPod で Docker コンテナを使用するには、ホストマシン (このケースでは HyperPod コンピューティングノード) からコンテナ内の `/var/log` ディレクトリに `/var/log` ディレクトリをマウントする必要があります。これは、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}}
   ```

ダウンロード可能なコード例については、「*Awsome Distributed Training GitHub リポジトリ*」の「[SageMaker AI モデル並列処理ライブラリ、Docker、Enroot with 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)」を参照してください。SageMaker HyperPod の Slurm クラスターを使用した分散トレーニングの詳細については、「[HyperPod で Slurm を使用して分散トレーニングワークロードを実行する](sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload.md)」の次のトピックを参照してください。