

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# SageMaker HyperPod 叢集上的任務
<a name="sagemaker-hyperpod-run-jobs-slurm"></a>

下列主題提供在佈建的 SageMaker HyperPod 叢集上存取運算節點和執行 ML 工作負載的程序和範例。根據您在 HyperPod 叢集上設定環境的方式，在 HyperPod 叢集上執行 ML 工作負載的方法有很多種。[Awsome 分散式訓練 GitHub 儲存庫](https://github.com/aws-samples/awsome-distributed-training/)中也提供在 HyperPod 叢集上執行 ML 工作負載的範例。下列主題會逐步解說如何登入佈建的 HyperPod 叢集，並讓您開始執行範例 ML 工作負載。

**提示**  
若要尋找實際範例和解決方案，另請參閱 [SageMaker HyperPod 工作坊](https://catalog.workshops.aws/sagemaker-hyperpod)。

**Topics**
+ [存取您的 SageMaker HyperPod 叢集節點](sagemaker-hyperpod-run-jobs-slurm-access-nodes.md)
+ [在 SageMaker HyperPod 叢集上排程 Slurm 任務](sagemaker-hyperpod-run-jobs-slurm-schedule-slurm-job.md)
+ [在 HyperPod 的 Slurm 運算節點上執行 Docker 容器](sagemaker-hyperpod-run-jobs-slurm-docker.md)
+ [在 HyperPod 上使用 Slurm 執行分散式訓練工作負載](sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload.md)

# 存取您的 SageMaker HyperPod 叢集節點
<a name="sagemaker-hyperpod-run-jobs-slurm-access-nodes"></a>

您可以使用 SageMaker HyperPod 叢集主機名稱的格式執行 AWS CLI 命令`aws ssm start-session`，透過 AWS Systems Manager (SSM) 存取 **InService** 叢集`sagemaker-cluster:[cluster-id]_[instance-group-name]-[instance-id]`。您可以從 [SageMaker HyperPod 主控台](sagemaker-hyperpod-operate-slurm-console-ui.md#sagemaker-hyperpod-operate-slurm-console-ui-view-details-of-clusters)或是從 [SageMaker HyperPod 的AWS CLI 命令](sagemaker-hyperpod-operate-slurm-cli-command.md#sagemaker-hyperpod-operate-slurm-cli-command-list-cluster-nodes)執行 `describe-cluster` 和 `list-cluster-nodes`，擷取叢集 ID、執行個體 ID 和執行個體群組名稱。例如，如果您的叢集 ID 為 `aa11bbbbb222`、叢集節點名稱為 `controller-group`，而叢集節點 ID 為 `i-111222333444555aa`，則 SSM `start-session` 命令應該如下。

**注意**  
授予使用者 HyperPod 叢集節點的存取權，可讓使用者在節點上安裝和操作使用者受管軟體。確保您維護使用者最低權限許可的原則。  
如果您尚未設定 AWS Systems Manager，請遵循 提供的指示[設定 AWS Systems Manager 和執行為叢集使用者存取控制](sagemaker-hyperpod-prerequisites.md#sagemaker-hyperpod-prerequisites-ssm)。

```
$ aws ssm start-session \
    --target sagemaker-cluster:aa11bbbbb222_controller-group-i-111222333444555aa \
    --region us-west-2
Starting session with SessionId: s0011223344aabbccdd
root@ip-111-22-333-444:/usr/bin#
```

請注意，這最初會將您連線為根使用者。在執行任務之前，請執行下列命令來切換到 `ubuntu` 使用者。

```
root@ip-111-22-333-444:/usr/bin# sudo su - ubuntu
ubuntu@ip-111-22-333-444:/usr/bin#
```

如需 HyperPod 叢集實際使用的進階設定，請參閱下列主題。

**Topics**
+ [存取 SageMaker HyperPod 叢集節點的其他秘訣](#sagemaker-hyperpod-run-jobs-slurm-access-nodes-tips)
+ [透過 Amazon FSx 共用空間設定多使用者環境](#sagemaker-hyperpod-run-jobs-slurm-access-nodes-multi-user-with-fxs-shared-space)
+ [透過將 HyperPod 叢集與 Active Directory 整合來設定多使用者環境](#sagemaker-hyperpod-run-jobs-slurm-access-nodes-multi-user-with-active-directory)

## 存取 SageMaker HyperPod 叢集節點的其他秘訣
<a name="sagemaker-hyperpod-run-jobs-slurm-access-nodes-tips"></a>

**使用 HyperPod 提供的 `easy-ssh.sh` 指令碼來簡化連線程序**

為了將先前的程序變成單行命令，HyperPod 團隊會提供 [https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/easy-ssh.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/easy-ssh.sh) 指令碼，擷取叢集資訊、將其彙總到 SSM 命令，以及連線至運算節點。您不需要手動尋找所需的 HyperPod 叢集資訊，因為此指令碼會執行 `describe-cluster` 和 `list-cluster-nodes` 命令，並剖析完成 SSM 命令所需的資訊。下列範例命令顯示如何執行 [https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/easy-ssh.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/easy-ssh.sh) 指令碼。如果成功執行，您將以根使用者身分連線到叢集。它也會列印程式碼片段，透過 SSM Proxy 將 HyperPod 叢集新增為遠端主機來設定 SSH。透過設定 SSH，您可以將 Visual Studio Code 等本機開發環境與 HyperPod 叢集連線。

```
$ chmod +x easy-ssh.sh
$ ./easy-ssh.sh -c <node-group> <cluster-name>
Cluster id: <cluster_id>
Instance id: <instance_id>
Node Group: <node-group>
Add the following to your ~/.ssh/config to easily connect:

$ cat <<EOF >> ~/.ssh/config
Host <cluster-name>
  User ubuntu
  ProxyCommand sh -c "aws ssm start-session  --target sagemaker-cluster:<cluster_id>_<node-group>-<instance_id> --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
EOF

Add your ssh keypair and then you can do:

$ ssh <cluster-name>

aws ssm start-session --target sagemaker-cluster:<cluster_id>_<node-group>-<instance_id>

Starting session with SessionId: s0011223344aabbccdd
root@ip-111-22-333-444:/usr/bin#
```

請注意，這最初會將您連線為根使用者。在執行任務之前，請執行下列命令來切換到 `ubuntu` 使用者。

```
root@ip-111-22-333-444:/usr/bin# sudo su - ubuntu
ubuntu@ip-111-22-333-444:/usr/bin#
```

**使用 HyperPod 運算節點做為遠端主機，設定透過 SSH 輕鬆存取**

為了進一步簡化從本機電腦使用 SSH 存取運算節點，`easy-ssh.sh` 指令碼會輸出程式碼片段，將 HyperPod 叢集設定為遠端主機，如上節所示。此程式碼片段會自動產生，以協助您直接新增至本機裝置上的 `~/.ssh/config` 檔案。下列程序說明如何設定透過 SSM Proxy 使用 SSH 輕鬆存取，以便您或您的叢集使用者可以直接執行 `ssh <cluster-name>` 以連線至 HyperPod 叢集節點。

1. 在本機裝置上，將具有使用者名稱的 HyperPod 運算節點做為遠端主機新增至 `~/.ssh/config` 檔案。下列命令顯示如何將自動產生的程式碼片段從 `easy-ssh.sh` 指令碼附加至 `~/.ssh/config` 檔案。確定您從 `easy-ssh.sh` 指令碼自動產生且具有正確叢集資訊的輸出中複製它。

   ```
   $ cat <<EOF >> ~/.ssh/config
   Host <cluster-name>
     User ubuntu
     ProxyCommand sh -c "aws ssm start-session  --target sagemaker-cluster:<cluster_id>_<node-group>-<instance_id> --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
   EOF
   ```

1. 在 HyperPod 叢集節點上，將本機裝置上的公有金鑰新增至 HyperPod 叢集節點上的 `~/.ssh/authorized_keys` 檔案。

   1. 在本機電腦上列印公有金鑰檔案。

      ```
      $ cat ~/.ssh/id_rsa.pub
      ```

      這應該會傳回您的金鑰。複製此命令的輸出。

      (選用) 如果您沒有公有金鑰，請執行下列命令建立一個。

      ```
      $ ssh-keygen -t rsa -q -f "$HOME/.ssh/id_rsa" -N ""
      ```

   1. 連線至叢集節點，並切換到使用者以新增金鑰。下列命令是以 `ubuntu` 使用者身分存取的範例。將 `ubuntu` 取代為您想要使用 SSH 設定輕鬆存取的使用者名稱。

      ```
      $ ./easy-ssh.sh -c <node-group> <cluster-name>
      $ sudo su - ubuntu
      ubuntu@ip-111-22-333-444:/usr/bin#
      ```

   1. 開啟 `~/.ssh/authorized_keys` 檔案，並在檔案結尾新增公有金鑰。

      ```
      ubuntu@ip-111-22-333-444:/usr/bin# vim ~/.ssh/authorized_keys
      ```

完成設定後，您可以執行簡化的 SSH 命令，以使用者身分連線至 HyperPod 叢集節點，如下所示。

```
$ ssh <cluster-name>
ubuntu@ip-111-22-333-444:/usr/bin#
```

此外，您可以使用主機從本機裝置上的 IDE 進行遠端開發，例如 [Visual Studio Code Remote - SSH](https://code.visualstudio.com/docs/remote/ssh)。

## 透過 Amazon FSx 共用空間設定多使用者環境
<a name="sagemaker-hyperpod-run-jobs-slurm-access-nodes-multi-user-with-fxs-shared-space"></a>

您可以使用 Amazon FSx 共用空間，管理 SageMaker HyperPod 上 Slurm 叢集中的多使用者環境。如果您在 HyperPod 叢集建立期間已使用 Amazon FSx 設定 Slurm 叢集，這是為叢集使用者設定工作區的好選項。建立新的使用者，並在 Amazon FSx 共用檔案系統上設定使用者的主目錄。

**提示**  
若要允許使用者透過其使用者名稱和專用目錄存取您的叢集，您也應該依照《 AWS Systems Manager 使用者指南》中[開啟 Linux 和 macOS 受管節點的執行身分支援](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-preferences-run-as.html)提供的程序**開啟 Linux 和 macOS 受管節點的執行身分支援**下步驟 5 的**選項 2** 中的指引，將它們與 IAM 角色或使用者建立關聯。另請參閱[設定 AWS Systems Manager 和執行為叢集使用者存取控制](sagemaker-hyperpod-prerequisites.md#sagemaker-hyperpod-prerequisites-ssm)。

**在 SageMaker HyperPod 上建立 Slurm 叢集時設定多使用者環境**

SageMaker HyperPod 服務團隊會提供指令碼 [https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/add_users.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/add_users.sh) 做為基本生命週期指令碼範例的一部分。

1. 準備名為 `shared_users.txt` 的文字檔案，您需要以下列格式建立該文字檔案。第一欄用於使用者名稱、第二欄用於唯一使用者 ID，而第三欄用於 Amazon FSx 共用空間中的使用者目錄。

   ```
   username1,uid1,/fsx/username1
   username2,uid2,/fsx/username2
   ...
   ```

1. 確定您將 `shared_users.txt` 和 [https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/add_users.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/add_users.sh) 檔案上傳至 HyperPod 生命週期指令碼的 S3 儲存貯體。當叢集建立、叢集更新或叢集軟體更新正在進行時，[https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/add_users.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/1.architectures/5.sagemaker-hyperpod/LifecycleScripts/base-config/add_users.sh) 會在 `shared_users.txt` 中讀取並正確設定使用者目錄。

**建立新的使用者，並將其新增至 SageMaker HyperPod 上執行的現有 Slurm 叢集**

1. 在主節點上執行下列命令，以儲存有助於建立使用者的指令碼。確定您透過 sudo 許可來執行此操作。

   ```
   $ cat > create-user.sh << EOL
   #!/bin/bash
   
   set -x
   
   # Prompt user to get the new user name.
   read -p "Enter the new user name, i.e. 'sean': 
   " USER
   
   # create home directory as /fsx/<user>
   # Create the new user on the head node
   sudo useradd \$USER -m -d /fsx/\$USER --shell /bin/bash;
   user_id=\$(id -u \$USER)
   
   # add user to docker group
   sudo usermod -aG docker \${USER}
   
   # setup SSH Keypair
   sudo -u \$USER ssh-keygen -t rsa -q -f "/fsx/\$USER/.ssh/id_rsa" -N ""
   sudo -u \$USER cat /fsx/\$USER/.ssh/id_rsa.pub | sudo -u \$USER tee /fsx/\$USER/.ssh/authorized_keys
   
   # add user to compute nodes
   read -p "Number of compute nodes in your cluster, i.e. 8: 
   " NUM_NODES
   srun -N \$NUM_NODES sudo useradd -u \$user_id \$USER -d /fsx/\$USER --shell /bin/bash;
   
   # add them as a sudoer
   read -p "Do you want this user to be a sudoer? (y/N):
   " SUDO
   if [ "\$SUDO" = "y" ]; then
           sudo usermod -aG sudo \$USER
           sudo srun -N \$NUM_NODES sudo usermod -aG sudo \$USER
           echo -e "If you haven't already you'll need to run:\n\nsudo visudo /etc/sudoers\n\nChange the line:\n\n%sudo   ALL=(ALL:ALL) ALL\n\nTo\n\n%sudo   ALL=(ALL:ALL) NOPASSWD: ALL\n\nOn each node."
   fi
   EOL
   ```

1. 使用下列命令執行指令碼。系統會提示您新增使用者的名稱，以及您要允許使用者存取的運算節點數量。

   ```
   $ bash create-user.sh
   ```

1. 執行下列命令測試使用者。

   ```
   $ sudo su - <user> && ssh $(srun hostname)
   ```

1. 將使用者資訊新增至 `shared_users.txt` 檔案，以便使用者將在任何新的運算節點或新的叢集上建立。

## 透過將 HyperPod 叢集與 Active Directory 整合來設定多使用者環境
<a name="sagemaker-hyperpod-run-jobs-slurm-access-nodes-multi-user-with-active-directory"></a>

在實際使用案例中，HyperPod 叢集通常由多個使用者使用：機器學習 (ML) 研究人員、軟體工程師、資料科學家和叢集管理員。他們編輯自己的檔案並執行自己的任務，而不會影響彼此的工作。若要設定多使用者環境，請使用 Linux 使用者和群組機制，透過生命週期指令碼在每個執行個體上靜態建立多個使用者。不過，此方法的缺點是，您需要跨叢集中的多個執行個體複製使用者和群組設定，才能在進行新增、編輯和移除使用者等更新時，在所有執行個體之間保持一致的組態。

若要解決此問題，您可以使用[輕量型目錄存取通訊協定 (LDAP)](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) 和 [LDAP over TLS/SSL (LDAPS)](https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol) 與目錄服務整合，例如 [AWS Directory Service for Microsoft Active Directory](https://aws.amazon.com/directoryservice/)。若要進一步了解如何在 HyperPod 叢集中設定 Active Directory 和多使用者環境，請參閱部落格文章[將 HyperPod 叢集與 Active Directory 整合，以進行多使用者無縫登入](https://aws.amazon.com/blogs/machine-learning/integrate-hyperpod-clusters-with-active-directory-for-seamless-multi-user-login/)。

# 在 SageMaker HyperPod 叢集上排程 Slurm 任務
<a name="sagemaker-hyperpod-run-jobs-slurm-schedule-slurm-job"></a>

您可以使用標準 Slurm `sbatch` 或 `srun` 命令來啟動訓練任務。例如，若要啟動 8 節點訓練任務，您可以執行 `srun -N 8 --exclusive train.sh` SageMaker HyperPod 支援在各種環境中進行訓練，包括 `conda`、`venv` `docker` 和 `enroot`。您可以在 SageMaker HyperPod 叢集上執行生命週期指令碼來設定 ML 環境。您也可以選擇連接也可以用作虛擬環境的共用檔案系統，例如 Amazon FSx。

下列範例展示如何在具有 Amazon FSx 共用檔案系統的 SageMaker HyperPod 叢集上，執行使用全碎片資料平行化 (FSDP) 技術訓練 Llama-2 的任務。您也可以從 [Awsome 分散式訓練 GitHub 儲存庫](https://github.com/aws-samples/awsome-distributed-training/)找到更多範例。

**提示**  
所有 SageMaker HyperPod 範例都可在 [Awsome 分散式訓練 GitHub 儲存庫](https://github.com/aws-samples/awsome-distributed-training/)的 `3.test_cases` 資料夾中取得。

1. 複製 [Awsome 分散式訓練 GitHub 儲存庫](https://github.com/aws-samples/awsome-distributed-training/)，並將訓練任務範例複製到您的 Amazon FSx 檔案系統。

   ```
   $ TRAINING_DIR=/fsx/users/my-user/fsdp
   $ git clone https://github.com/aws-samples/awsome-distributed-training/
   ```

1. 執行 [https://github.com/aws-samples/awsome-distributed-training/blob/main/3.test_cases/10.FSDP/0.create_conda_env.sh](https://github.com/aws-samples/awsome-distributed-training/blob/main/3.test_cases/10.FSDP/0.create_conda_env.sh) 指令碼。這會在 Amazon FSx 檔案系統上建立 `conda` 環境。確定叢集中的所有節點都可以存取檔案系統。

1. 透過啟動單一節點 Slurm 任務來建置虛擬 Conda 環境，如下所示。

   ```
   $ srun -N 1 /path_to/create_conda_env.sh
   ```

1. 建置環境後，您可以透過指向共用磁碟區上的環境路徑來啟動訓練任務。您可以使用相同的設定來啟動單一節點和多節點訓練任務。若要啟動任務，請建立任務啟動器指令碼 (也稱為進入點指令碼)，如下所示。

   ```
   #!/usr/bin/env bash
   set -ex
   
   ENV_PATH=/fsx/users/my_user/pytorch_env
   TORCHRUN=$ENV_PATH/bin/torchrun
   TRAINING_SCRIPT=/fsx/users/my_user/pt_train.py
   
   WORLD_SIZE_JOB=$SLURM_NTASKS
   RANK_NODE=$SLURM_NODEID
   PROC_PER_NODE=8
   MASTER_ADDR=(`scontrol show hostnames \$SLURM_JOB_NODELIST | head -n 1`)
   MASTER_PORT=$(expr 10000 + $(echo -n $SLURM_JOBID | tail -c 4))
   
   DIST_ARGS="--nproc_per_node=$PROC_PER_NODE \
              --nnodes=$WORLD_SIZE_JOB \
              --node_rank=$RANK_NODE \
              --master_addr=$MASTER_ADDR \
              --master_port=$MASTER_PORT \
             "
             
   $TORCHRUN $DIST_ARGS $TRAINING_SCRIPT
   ```
**提示**  
如果您想要使用 SageMaker HyperPod 的自動繼續功能，讓您的訓練任務對硬體故障更具彈性，則需要在進入點指令碼中正確設定環境變數 `MASTER_ADDR`。如需詳細資訊，請參閱 [自動節點復原和自動恢復](sagemaker-hyperpod-resiliency-slurm-auto-resume.md)。

   本教學假設此指令碼儲存為 `/fsx/users/my_user/train.sh`。

1. 在 `/fsx/users/my_user/train.sh` 的共用磁碟區中使用此指令碼，執行下列 `srun` 命令來排程 Slurm 任務。

   ```
   $ cd /fsx/users/my_user/
   $ srun -N 8 train.sh
   ```

# 在 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) 指令碼中，有一個 `Config` 類別具有布林值類型參數，用於安裝設定為 `True` (`enable_docker_enroot_pyxis=True`) 的套件。這由 [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 容器，則該磁碟區將耗盡。如果您使用 P 和 G 等執行個體系列搭配本機 NVMe 儲存體，則需要確保您使用 `/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-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                                                 |
   +-----------------------------------------------------------------------------+
   ```

   您也可以建立指令碼並執行 `sbatch` 命令來進行測試，如下所示。

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

**使用 Docker 執行測試 Slurm 任務**

使用 Docker 完成了 Slurm 設定後，您可以攜帶任何預先建置的 Docker 映像，並在 SageMaker HyperPod 上使用 Slurm 執行這些映像。以下是範例使用案例，逐步引導您如何在 SageMaker HyperPod 上使用 Docker 和 Slurm 執行訓練任務。它顯示如何使用 SageMaker AI 模型平行化 (SMP) 程式庫以模型平行化方式訓練 Llama 2 模型的範例任務。

1. 如果您想要使用 SageMaker AI 或 DLC 分發的其中一個預先建置 ECR 映像，請確定您授予 HyperPod 叢集透過 [SageMaker HyperPod 的 IAM 角色](sagemaker-hyperpod-prerequisites-iam.md#sagemaker-hyperpod-prerequisites-iam-role-for-hyperpod) 提取 ECR 映像的許可。如果您使用自己的映像或開放原始碼 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. 在本教學課程中，執行範例指令碼 [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)，提取 SMP Docker 映像檔、建置 Docker 容器，並將其做為 Enroot 執行時期執行。您可以視需要進行修改。

   ```
   $ 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) 會啟動 700 億參數 Llama 2 模型的模型平行化訓練任務，搭配 8 個運算節點上的合成資料集。在 [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 容器，您必須從主機電腦將 `/var/log` 目錄掛載到容器中的 `/var/log` 目錄，在此案例中，該主機電腦是 HyperPod 運算節點。您可以為 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 分散式訓練 GitHub 儲存庫」**中的[使用 SageMaker AI 模型平行化程式庫、Docker 和 Enroot 搭配 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)中的下一個主題。

# 在 HyperPod 上使用 Slurm 執行分散式訓練工作負載
<a name="sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload"></a>

SageMaker HyperPod 專門用於訓練大型語言模型 (LLM) 和基礎模型 (FM) 的工作負載。這些工作負載通常需要針對 ML 基礎設施和資源使用多個平行化技術和最佳化的操作。使用 SageMaker HyperPod，您可以使用下列 SageMaker AI 分散式訓練架構：
+ [SageMaker AI 分散式資料平行化 (SMDDP) 程式庫](data-parallel.md)，可提供針對 AWS最佳化的集體通訊操作。
+ [SageMaker AI 模型平行化 (SMP) 程式庫](model-parallel-v2.md)，可實作各種模型平行化技術。

**Topics**
+ [在 SageMaker HyperPod 上使用 SMDDP](#sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload-smddp)
+ [在 SageMaker HyperPod 叢集上使用 SMP HyperPod](#sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload-smp)

## 在 SageMaker HyperPod 上使用 SMDDP
<a name="sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload-smddp"></a>

[SMDDP 程式庫](data-parallel.md)是集體通訊程式庫，可改善分散式資料平行訓練的運算效能。SMDDP 程式庫使用下列開放原始碼分散式訓練架構：
+ [PyTorch 分散式資料平行 (DDP)](https://pytorch.org/docs/stable/notes/ddp.html)
+ [PyTorch 全碎片資料平行化 (FSDP)](https://pytorch.org/docs/stable/fsdp.html)
+ [DeepSpeed](https://github.com/microsoft/DeepSpeed)
+ [Megatron-DeepSpeed](https://github.com/microsoft/Megatron-DeepSpeed)

SMDDP 程式庫透過為 SageMaker HyperPod 提供下列項目，解決金鑰集體通訊操作的通訊負荷。
+ 程式庫提供 `AllGather` 最佳化 AWS。 `AllGather` 是一種用於碎片資料平行訓練的金鑰操作，這是一種由熱門程式庫提供的記憶體效率資料平行處理技術。其中包括 SageMaker AI 模型平行化 (SMP) 程式庫、DeepSpeed 零冗餘最佳化工具 (ZeRO) 和 PyTorch 全碎片資料平行化 (FSDP)。
+ 程式庫會透過充分利用 AWS 網路基礎設施和 SageMaker AI ML 執行個體拓撲來執行最佳化node-to-node通訊。

**執行範例資料平行訓練任務**

探索下列使用 SMDDP 程式庫實作資料平行化技術的分散式訓練範例。
+ [https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/12.SM-dataparallel-FSDP](https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/12.SM-dataparallel-FSDP)
+ [https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/13.SM-dataparallel-deepspeed](https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/13.SM-dataparallel-deepspeed)

**設定在 SageMaker HyperPod 上使用 SMDDP 程式庫的環境**

以下是在 SageMaker HyperPod 上使用 SMDDP 程式庫的訓練環境要求。
+ PyTorch v2.0.1 及更新版本
+ CUDA v11.8 及更新版本
+ 大於 3 的 `libstdc++` 執行時期版本
+ Python v3.10.x 及更新版本
+ `ml.p4d.24xlarge` 和 `ml.p4de.24xlarge`，這是 SMDDP 程式庫支援的執行個體類型
+ 在訓練主機上啟用 `imdsv2`

根據您想要執行分散式訓練任務的方式，有兩種安裝 SMDDP 程式庫的選項：
+ 使用 SMDDP 二進位檔案的直接安裝。
+ 使用預先安裝了 SMDDP 程式庫的 SageMaker AI 深度學習容器 (DLC)。

預先安裝了 SMDDP 程式庫的 Docker 映像檔或 SMDDP 二進位檔案的 URL 會列示在 SMDDP 程式庫文件中[支援的架構](https://docs.aws.amazon.com/sagemaker/latest/dg/distributed-data-parallel-support.html#distributed-data-parallel-supported-frameworks)。

**在 SageMaker HyperPod DLAMI 上安裝 SMDDP 程式庫**
+ `pip install --no-cache-dir https://smdataparallel.s3.amazonaws.com/binary/pytorch/<pytorch-version>/cuXYZ/YYYY-MM-DD/smdistributed_dataparallel-X.Y.Z-cp310-cp310-linux_x86_64.whl`
**注意**  
如果您在 Conda 環境中工作，請確定您使用 `conda install` 而非 `pip` 安裝 PyTorch。  

  ```
  conda install pytorch==X.Y.Z  torchvision==X.Y.Z torchaudio==X.Y.Z pytorch-cuda=X.Y.Z -c pytorch -c nvidia
  ```

**在 Docker 容器上使用 SMDDP 程式庫**
+ SMDDP 程式庫會預先安裝在 SageMaker AI 深度學習容器 (DLC) 上。若要使用 SMDDP 程式庫尋找 PyTorch 的 SageMaker AI 架構 DLC 清單，請參閱 SMDDP 程式庫文件中[支援的架構](https://docs.aws.amazon.com/sagemaker/latest/dg/distributed-data-parallel-support.html#distributed-data-parallel-supported-frameworks)。您也可以自帶已安裝必要相依性的 Docker 容器來使用 SMDDP 程式庫。若要進一步了解如何設定自訂 Docker 容器以使用 SMDDP 程式庫，另請參閱[使用 SageMaker AI 分散式資料平行程式庫建立您自己的 Docker 容器](data-parallel-bring-your-own-container.md)。
**重要**  
若要在 Docker 容器中使用 SMDDP 程式庫，請將 `/var/log` 目錄從主機電腦掛載到容器中的 `/var/log`。您可以在執行容器時新增下列選項來完成此操作。  

  ```
  docker run <OTHER_OPTIONS> -v /var/log:/var/log ...
  ```

若要了解通常如何使用 SMDDP 執行資料平行訓練任務，請參閱[使用 SageMaker AI 分散式資料平行化程式庫進行分散式訓練](data-parallel-modify-sdp.md)。

## 在 SageMaker HyperPod 叢集上使用 SMP HyperPod
<a name="sagemaker-hyperpod-run-jobs-slurm-distributed-training-workload-smp"></a>

[SageMaker AI 模型平行化 (SMP) 程式庫](model-parallel-v2.md)提供各種[最先進的模型平行化技術](model-parallel-core-features-v2.md)，包括：
+ 全碎片資料平行化
+ 專家平行化
+ 使用 FP16/BF16 和 FP8 資料類型的混合精確度訓練
+ 張量平行化

SMP 程式庫也與 PyTorch FSDP、NVIDIA Megatron 和 NVIDIA 轉換器引擎等開放原始碼架構相容。

**執行範例模型平行化訓練工作負載**

SageMaker AI 服務團隊在 [https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/17.SM-modelparallelv2](https://github.com/aws-samples/awsome-distributed-training/tree/main/3.test_cases/17.SM-modelparallelv2) 提供使用 SMP 程式庫實作模型平行化的範例訓練任務。