

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

# SageMaker Training Compiler 疑難排解
<a name="training-compiler-troubleshooting"></a>

**重要**  
Amazon Web Services (AWS) 宣佈不再推出新版本的 SageMaker Training Compiler。您可以透過現有的 SageMaker 訓練 AWS 深度學習容器 (DLC)，繼續利用 SageMaker Training Compiler。請務必注意，雖然現有 DLCs仍可存取，但根據深度學習容器架構支援政策 AWS，他們將不再收到來自 的修補程式或更新。 [AWS](https://docs.aws.amazon.com/deep-learning-containers/latest/devguide/support-policy.html)

如果遇到錯誤，您可以透過下列清單嘗試疑難排解訓練工作。如需進一步支援，請透過 [AWS 支援](https://console.aws.amazon.com/support/)或 [Amazon SageMaker AI 的AWS 開發人員論壇](https://forums.aws.amazon.com/forum.jspa?forumID=285)與 SageMaker AI 團隊聯絡。

## 相較於原生架構訓練工作，訓練工作未如預期般收斂
<a name="training-compiler-troubleshooting-convergence-issue"></a>

收斂問題範圍從 “當開啟 SageMaker Training Compiler 時，模型未進行學習” 到 “模型正在學習，但速度比原生架構慢”。在本疑難排解指南，我們假設在無 SageMaker Training Compiler (採用原生架構) 的情況，收斂性狀態良好 ，並視此為基準。

當遇到此類收斂問題時，第一步是確定問題是否僅限於分散式訓練，還是源於單 GPU 訓練。採用 SageMaker Training Compiler 的分散式訓練是單 GPU 訓練的擴充，其中包含其他步驟。

1. 設定具多個執行個體或 GPU 的叢集。

1. 分配輸入資料至所有工作者。

1. 同步處理來自所有工作者的模型更新。

因此，單 GPU 訓練的任何收斂問題都會傳播到具多位工作者的分散式訓練。

![\[使用 SageMaker Training Compiler 時，針對訓練任務中的收斂問題進行故障診斷的流程圖。\]](http://docs.aws.amazon.com/zh_tw/sagemaker/latest/dg/images/training-compiler-troubleshooting-convergence-flow.jpg)


### 在單 GPU 訓練時發生的收斂問題
<a name="training-compiler-troubleshooting-convergence-issue-single-gpu"></a>

如收斂問題源於單 GPU 訓練，這可能是因為超參數或 `torch_xla` API 的設定不當所致。

**檢查超參數**

採用 SageMaker Training Compiler 進行訓練會導致模型的記憶體用量發生變化。編譯器會以智慧方式在重複使用及重新計算之間進行仲裁，因而增加或減少相應記憶體消耗量。若要利用此功能，當遷移訓練工作至 SageMaker Training Compiler 時，必須重新調整批次大小及關聯的超參數。然而，不正確的超參數設定常會導致訓練損失振盪，且可能因而減慢收斂速度。在極少數情況，積極超參數可能導致模型無法學習 (訓練損失指標未減少或傳回 `NaN`)。若要確定收斂問題是否源自超參數，請針對兩個訓練工作進行並行測試，在保持所有超參數相同的情況，其中之一採用 SageMaker Training Compiler，另一則否。

**檢查是否正確設定單 GPU 訓練的 `torch_xla` API**

若基準超參數仍存在收斂問題，則需檢查是否不當使用任何 `torch_xla` API，特別是用於更新模型者。基本上，`torch_xla` 會繼續以圖形的形式累積指令 (延遲執行)，直到明確指示執行累積圖形為止。`torch_xla.core.xla_model.mark_step()` 函式可協助執行累積圖形。在***每個模型更新之後***，以及***在列印及記錄任何變數之前***，應採用此函式來同步執行圖形。如缺少同步處理步驟，則模型可能在列印、記錄及後續向前傳遞期間採用記憶體的過時值，而非採用最新值 (應於每次重複及模型更新之後進行同步)。

若採用具有梯度縮放 (可能來自 AMP) 或梯度剪輯技術的 SageMaker Training Compiler，則可能更複雜。採用 AMP 進行梯度運算的適當順序如下。

1. 具縮放功能的梯度運算

1. 梯度不縮放，梯度剪輯，然後縮放

1. 模式更新

1. 利用 `mark_step()` 同步執行圖形

若要尋找正確 API 以便用於清單所提及的操作，請參閱[遷移訓練指令碼至 SageMaker Training Compiler](https://docs.aws.amazon.com/sagemaker/latest/dg/training-compiler-pytorch-models.html) 指南。

**考慮使用自動模型調校**

在運用 SageMaker Training Compiler 時,若於重新調整批次大小及關聯的超參數 (例如學習速率) 時出現收斂問題，請考慮使用[自動模型調校](https://docs.aws.amazon.com/sagemaker/latest/dg/automatic-model-tuning.html)來調校超參數。您可以參考[調校 SageMaker Training Compiler 的超參數範例筆記本](https://github.com/aws/amazon-sagemaker-examples/blob/main/sagemaker-training-compiler/tensorflow/single_gpu_single_node/hyper-parameter-tuning.ipynb)。

### 在分散式訓練時發生的收斂問題
<a name="training-compiler-troubleshooting-convergence-issue-distributed-training"></a>

如在分散式訓練時持續發生收斂問題，這可能是因為權重初始化或 `torch_xla` API 設定不當所致。

**檢查工作者的權重初始化**

如在執行具多位工作者的分散式訓練工作時出現收斂問題，請在適當情況設定常數種子，以便確保所有工作者採取一致確定性行為。請注意權重初始化等技術，因其涉及隨機性。若無常數種子，每位工作者最終可能訓練出不同模型。

**檢查是否已正確設定 `torch_xla` API，以便進行分散式訓練**

如問題仍存在，這可能是因為不當使用 `torch_xla` API 進行分散式訓練。請務必新增下列項目至估算器，以便利用 SageMaker Training Compiler 來設定用於分散式訓練的叢集。

```
distribution={'torchxla': {'enabled': True}}
```

這應伴隨訓練指令碼的函式 `_mp_fn(index)`，每位工作者都會調用一次。如無 `mp_fn(index)` 函式，可能導致每位工作者各自獨立訓練模型，而未共用模型更新。

接下來，請按照[遷移訓練指令碼至 SageMaker Training Compiler](https://docs.aws.amazon.com/sagemaker/latest/dg/training-compiler-pytorch-models.html) 文件的指引，確保採用 `torch_xla.distributed.parallel_loader.MpDeviceLoader` API 與分散式資料取樣器，如下列範例所示。

```
torch.utils.data.distributed.DistributedSampler()
```

 這可確保輸入資料正確分配至所有工作者。

最後，若要同步處理來自所有工作者的模型更新，請利用 `torch_xla.core.xla_model._fetch_gradients` 來收集所有工作者的梯度，並利用 `torch_xla.core.xla_model.all_reduce` 來整合所有收集的梯度為單一更新。

當採用 SageMaker Training Compiler 搭配梯度縮放 (可能來自 AMP) 或梯度剪輯技術時，可能更複雜。採用 AMP 進行梯度運算的適當順序如下。

1. 具縮放功能的梯度運算

1. 跨所有工作者進行梯度同步處理

1. 梯度不縮放，梯度剪輯，然後梯度縮放

1. 模式更新

1. 利用 `mark_step()` 同步執行圖形

請注意，相較於單 GPU 訓練檢查清單，此檢查清單具額外項目可用於同步所有工作者。

## 由於缺少 PyTorch/XLA 組態，導致訓練任務失敗
<a name="training-compiler-troubleshooting-missing-xla-config"></a>

如訓練工作失敗並顯示 `Missing XLA configuration` 錯誤訊息，可能是因為所使用每個執行個體的 GPU 數目設定錯誤。

XLA 需要額外環境變數來編譯訓練工作。最常見的遺失環境變數是 `GPU_NUM_DEVICES`。若要讓編譯器正常運作，您必須將此環境變數設為等於每個執行個體的 GPU 數目。

有三種方法可設定 `GPU_NUM_DEVICES` 環境變數：
+ **方法 1** — 利用 SageMaker AI 估算器類別的 `environment` 參數。例如，如您採用具四個 GPU 的 `ml.p3.8xlarge` 執行個體，請執行下列動作：

  ```
  # Using the SageMaker Python SDK's HuggingFace estimator
  
  hf_estimator=HuggingFace(
      ...
      instance_type="ml.p3.8xlarge",
      hyperparameters={...},
      environment={
          ...
          "GPU_NUM_DEVICES": "4" # corresponds to number of GPUs on the specified instance
      },
  )
  ```
+ **方法 2** — 利用 SageMaker AI 估算器類別的 `hyperparameters` 參數，並運用訓練指令碼加以剖析。

  1. 若要指定 GPU 數目，請新增鍵值對至 `hyperparameters` 參數。

     例如，如您採用具四個 GPU 的 `ml.p3.8xlarge` 執行個體，請執行下列動作：

     ```
     # Using the SageMaker Python SDK's HuggingFace estimator
     
     hf_estimator=HuggingFace(
         ...
         entry_point = "train.py"
         instance_type= "ml.p3.8xlarge",
         hyperparameters = {
             ...
             "n_gpus": 4 # corresponds to number of GPUs on specified instance
         }
     )
     hf_estimator.fit()
     ```

  1. 在訓練指令碼剖析 `n_gpus` 超參數，並指定其為 `GPU_NUM_DEVICES` 環境變數的輸入。

     ```
     # train.py
     import os, argparse
     
     if __name__ == "__main__":
         parser = argparse.ArgumentParser()
         ...
         # Data, model, and output directories
         parser.add_argument("--output_data_dir", type=str, default=os.environ["SM_OUTPUT_DATA_DIR"])
         parser.add_argument("--model_dir", type=str, default=os.environ["SM_MODEL_DIR"])
         parser.add_argument("--training_dir", type=str, default=os.environ["SM_CHANNEL_TRAIN"])
         parser.add_argument("--test_dir", type=str, default=os.environ["SM_CHANNEL_TEST"])
         parser.add_argument("--n_gpus", type=str, default=os.environ["SM_NUM_GPUS"])
     
         args, _ = parser.parse_known_args()
     
         os.environ["GPU_NUM_DEVICES"] = args.n_gpus
     ```
+ **方法 3** — 在訓練指令碼針對 `GPU_NUM_DEVICES` 環境變數進行硬式編碼。例如，如您採用具四個 GPU 的執行個體，請新增下列項目至指令碼。

  ```
  # train.py
  
  import os
  os.environ["GPU_NUM_DEVICES"] = 4
  ```

**提示**  
若要針對您要使用的機器學習執行個體尋找其 GPU 裝置數量，請參閱 *Amazon EC2 執行個體類型頁面*的[加速運算](https://aws.amazon.com/ec2/instance-types/#Accelerated_Computing)。

## SageMaker Training Compiler 未減少總訓練時間
<a name="training-compiler-troubleshooting-no-improved-training-time"></a>

如 SageMaker Training Compiler 未減少總訓練時間，強烈建議您瀏覽 [SageMaker Training Compiler 最佳實務和考量事項](training-compiler-tips-pitfalls.md) 頁面，並檢查訓練組態、輸入張量形狀的填補策略，以及超參數。