

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 Debugger 和自定义训练容器
<a name="debugger-bring-your-own-container"></a>

Amazon SageMaker Debugger 适用于你带到 Amazon A SageMaker I 的任何深度学习模型。 SageMaker A `Estimator` I API 和调试器 APIs 使您能够使用任何 Docker 基础镜像来构建和自定义容器来训练模型。 AWS CLI要将 Debugger 与自定义容器结合使用，您只需对训练脚本进行极少的更改，以实施 Debugger 钩子回调并从训练作业中检索张量。以下部分介绍了如何使用 Debugger 和自定义训练容器。

您需要以下资源来使用 Debugger 构建自定义容器。
+ [亚马逊 SageMaker Python 软件开发工具包](https://sagemaker.readthedocs.io/en/stable)
+ [ SMDebug 开源客户端库](https://github.com/awslabs/sagemaker-debugger)
+ 您选择的 Docker 基本映像
+ 您的训练脚本并注册了 Debugger 钩子 – 有关将 Debugger 钩子注册到训练脚本的更多信息，请参阅[在训练脚本中注册 Debugger 钩子](#debugger-script-mode)。

有关在自定义训练容器中使用 Debugger 的示 end-to-end例，请参阅以下示例笔记本。
+ [使用 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 ResNet 50 模型的训练脚本的结构，以及如何将调试器挂钩作为 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()
```

有关为支持的框架和算法注册 Debugger 挂钩的更多信息，请参阅 SMDebug 客户端库中的以下链接：
+ [SMDebug TensorFlow hook](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/tensorflow.md)
+ [SMDebug PyTorch hook](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/pytorch.md)
+ [SMDebug MXNet hook](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/mxnet.md)
+ [SMDebug XGBoost hook](https://github.com/awslabs/sagemaker-debugger/blob/master/docs/xgboost.md)

在以下示例笔记本的训练脚本中，您可以找到更多示例，详细说明了如何将 Debugger 钩子添加到训练脚本和收集输出张量：
+ [使用 TensorFlow 2.1 框架的脚本模式调试器](https://sagemaker-examples.readthedocs.io/en/latest/sagemaker-debugger/tensorflow2/tensorflow2_keras_custom_container/tf2-keras-custom-container.html)

  要查看在深度学习容器中使用调试器与在脚本模式下使用调试器的区别，请打开此笔记本并将其与[之前的调试器并排放在深度学习容器 TensorFlow v2.1 笔记本示例中](https://sagemaker-examples.readthedocs.io/en/latest/sagemaker-debugger/tensorflow2/tensorflow2_zero_code_change/tf2-keras-default-container.html)。

   在脚本模式下，挂钩配置部分将从您设置评估程序的脚本中删除。取而代之的是，调试器挂钩功能被合并到训练脚本中，即脚本模式下的 [ 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)。训练脚本将`smdebug`库导入所需的 TensorFlow Keras 环境中，以便与 TensorFlow ResNet 50 算法进行通信。它还通过在`train`函数中添加`callbacks=[hook]`参数（在第 49 行）和添加通过 SageMaker Python SDK 提供的手动挂钩配置（在第 89 行中）来手动实现挂钩功能。`smdebug`

  该脚本模式示例在 TF 2.1 框架中运行训练作业，以便与 TF 2.1 示例中的零脚本更改进行直接比较。在脚本模式下设置调试器的好处是，可以灵活地选择 Dee AWS p Learning Containers 未涵盖的框架版本。
+ [在脚本模式下在 PyTorch 容 SageMaker 器中使用 Amazon 调试器](https://github.com/awslabs/amazon-sagemaker-examples/tree/master/sagemaker-debugger/pytorch_custom_container)

  此笔记本在 PyTorch v1.3.1 框架中启用脚本模式下的调试器。 PyTorchv1.3.1 受 A SageMaker I 容器支持，此示例显示了如何修改训练脚本的详细信息。

  默认 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`。以下代码示例是 `Dockerfile`，其中包括了必要的 Docker 构建注释。将以下代码粘贴到 `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 后，请使用您的训练脚本和调试器特定的参数配置 SageMaker AI 估算器。执行 `estimator.fit()` 之后，Debugger 将收集输出张量、监控它们并检测训练问题。使用保存的张量，您可以使用 `smdebug` 核心功能和工具进一步分析训练作业。使用 Amazon Ev CloudWatch ents 配置调试器规则监控流程的工作流程 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()
```