

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

# Debugger 和自訂訓練容器搭配使用
<a name="debugger-bring-your-own-container"></a>

Amazon SageMaker Debugger 適用於您提供給 Amazon SageMaker AI 的任何深度學習模型。 AWS CLI、SageMaker AI `Estimator` API 和 Debugger APIs 可讓您使用任何 Docker 基礎映像來建置和自訂容器來訓練模型。若要 Debugger 和自訂容器搭配使用，您需要對訓練指令碼進行最小的變更，才能實施 Debugger 勾點回呼，並從訓練任務擷取張量。以下各節將逐步引導您如何使用 Debugger 搭配自訂訓練容器。

您需要下列資源，才能使用 Debugger 建置自訂容器。
+ [Amazon SageMaker Python SDK](https://sagemaker.readthedocs.io/en/stable)
+ [SMDebug 開放原始碼用戶端程式庫](https://github.com/awslabs/sagemaker-debugger)
+ 您選擇的 Docker 基礎映像
+ 已註冊 Debugger 勾點的訓練指令碼——如需將 Debugger 勾點註冊至訓練指令碼的詳細資訊，請參閱[將 Debugger 勾點註冊到您的訓練指令碼](#debugger-script-mode)。

如需 Debugger 和自訂訓練容器搭配使用的端對端範例，請參閱下列範例筆記本。
+ [使用 Debugger 建置自訂訓練容器和偵錯訓練任務](https://sagemaker-examples.readthedocs.io/en/latest/sagemaker-debugger/build_your_own_container_with_debugger/debugger_byoc.html)

**提示**  
使用 Debugger 之自訂容器指南是[調整自有訓練容器](adapt-training-container.md)指南的延伸，該指南會逐步引導您如何建置自訂訓練容器，並將其推送至 Amazon ECR。

## 準備建置自訂訓練容器
<a name="debugger-bring-your-own-container-1"></a>

若要建置 Docker 容器，檔案的基本結構應如下所示：

```
├── debugger_custom_container_test_notebook.ipynb      # a notebook to run python snippet codes
└── debugger_custom_container_test_folder              # this is a docker folder
    ├──  your-training-script.py                       # your training script with Debugger hook
    └──  Dockerfile                                    # a Dockerfile to build your own container
```

## 將 Debugger 勾點註冊到您的訓練指令碼
<a name="debugger-script-mode"></a>

若要偵錯模型訓練，您需要將 Debugger 勾點新增到訓練指令碼。

**注意**  
需要執行此步驟，才能收集到偵錯模型訓練的模型參數 (輸出張量)。如果您只想進行監控和分析，則可在建構估算器時，跳過此勾點註冊步驟，並排除 `debugger_hook_config` 參數。

下列範例程式碼會使用 Keras ResNet50 模型示範訓練指令碼的結構，並示範如何傳遞 Debugger 勾點做為Keras 回呼以進行偵錯。若要尋找完整的訓練指令碼，請參閱[使用 SageMaker Debugger 勾點之 TensorFlow 訓練指令碼](https://github.com/aws/amazon-sagemaker-examples/blob/master/sagemaker-debugger/build_your_own_container_with_debugger/docker/tf_keras_resnet_byoc.py)。

```
# An example of training script (your-training-script.py)
import tensorflow.compat.v2 as tf
from tensorflow.keras.applications.resnet50 import ResNet50
import smdebug.tensorflow as smd

def train(batch_size, epoch, model, hook):

    ...
    model.fit(X_train, Y_train,
              batch_size=batch_size,
              epochs=epoch,
              validation_data=(X_valid, Y_valid),
              shuffle=True,

              # smdebug modification: Pass the Debugger hook in the main() as a Keras callback
              callbacks=[hook])

def main():
    parser=argparse.ArgumentParser(description="Train resnet50 cifar10")

    # hyperparameter settings
    parser.add_argument(...)
    
    args = parser.parse_args()

    model=ResNet50(weights=None, input_shape=(32,32,3), classes=10)

    # Add the following line to register the Debugger hook for Keras.
    hook=smd.KerasHook.create_from_json_file()

    # Start the training.
    train(args.batch_size, args.epoch, model, hook)

if __name__ == "__main__":
    main()
```

如需註冊支援架構和演算法之 SageMaker Debugger 勾點的詳細資訊，請參閱 SMDebug 用戶端程式庫中的下列連結：
+ [SMDebug TensorFlow 勾點](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/tensorflow.md)
+ [SMDebug PyTorch 勾點](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/pytorch.md)
+ [SMDebug MXNet 勾點](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/mxnet.md)
+ [SMDebug XGBoost 勾點](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/xgboost.md)

在下列範例筆記本的訓練指令碼中，您可以找到更多有關如何將 Debugger 勾點新增至訓練指令碼，並收集詳細輸出張量的範例：
+ [具有 TensorFlow 2.1 架構的指令碼模式下的 Debugger](https://sagemaker-examples.readthedocs.io/en/latest/sagemaker-debugger/tensorflow2/tensorflow2_keras_custom_container/tf2-keras-custom-container.html)

  若要了解在深度學習容器和指令碼模式中使用 Debugger 之間的差異，請開啟此筆記本，然後將它和[在深度學習容器 TensorFlow v2.1 筆記本範例中先前的 Debugger](https://sagemaker-examples.readthedocs.io/en/latest/sagemaker-debugger/tensorflow2/tensorflow2_zero_code_change/tf2-keras-default-container.html) 並排放置。

   在指令碼模式下，勾點組態部分會從您設定估算器的指令碼中移除。相反地，Debugger 勾點功能會合併到訓練指令碼 [(指令碼模式下的 TensorFlow Keras ResNet 訓練指令碼)](https://github.com/awslabs/amazon-sagemaker-examples/blob/master/sagemaker-debugger/tensorflow2/tensorflow2_keras_custom_container/src/tf_keras_resnet_byoc.py)。訓練指令碼會在所需的 TensorFlow Keras 環境中匯入 `smdebug` 程式庫，以便與 TensorFlow ResNet50 演算法進行通訊。它還透過在 `train` 函式 (在第 49 行) 內新增 `callbacks=[hook]` 引數，以及新增透過 SageMaker Python SDK 提供的手動勾點組態 (在第 89 行)，來手動實作 `smdebug` 勾點功能。

  此指令碼模式範例在 TF 2.1 架構中執行訓練任務，可直接與 TF 2.1 範例中完全不變更指令碼做比較。在指令碼模式中設定 Debugger 的好處是彈性選擇 AWS 深度學習容器未涵蓋的架構版本。
+ [在指令碼模式下的 PyTorch 容器中使用 Amazon SageMaker Debugger](https://github.com/awslabs/amazon-sagemaker-examples/tree/master/sagemaker-debugger/pytorch_custom_container)

  此筆記本可支援在 PyTorch v1.3.1 架構中透過指令碼模式使用 Debugger。SageMaker AI 容器可支援 PyTorch v1.3.1，而此範例提供如何修改訓練指令碼的詳細資訊。

  根據預設，SageMaker AI PyTorch 估算器已在指令碼模式下。在筆記本中，啟用 `script_mode` 的那一行程式碼並未包含在估算器組態中。

  此筆記本提供將[原始 Pytorch 訓練指令碼](https://github.com/pytorch/examples/blob/master/mnist/main.py)變更為修改版本以啟用 Debugger 的詳細步驟。此外，這個範例會顯示如何使用 Debugger 內建規則，來偵測消失梯度問題之類的訓練問題，以及 Debugger 試用功能，來呼叫和分析儲存的張量。

## 建立並設定 Dockerfile
<a name="debugger-bring-your-own-container-2"></a>

開啟您的 SageMaker AI JupyterLab 並建立新資料夾 (在此範例中為 `debugger_custom_container_test_folder`)，以儲存訓練指令碼和 `Dockerfile`。下列程式碼範例是一個包含基本 Docker 建置命令的 `Dockerfile`。將下列程式碼貼入 `Dockerfile` 文字檔案並儲存。將訓練指令碼上傳至相同的資料夾。

```
# Specify a docker base image
FROM tensorflow/tensorflow:2.2.0rc2-gpu-py3
RUN /usr/bin/python3 -m pip install --upgrade pip
RUN pip install --upgrade protobuf

# Install required packages to enable the SageMaker Python SDK and the smdebug library
RUN pip install sagemaker-training
RUN pip install smdebug
CMD ["bin/bash"]
```

如果您想要使用預先建置的 AWS 深度學習容器映像，請參閱[可用的 AWS 深度學習容器映像](https://aws.amazon.com/releasenotes/available-deep-learning-containers-images/)。

## 建置自訂訓練映像並將其推送至 Amazon ECR
<a name="debugger-bring-your-own-container-3"></a>

建立測試筆記本`debugger_custom_container_test_notebook.ipynb`，並在筆記本儲存格中執行下列程式碼。這將會存取 `debugger_byoc_test_docker` 目錄，使用指定的 `algorithm_name` 建置 Docker，然後將 Docker 容器推送到您的 Amazon ECR。

```
import boto3

account_id = boto3.client('sts').get_caller_identity().get('Account')
ecr_repository = 'sagemaker-debugger-mnist-byoc-tf2'
tag = ':latest'

region = boto3.session.Session().region_name

uri_suffix = 'amazonaws.com'
if region in ['cn-north-1', 'cn-northwest-1']:
    uri_suffix = 'amazonaws.com.cn'
byoc_image_uri = '{}.dkr.ecr.{}.{}/{}'.format(account_id, region, uri_suffix, ecr_repository + tag)

!docker build -t $ecr_repository docker
!$(aws ecr get-login --region $region --registry-ids $account_id --no-include-email)
!aws ecr create-repository --repository-name $ecr_repository
!docker tag {ecr_repository + tag} $byoc_image_uri
!docker push $byoc_image_uri
```

**提示**  
如果您使用其中一個 AWS 深度學習容器基礎映像，請執行下列程式碼來登入 Amazon ECR 並存取深度學習容器映像儲存庫。  

```
! aws ecr get-login-password --region {region} | docker login --username AWS --password-stdin 763104351884.dkr.ecr.us-east-1.amazonaws.com
```

## 使用自訂訓練容器執行和偵錯訓練任務
<a name="debugger-bring-your-own-container-4"></a>

在建置 Docker 容器並將其推送至 Amazon ECR 之後，請使用訓練指令碼和特定的 Debugger 參數來設定 SageMaker AI 估算器。在執行 `estimator.fit()` 之後，Debugger 會收集並監控輸出張量，然後偵測訓練問題。使用儲存的張量，您可以使用 `smdebug` 核心功能和工具，進一步分析訓練任務。使用 Amazon CloudWatch Events 設定偵錯工具規則監控程序的工作流程 AWS Lambda，而且只要偵錯工具規則發現訓練問題，您就可以自動停止訓練任務程序。

```
import sagemaker
from sagemaker.estimator import Estimator
from sagemaker.debugger import Rule, DebuggerHookConfig, CollectionConfig, rule_configs

profiler_config=ProfilerConfig(...)
debugger_hook_config=DebuggerHookConfig(...)
rules=[
    Rule.sagemaker(rule_configs.built_in_rule()),
    ProfilerRule.sagemaker(rule_configs.BuiltInRule())
]

estimator=Estimator(
    image_uri=byoc_image_uri,
    entry_point="./debugger_custom_container_test_folder/your-training-script.py"
    role=sagemaker.get_execution_role(),
    base_job_name='debugger-custom-container-test',
    instance_count=1,
    instance_type='ml.p3.2xlarge',
    
    # Debugger-specific parameters
    profiler_config=profiler_config,
    debugger_hook_config=debugger_hook_config,
    rules=rules
)

# start training
estimator.fit()
```