

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

# 在異質叢集上執行訓練任務
<a name="train-heterogeneous-cluster"></a>

透過 SageMaker 訓練的異質叢集功能，您可以使用多種類型的機器學習 (ML) 執行個體執行訓練任務，以便針對不同的機器學習 (ML) 訓練任務和目的提供更完善的資源擴展與使用率。例如，若在具有 GPU 執行個體的叢集上之訓練任務因 CPU 密集任務而遭受低 GPU 使用率和 CPU 瓶頸問題，則使用異質叢集可透過新增更具成本效益的 CPU 執行個體群組，來妥善卸載 CPU 密集型任務、解決此類瓶頸問題，並達到更佳的 GPU 使用率。

**注意**  
此功能可在 SageMaker Python SDK v2.98.0 及較新版本中取得。

**注意**  
這項功能可透過 SageMaker AI [PyTorch](https://sagemaker.readthedocs.io/en/stable/frameworks/pytorch/sagemaker.pytorch.html) 和 [TensorFlow](https://sagemaker.readthedocs.io/en/stable/frameworks/tensorflow/sagemaker.tensorflow.html#tensorflow-estimator) 架構估算器類別取得。系統支援的架構為 PyTorch v1.10 或較新版本，以及 TensorFlow v2.6 或較新版本。

請參閱部落格[使用 Amazon SageMaker AI 異質叢集改善模型訓練的價格效能](https://aws.amazon.com/blogs/machine-learning/improve-price-performance-of-your-model-training-using-amazon-sagemaker-heterogeneous-clusters/)。

**Topics**
+ [在 Amazon SageMaker AI 中使用異質叢集設定訓練任務](train-heterogeneous-cluster-configure.md)
+ [在 Amazon SageMaker AI 的異質叢集上執行分散式訓練](train-heterogeneous-cluster-configure-distributed.md)
+ [修改訓練指令碼以指派執行個體群組](train-heterogeneous-cluster-modify-training-script.md)

# 在 Amazon SageMaker AI 中使用異質叢集設定訓練任務
<a name="train-heterogeneous-cluster-configure"></a>

本節提供如何使用包含多個執行個體類型的異質叢集來執行訓練任務之說明。

開始之前，請注意下列事項。
+ 所有執行個體群組都共用相同的 Docker 映像和訓練指令碼。因此，您應該修改訓練指令碼，以偵測它所屬的執行個體群組，並相應地進行 fork 執行。
+ SageMaker AI 本機模式不相容於異質叢集功能。
+ 異質叢集訓練任務的 Amazon CloudWatch 日誌串流不會依執行個體群組分組。您需要從日誌中找出哪些節點在哪個群組中。

**Topics**
+ [選項 1：使用 SageMaker Python SDK](#train-heterogeneous-cluster-configure-pysdk)
+ [選項 2：使用低階 SageMaker API](#train-heterogeneous-cluster-configure-api)

## 選項 1：使用 SageMaker Python SDK
<a name="train-heterogeneous-cluster-configure-pysdk"></a>

請遵循有關如何使用 SageMaker Python SDK 為異質叢集設定執行個體群組的指示。

1. 若要針對訓練任務配置異質叢集的執行個體群組，請使用 `sagemaker.instance_group.InstanceGroup` 類別。您可以為每個執行個體群組指定自訂名稱、執行個體類型，以及每個執行個體群組的執行個體數目。如需更多資訊，請參閱 *SageMaker AI Python SDK 文件*中的 [sagemaker.instance\$1group.InstanceGroup](https://sagemaker.readthedocs.io/en/stable/api/utility/instance_group.html)。
**注意**  
如需有關可用執行個體類型和可在異質叢集中設定的執行個體數目上限等詳細資訊，請參閱 [InstanceGroup](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_InstanceGroup.html) API 參考資料。

   下列程式碼範例說明如何設定兩個執行個體群組，這兩個執行個體群組包含兩個名為 `instance_group_1` 的 `ml.c5.18xlarge` 僅限 CPU 執行個體，以及一個名為 `instance_group_2` 的 `ml.p3dn.24xlarge` GPU 執行個體，如下圖所示。  
![\[如何在 SageMaker 訓練任務中指派資料的概念性範例。\]](http://docs.aws.amazon.com/zh_tw/sagemaker/latest/dg/images/HCTraining.png)

   上圖的概念性範例說明如何將預先訓練程序 (例如資料預先處理) 指派給 CPU 執行個體群組，並將預先處理的資料串流至 GPU 執行個體群組。

   ```
   from sagemaker.instance_group import InstanceGroup
   
   instance_group_1 = InstanceGroup(
       "instance_group_1", "ml.c5.18xlarge", 2
   )
   instance_group_2 = InstanceGroup(
       "instance_group_2", "ml.p3dn.24xlarge", 1
   )
   ```

1. 使用執行個體群組物件，設定訓練輸入頻道，並透過 [sagemaker.inputs.TrainingInput](https://sagemaker.readthedocs.io/en/stable/api/utility/inputs.html) 的 `instance_group_names` 引數，將執行個體群組指派給頻道。`instance_group_names` 引數會接受執行個體群組名稱的字串清單。

   下列範例顯示如何設定兩個訓練輸入頻道，並指派在上一個步驟範例中建立的執行個體群組。您也可以指定 Amazon S3 儲存貯體的 `s3_data` 引數路徑，讓執行個體群組為您的使用目的處理資料。

   ```
   from sagemaker.inputs import TrainingInput
   
   training_input_channel_1 = TrainingInput(
       s3_data_type='S3Prefix', # Available Options: S3Prefix | ManifestFile | AugmentedManifestFile
       s3_data='s3://your-training-data-storage/folder1',
       distribution='FullyReplicated', # Available Options: FullyReplicated | ShardedByS3Key 
       input_mode='File', # Available Options: File | Pipe | FastFile
       instance_groups=["instance_group_1"]
   )
   
   training_input_channel_2 = TrainingInput(
       s3_data_type='S3Prefix',
       s3_data='s3://your-training-data-storage/folder2',
       distribution='FullyReplicated',
       input_mode='File',
       instance_groups=["instance_group_2"]
   )
   ```

   如需 `TrainingInput` 引數的詳細資訊，請參閱以下連結。
   + *SageMaker Python SDK 文件*中的 [sagemaker.inputs.TrainingInput](https://sagemaker.readthedocs.io/en/stable/api/utility/inputs.html) 類別
   + *SageMaker AI API 參考*中的 [S3DataSource](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_S3DataSource.html) API

1. 使用 `instance_groups` 引數設定 SageMaker AI 估算器，如下列程式碼範例所示。`instance_groups` 引數接受 `InstanceGroup` 物件的清單。
**注意**  
異質叢集功能可透過 SageMaker AI [PyTorch](https://sagemaker.readthedocs.io/en/stable/frameworks/pytorch/sagemaker.pytorch.html) 和 [TensorFlow](https://sagemaker.readthedocs.io/en/stable/frameworks/tensorflow/sagemaker.tensorflow.html#tensorflow-estimator) 架構估算器類別取得。系統支援的架構為 PyTorch v1.10 或較新版本，以及 TensorFlow v2.6 或較新版本。若要尋找可用架構容器、架構版本和 Python 版本的完整清單，請參閱 AWS 深度學習容器 GitHub 儲存庫中的 [SageMaker AI Framework Containers](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only)。

------
#### [ PyTorch ]

   ```
   from sagemaker.pytorch import PyTorch
   
   estimator = PyTorch(
       ...
       entry_point='my-training-script.py',
       framework_version='x.y.z',    # 1.10.0 or later
       py_version='pyxy',            
       job_name='my-training-job-with-heterogeneous-cluster',
       instance_groups=[instance_group_1, instance_group_2]
   )
   ```

------
#### [ TensorFlow ]

   ```
   from sagemaker.tensorflow import TensorFlow
   
   estimator = TensorFlow(
       ...
       entry_point='my-training-script.py',
       framework_version='x.y.z', # 2.6.0 or later
       py_version='pyxy',
       job_name='my-training-job-with-heterogeneous-cluster',
       instance_groups=[instance_group_1, instance_group_2]
   )
   ```

------
**注意**  
`instance_type` 與 `instance_count` 引數對和 SageMaker AI 估算器類別的 `instance_groups` 引數會相互排斥。對於同質叢集訓練，請使用 `instance_type` 和 `instance_count` 引數對。若要進行異質叢集訓練，請使用 `instance_groups`。
**注意**  
若要尋找可用架構容器、架構版本和 Python 版本的完整清單，請參閱 AWS 深度學習容器 GitHub 儲存庫中的 [SageMaker AI Framework Containers](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only)。

1. 使用執行個體群組配置的訓練輸入頻道來設定 `estimator.fit` 方法，然後開始訓練任務。

   ```
   estimator.fit(
       inputs={
           'training': training_input_channel_1, 
           'dummy-input-channel': training_input_channel_2
       }
   )
   ```

## 選項 2：使用低階 SageMaker API
<a name="train-heterogeneous-cluster-configure-api"></a>

如果您使用 AWS Command Line Interface 或 ， 適用於 Python (Boto3) 的 AWS SDK 並想要使用低階 SageMaker APIs 向異質叢集提交訓練任務請求，請參閱下列 API 參考。
+ [CreateTrainingJob](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html)
+ [ResourceConfig ](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_ResourceConfig.html)
+ [InstanceGroup](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_InstanceGroup.html)
+ [S3DataSource](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_S3DataSource.html)

# 在 Amazon SageMaker AI 的異質叢集上執行分散式訓練
<a name="train-heterogeneous-cluster-configure-distributed"></a>

透過 SageMaker AI 估算器類別的 `distribution` 引數，您可以指派特定的執行個體群組來執行分散式訓練。舉例來說，假設您擁有下列兩個執行個體群組，而且想要對其中一個執行多重 GPU 訓練。

```
from sagemaker.instance_group import InstanceGroup

instance_group_1 = InstanceGroup("instance_group_1", "ml.c5.18xlarge", 1)
instance_group_2 = InstanceGroup("instance_group_2", "ml.p3dn.24xlarge", 2)
```

您可以為其中一個執行個體群組設定分散式訓練組態。例如，下列程式碼範例會示範如何透過兩個 `ml.p3dn.24xlarge` 執行個體將 `training_group_2` 指派給分散式訓練組態。

**注意**  
目前，分散式組態僅可指定異質叢集的一個執行個體群組。

**使用 MPI**

------
#### [ PyTorch ]

```
from sagemaker.pytorch import PyTorch

estimator = PyTorch(
    ...
    instance_groups=[instance_group_1, instance_group_2],
    distribution={
        "mpi": {
            "enabled": True, "processes_per_host": 8
        },
        "instance_groups": [instance_group_2]
    }
)
```

------
#### [ TensorFlow ]

```
from sagemaker.tensorflow import TensorFlow

estimator = TensorFlow(
    ...
    instance_groups=[instance_group_1, instance_group_2],
    distribution={
        "mpi": {
            "enabled": True, "processes_per_host": 8
        },
        "instance_groups": [instance_group_2]
    }
)
```

------

**使用 SageMaker AI 資料平行程式庫**

------
#### [ PyTorch ]

```
from sagemaker.pytorch import PyTorch

estimator = PyTorch(
    ...
    instance_groups=[instance_group_1, instance_group_2],
    distribution={
        "smdistributed": {
            "dataparallel": {
                "enabled": True
            }
        }, 
        "instance_groups": [instance_group_2]
    }
)
```

------
#### [ TensorFlow ]

```
from sagemaker.tensorflow import TensorFlow

estimator = TensorFlow(
    ...
    instance_groups=[instance_group_1, instance_group_2],
    distribution={
        "smdistributed": {
            "dataparallel": {
                "enabled": True
            }
        }, 
        "instance_groups": [instance_group_2]
    }
)
```

------

**注意**  
使用 SageMaker AI 資料平行程式庫時，請確認執行個體群組由[程式庫支援的執行個體群組類型](https://docs.aws.amazon.com/sagemaker/latest/dg/distributed-data-parallel-support.html#distributed-data-parallel-supported-instance-types)所組成。

如需有關 SageMaker AI 資料平行程式庫的詳細資訊，請參閱 [SageMaker AI 資料平行訓練](https://docs.aws.amazon.com/sagemaker/latest/dg/data-parallel.html)。

**使用 SageMaker AI 模型平行程式庫**

------
#### [ PyTorch ]

```
from sagemaker.pytorch import PyTorch

estimator = PyTorch(
    ...
    instance_groups=[instance_group_1, instance_group_2],
    distribution={
        "smdistributed": {
            "modelparallel": {
                "enabled":True,
                "parameters": {
                    ...   # SageMaker AI model parallel parameters
                } 
            }
        }, 
        "instance_groups": [instance_group_2]
    }
)
```

------
#### [ TensorFlow ]

```
from sagemaker.tensorflow import TensorFlow

estimator = TensorFlow(
    ...
    instance_groups=[instance_group_1, instance_group_2],
    distribution={
        "smdistributed": {
            "modelparallel": {
                "enabled":True,
                "parameters": {
                    ...   # SageMaker AI model parallel parameters
                } 
            }
        }, 
        "instance_groups": [instance_group_2]
    }
)
```

------

如需有關 SageMaker AI 模型平行程式庫的詳細資訊，請參閱 [SageMaker AI 模型平行訓練](https://docs.aws.amazon.com/sagemaker/latest/dg/model-parallel.html)。

# 修改訓練指令碼以指派執行個體群組
<a name="train-heterogeneous-cluster-modify-training-script"></a>

完成前幾個章節中的異質叢集組態，您已經為訓練任務備妥了 SageMaker 訓練環境和執行個體。若要將執行個體群組進一步指派給特定訓練和資料處理任務，下個步驟為修改訓練指令碼。根據預設，訓練任務只會為所有節點建立訓練指令碼複本，不論執行個體的大小皆如此，而這可能導致效能的損失。

例如，如果您在異質叢集中混合 CPU 執行個體和 GPU 執行個體，同時將深度神經網路訓練指令碼傳遞給 SageMaker AI 估算器的 `entry_point` 引數，則 `entry_point` 指令碼會複寫至每個執行個體。換句話說，如果沒有適當的任務指派，CPU 執行個體也會執行整個指令碼，並開始針對 GPU 執行個體進行分散式訓練所設計的訓練任務。因此，您必須變更要卸載並在 CPU 執行個體上執行的特定處理函式。您可以使用 SageMaker AI 環境變數擷取異質叢集的資訊，並讓特定程序相應地執行。

訓練任務開始時，訓練指令碼會讀取 SageMaker 訓練環境資訊，其中包含異質叢集組態。組態包含目前執行個體群組、每個群組中目前的主機，以及目前主機所在的群組等資訊。

您可以透過以下方式，在 SageMaker AI 訓練任務的初始化階段期間查詢執行個體群組資訊。

**(建議) 使用 SageMaker 訓練工具組讀取執行個體群組資訊**

使用 [SageMaker 訓練工具組程式庫](https://github.com/aws/sagemaker-training-toolkit)所提供的環境 Python 模組。工具組程式庫已預先安裝在 TensorFlow 和 PyTorch 的 [SageMaker 架構容器](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only)中，因此您在使用預先建置的容器時不需要額外的安裝步驟。這是在訓練指令碼中以較少的程式碼變更來擷取 SageMaker AI 環境變數的建議方式。

```
from sagemaker_training import environment

env = environment.Environment()
```

與一般 SageMaker 訓練和異質叢集相關的環境變數：
+ `env.is_hetero` — 無論是否已設定異質叢集，都會傳回布林值結果。
+ `env.current_host` — 傳回目前的主機。
+ `env.current_instance_type` — 傳回目前主機的執行個體類型。
+ `env.current_instance_group` — 傳回目前執行個體群組的名稱。
+ `env.current_instance_group_hosts` — 傳回目前執行個體群組中的主機清單。
+ `env.instance_groups` — 傳回用於訓練的執行個體群組名稱清單。
+ `env.instance_groups_dict` — 傳回訓練任務的整個異質叢集組態。
+ `env.distribution_instance_groups` — 傳回指派給 SageMaker AI 估算器類別 `distribution` 參數的執行個體群組清單。
+ `env.distribution_hosts` — 傳回屬於指派給 SageMaker AI 估算器類別 `distribution` 參數之執行個體群組的主機清單。

例如，請考慮下列包含兩個執行個體群組的異質叢集範例。

```
from sagemaker.instance_group import InstanceGroup

instance_group_1 = InstanceGroup(
    "instance_group_1", "ml.c5.18xlarge", 1)
instance_group_2 = InstanceGroup(
    "instance_group_2", "ml.p3dn.24xlarge", 2)
```

範例異質叢集 `env.instance_groups_dict` 的輸出格式應類似以下內容。

```
{
    "instance_group_1": {
        "hosts": [
            "algo-2"
        ],
        "instance_group_name": "instance_group_1",
        "instance_type": "ml.c5.18xlarge"
    },
    "instance_group_2": {
        "hosts": [
            "algo-3",
            "algo-1"
        ],
        "instance_group_name": "instance_group_2",
        "instance_type": "ml.p3dn.24xlarge"
    }
}
```

**(選用) 從資源組態 JSON 檔案讀取執行個體群組資訊**

如果您希望以 JSON 格式擷取環境變數，則可直接使用資源組態 JSON 檔案。根據預設，SageMaker 訓練執行個體中的 JSON 檔案位於 `/opt/ml/input/config/resourceconfig.json`。

```
file_path = '/opt/ml/input/config/resourceconfig.json'
config = read_file_as_json(file_path)
print(json.dumps(config, indent=4, sort_keys=True))
```