

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

# 创建算法映像
<a name="ml-algorithm-images"></a>

Amazon SageMaker AI 算法要求买家在做出预测之前带上自己的数据进行训练。作为 AWS Marketplace 卖家，您可以使用 SageMaker AI 来创建机器学习 (ML) 算法和模型，供买家部署 AWS。以下各节将介绍如何为其创建算法图像 AWS Marketplace。这包括创建用于训练算法的 Docker 训练映像以及包含推理逻辑的推理映像。发布算法产品时，需要同时提供训练映像和推理映像。

**Topics**
+ [概述](#ml-algorithm-images-overview)
+ [为算法创建训练映像](#ml-creating-a-training-image-for-algorithms)
+ [为算法创建推理映像](#ml-creating-an-inference-image-for-algorithms)

## 概述
<a name="ml-algorithm-images-overview"></a>

算法包括以下组件：
+  存储在 [Amazon ECR](https://aws.amazon.com/ecr/) 中的训练映像 
+  存储在 Amazon Elastic Container Registry (Amazon ECR) 中的推理映像 

**注意**  
 对于算法产品，训练容器会生成模型构件，这些构件在模型部署时加载到推理容器中。

下图显示了发布和使用算法产品的工作流程。

![\[卖家如何创建算法包映像以及买家如何使用它的示意图。\]](http://docs.aws.amazon.com/zh_cn/marketplace/latest/userguide/images/ml-algorithm-package-images.png)


为创建 A SageMaker I 算法的工作流程 AWS Marketplace 包括以下步骤：

1. 卖家创建训练映像和推理映像（部署后无法访问网络），然后将其上传到 Amazon ECR Registry。

1. 然后，卖家在 Amazon A SageMaker I 中创建算法资源，并在上发布其机器学习产品 AWS Marketplace。

1. 买家订阅机器学习产品。

1. 买方使用兼容的数据集和适当的超参数值创建训练作业。 SageMaker AI 运行训练图像并将训练数据和超参数加载到训练容器中。训练作业完成后，位于 `/opt/ml/model/` 中的模型构件会被压缩并复制到买家的 [Amazon S3](https://aws.amazon.com/s3/) 存储桶中。

1. 买家使用存储在 Amazon S3 中的训练模型构件创建模型包，然后部署模型。

1. SageMaker AI 运行推理图像，提取压缩后的模型工件，并将文件加载到推理容器目录路径`/opt/ml/model/`中，用于推理的代码将在该路径中使用这些文件。

1.  无论模型是作为终端节点部署还是批量转换作业， SageMaker AI 都会通过容器的 HTTP 端点代表买方将用于推理的数据传递到容器并返回预测结果。

**注意**  
 有关更多信息，请参阅[训练模型](https://docs.aws.amazon.com/sagemaker/latest/dg/train-model.html)。

## 为算法创建训练映像
<a name="ml-creating-a-training-image-for-algorithms"></a>

 本部分提供了将训练代码打包成训练映像的演练。创建算法产品需要训练映像。

 *训练映像* 是包含您的训练算法的 Docker 映像。容器遵循特定的文件结构，允许 SageMaker AI 将数据复制到您的容器或从您的容器中复制数据。

 发布算法产品时，需要同时提供训练映像和推理映像。创建训练映像后，必须创建推理映像。这两个映像可以合并为一个映像，也可以作为单独的映像保留。是合并映像还是将它们分开由您决定。通常，推理比训练简单，您可能需要单独的映像来提高推理性能。

**注意**  
 以下只是训练映像打包代码的一个示例。有关更多信息，请参阅[使用您自己的算法和模型以及开启 AWS Marketplace](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-marketplace.html)的 [AWS Marketplace SageMaker AI 示例](https://github.com/aws/amazon-sagemaker-examples/tree/master/aws_marketplace) GitHub。

**Topics**
+ [步骤 1：创建容器映像](#ml-step-1-creating-the-container-image-1)
+ [第 2 步：在本地构建和测试映像](#ml-step-2-building-and-testing-the-image-locally-1)

### 步骤 1：创建容器映像
<a name="ml-step-1-creating-the-container-image-1"></a>

 为了使训练图像与 Amazon A SageMaker I 兼容，它必须遵循特定的文件结构，以允许 SageMaker AI 将训练数据和配置输入复制到容器中的特定路径。训练完成后，生成的模型工件将存储在 A SageMaker I 从中复制的容器中的特定目录路径中。

 以下内容使用安装在 Linux 的 Ubuntu 发行版的开发环境中的 Docker CLI。
+ [准备好程序以读取配置输入](#ml-prepare-your-program-to-read-configuration-inputs)
+ [准备好程序以读取数据输入](#ml-prepare-your-program-to-read-data-inputs)
+ [准备好程序以编写训练输出](#ml-prepare-your-program-to-write-training-outputs)
+ [为容器运行创建脚本](#ml-create-the-script-for-the-container-run-1)
+ [创建 `Dockerfile`](#ml-create-the-dockerfile-1)

#### 准备好程序以读取配置输入
<a name="ml-prepare-your-program-to-read-configuration-inputs"></a>

 如果您的训练程序需要买家提供的任何配置输入，则以下是运行时将这些内容复制到容器中的位置。如果需要，您的程序必须从这些特定的文件路径中读取。
+  `/opt/ml/input/config` 是包含控制程序运行方式的信息的目录。
  +  `hyperparameters.json` 是 JSON 格式的超参数名称和值字典。这些值是字符串，因此您可能需要对其进行转换。
  +  `resourceConfig.json` 是一个 JSON 格式的文件，描述了用于[分布式训练](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-training-algo-running-container.html#your-algorithms-training-algo-running-container-dist-training)的网络布局。如果您的训练映像不支持分布式训练，则可以忽略此文件。

**注意**  
 有关配置输入的更多信息，请参阅 [Amazon A SageMaker I 如何提供训练信息](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-training-algo-running-container.html)。

#### 准备好程序以读取数据输入
<a name="ml-prepare-your-program-to-read-data-inputs"></a>

 训练数据可以通过以下两种模式之一传递到容器。在容器中运行的训练程序会以这两种模式之一提取训练数据。

 **文件模式** 
+  `/opt/ml/input/data/<channel_name>/` 包含该渠道的输入数据。渠道是根据对 `CreateTrainingJob` 操作的调用创建的，但通常重要的是渠道必须与算法的预期相匹配。每个渠道的文件都从 [Amazon S3](https://aws.amazon.com/s3/) 复制到此目录，同时保留 Amazon S3 密钥结构所指示的树结构。

 **管道模式** 
+  `/opt/ml/input/data/<channel_name>_<epoch_number>` 是给定纪元的管道。纪元从零开始，每次读取时都会增加一个。可以运行的纪元数没有限制，但是在读取下一个纪元之前，必须关闭每个管道。

#### 准备好程序以编写训练输出
<a name="ml-prepare-your-program-to-write-training-outputs"></a>

 训练的输出将写入以下容器目录：
+  `/opt/ml/model/` 是您编写模型或训练算法生成的模型构件的目录。您的模型可以采用任意格式。它可以是单个文件或整个目录树。 SageMaker AI 将此目录中的所有文件打包成压缩文件 (.tar.gz)。此文件位于 `DescribeTrainingJob` API 操作返回的 Amazon S3 位置。
+  `/opt/ml/output/` 是一个目录，算法可以在其中写入描述任务失败原因的 `failure` 文件。此文件的内容将在 `DescribeTrainingJob` 结果的 `FailureReason` 字段中返回。对于成功的作业，无需编写此文件，将被忽略。

#### 为容器运行创建脚本
<a name="ml-create-the-script-for-the-container-run-1"></a>

 创建 A SageMaker I 在运行 Docker 容器镜像时运行的 `train` shell 脚本。训练完成并将模型构件写入各自的目录后，退出脚本。

 **`./train`** 

```
#!/bin/bash

# Run your training program here
#
#
#
#
```

#### 创建 `Dockerfile`
<a name="ml-create-the-dockerfile-1"></a>

 在您的构建上下文中创建 `Dockerfile`。此示例使用 Ubuntu 18.04 作为基础映像，但您可以从适用于您的框架的任何基础映像开始。

 **`./Dockerfile`** 

```
FROM ubuntu:18.04

# Add training dependencies and programs
#
#
#
#
#
# Add a script that SageMaker AI will run
# Set run permissions
# Prepend program directory to $PATH
COPY /train /opt/program/train
RUN chmod 755 /opt/program/train
ENV PATH=/opt/program:${PATH}
```

 `Dockerfile` 将之前创建的 `train` 脚本添加到映像中。脚本的目录已添加到 PATH 中，因此它可以在容器运行时运行。

 在前面的示例中，没有实际的训练逻辑。对于实际的训练映像，将训练依赖项添加到 `Dockerfile` 中，然后添加读取训练输入的逻辑，以训练和生成模型构件。

 您的训练映像必须包含其所有必需的依赖项，因为它无法访问互联网。

 有关更多信息，请参阅[使用您自己的算法和模型以及开启 AWS Marketplace](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-marketplace.html)的 [AWS Marketplace SageMaker AI 示例](https://github.com/aws/amazon-sagemaker-examples/tree/master/aws_marketplace) GitHub。

### 第 2 步：在本地构建和测试映像
<a name="ml-step-2-building-and-testing-the-image-locally-1"></a>

 在构建上下文中，现在存在以下文件：
+ `./Dockerfile`
+ `./train`
+ 您的训练依赖项和逻辑

 接下来，您可以构建、运行和测试此容器映像。

#### 构建映像：
<a name="ml-build-the-image-1"></a>

 在构建上下文中运行 Docker 命令来构建和标记映像。此示例使用标记 `my-training-image`。

```
sudo docker build --tag my-training-image ./
```

 运行此 Docker 命令构建映像后，当 Docker 根据您的 `Dockerfile` 的每一行构建映像时，您该会看到输出。完成后，您应看到类似如下所示的内容：

```
Successfully built abcdef123456
Successfully tagged my-training-image:latest
```

#### 本地运行
<a name="ml-run-locally-1"></a>

 完成后，在本地测试映像，如以下示例中所示。

```
sudo docker run \
  --rm \
  --volume '<path_to_input>:/opt/ml/input:ro' \
  --volume '<path_to_model>:/opt/ml/model' \
  --volume '<path_to_output>:/opt/ml/output' \
  --name my-training-container \
  my-training-image \
  train
```

 以下是命令的详细信息：
+  `--rm` – 容器停止后自动将其移除。
+  `--volume '<path_to_input>:/opt/ml/input:ro'` – 将测试输入目录设置为只读供容器使用。
+  `--volume '<path_to_model>:/opt/ml/model'` – 训练测试完成后，绑定挂载模型构件在主机上的存储路径。
+  `--volume '<path_to_output>:/opt/ml/output'` – 绑定挂载主机上 `failure` 文件中写入失败原因的路径。
+  `--name my-training-container` – 为正在运行的容器提供名称。
+  `my-training-image` – 运行构建的映像。
+  `train`— 运行 SageMaker AI 在运行容器时运行的相同脚本。

 运行此命令后，Docker 会根据您构建的训练映像创建一个容器并运行它。容器运行 `train` 脚本，从而启动您的训练程序。

 训练程序完成且容器退出后，请检查输出模型构件是否正确。此外，请检查日志输出以确认它们没有生成您不想要的日志，同时确保提供了有关训练作业的足够信息。

 这样就完成了算法产品的训练代码打包。由于算法产品还包括推理映像，因此请继续下一部分[为算法创建推理映像](#ml-creating-an-inference-image-for-algorithms)。

## 为算法创建推理映像
<a name="ml-creating-an-inference-image-for-algorithms"></a>

 本部分提供了将推理代码打包成算法产品的推理映像的演练。

 推理映像是包含您的推理逻辑的 Docker 映像。容器在运行时会公开 HTTP 端点，以允许 SageMaker AI 将数据传入和传出您的容器。

 发布算法产品时，需要同时提供训练映像和推理映像。如果您尚未执行此操作，请参阅前面的部分[为算法创建训练映像](#ml-creating-a-training-image-for-algorithms)。这两个映像可以合并为一个映像，也可以作为单独的映像保留。是合并映像还是将它们分开由您决定。通常，推理比训练简单，您可能需要单独的映像来提高推理性能。

**注意**  
 以下只是推理映像打包代码的一个示例。有关更多信息，请参阅[使用您自己的算法和模型以及开启 AWS Marketplace](https://docs.aws.amazon.com/sagemaker/latest/dg/your-algorithms-marketplace.html)的 [AWS Marketplace SageMaker AI 示例](https://github.com/aws/amazon-sagemaker-examples/tree/master/aws_marketplace) GitHub。  
为了简单起见，以下示例使用了 Web 服务 [Flask](https://pypi.org/project/Flask/)，但不被视为生产就绪。

**Topics**
+ [步骤 1：创建推理映像](#ml-step-1-creating-the-inference-image)
+ [第 2 步：在本地构建和测试映像](#ml-step-2-building-and-testing-the-image-locally-2)

### 步骤 1：创建推理映像
<a name="ml-step-1-creating-the-inference-image"></a>

 为了使推理映像与 SageMaker AI 兼容，Docker 镜像必须公开 HTTP 端点。当您的容器运行时，SageMaker AI 会将买方提供的推理输入传递给您的容器的 HTTP 终端节点。推理结果返回在 HTTP 响应的正文中。

 以下内容使用安装在 Linux 的 Ubuntu 发行版的开发环境中的 Docker CLI。
+ [创建 Web 服务器脚本](#ml-create-the-web-server-script-1) 
+ [为容器运行创建脚本](#ml-create-the-script-for-the-container-run-2)
+ [创建 `Dockerfile`](#ml-create-the-dockerfile-2)
+ [准备程序以动态加载模型构件](#ml-preparing-your-program-to-dynamically-load-model-artifacts)

#### 创建 Web 服务器脚本
<a name="ml-create-the-web-server-script-1"></a>

 此示例使用名为 [Flask](https://pypi.org/project/Flask/) 的 Python 服务器，但您可以使用任何适用于您的框架的 Web 服务器。

**注意**  
为了简单起见，这里使用 [Flask](https://pypi.org/project/Flask/)。它不被视为生产就绪的 Web 服务器。

 创建 Flask Web 服务器脚本，该脚本在 SageMaker AI 使用的 TCP 端口 8080 上为两个 HTTP 端点提供服务。以下是两个预期的端点：
+  `/ping`— SageMaker AI 向此端点发出 HTTP GET 请求，以检查您的容器是否准备就绪。当您的容器准备就绪时，它会使用 HTTP 200 响应代码来响应此端点的 HTTP GET 请求。
+  `/invocations`— SageMaker AI 向此端点发出 HTTP POST 请求以进行推理。用于推理的输入数据在请求正文中发送。用户指定的内容类型在 HTTP 头中传递。响应的主体是推理输出。

 **`./web_app_serve.py`** 

```
# Import modules
import json
import re
from flask import Flask
from flask import request
app = Flask(__name__)

# Create a path for health checks
@app.route("/ping")
def endpoint_ping():
  return ""
 
# Create a path for inference
@app.route("/invocations", methods=["POST"])
def endpoint_invocations():
  
  # Read the input
  input_str = request.get_data().decode("utf8")
  
  # Add your inference code here.
  #
  #
  #
  #
  #
  # Add your inference code here.
  
  # Return a response with a prediction
  response = {"prediction":"a","text":input_str}
  return json.dumps(response)
```

 在前面的示例中，没有实际的推理逻辑。对于实际的推理映像，请将推理逻辑添加到 Web 应用中，以便它处理输入并返回预测。

 您的推理映像必须包含其所有必需的依赖项，因为它无法访问互联网。

#### 为容器运行创建脚本
<a name="ml-create-the-script-for-the-container-run-2"></a>

 创建一个名为 SageMaker AI `serve` 在运行 Docker 容器镜像时运行的脚本。在此脚本中，启动 HTTP Web 服务器。

 **`./serve`** 

```
#!/bin/bash

# Run flask server on port 8080 for SageMaker AI
flask run --host 0.0.0.0 --port 8080
```

#### 创建 `Dockerfile`
<a name="ml-create-the-dockerfile-2"></a>

 在您的构建上下文中创建 `Dockerfile`。此示例使用 Ubuntu 18.04，但您可以从适用于您的框架的任何基础映像开始。

 **`./Dockerfile`** 

```
FROM ubuntu:18.04

# Specify encoding
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8

# Install python-pip
RUN apt-get update \
&& apt-get install -y python3.6 python3-pip \
&& ln -s /usr/bin/python3.6 /usr/bin/python \
&& ln -s /usr/bin/pip3 /usr/bin/pip;

# Install flask server
RUN pip install -U Flask;

# Add a web server script to the image
# Set an environment to tell flask the script to run
COPY /web_app_serve.py /web_app_serve.py
ENV FLASK_APP=/web_app_serve.py

# Add a script that Amazon SageMaker AI will run
# Set run permissions
# Prepend program directory to $PATH
COPY /serve /opt/program/serve
RUN chmod 755 /opt/program/serve
ENV PATH=/opt/program:${PATH}
```

 `Dockerfile` 将之前创建的两个脚本添加到映像中。`serve` 脚本的目录已添加到 PATH 中，因此它可以在容器运行时运行。

#### 准备程序以动态加载模型构件
<a name="ml-preparing-your-program-to-dynamically-load-model-artifacts"></a>

 对于算法产品，买家使用自己的数据集和您的训练映像来生成独特的模型构件。训练过程完成后，您的训练容器会将模型工件输出到容器目录` /opt/ml/model/`。 SageMaker AI 将该目录中的内容压缩成.tar.gz 文件，并将其存储在买家的 Amazon S3 中。 AWS 账户 

 部署模型时， SageMaker AI 会运行您的推理图像，从 Amazon S3 中买家账户中存储的.tar.gz 文件中提取模型工件，然后将其加载到目录中的推理容器中。`/opt/ml/model/`在运行时，您的推理容器代码使用模型数据。

**注意**  
 要保护可能包含在模型构件文件中的知识产权，您可以选择在输出前对文件加密。有关更多信息，请参阅 [Amazon A SageMaker I 的安全和知识产权](ml-security-and-intellectual-property.md)。

### 第 2 步：在本地构建和测试映像
<a name="ml-step-2-building-and-testing-the-image-locally-2"></a>

 在构建上下文中，现在存在以下文件：
+ `./Dockerfile`
+ `./web_app_serve.py`
+ `./serve`

 接下来，您可以构建、运行和测试此容器映像。

#### 构建映像：
<a name="ml-build-the-image-2"></a>

 运行 Docker 命令来构建和标记映像。此示例使用标签 `my-inference-image`。

```
sudo docker build --tag my-inference-image ./
```

 运行此 Docker 命令构建映像后，当 Docker 根据您的 `Dockerfile` 的每一行构建映像时，您该会看到输出。完成后，您应看到类似如下所示的内容：

```
Successfully built abcdef123456
Successfully tagged my-inference-image:latest
```

#### 本地运行
<a name="ml-run-locally-2"></a>

 构建完成后，您可以在本地测试映像。

```
sudo docker run \
  --rm \
  --publish 8080:8080/tcp \
  --volume '<path_to_model>:/opt/ml/model:ro' \
  --detach \
  --name my-inference-container \
  my-inference-image \
  serve
```

 以下是命令的详细信息：
+  `--rm` – 容器停止后自动将其移除。
+  `--publish 8080:8080/tcp`— 公开端口 8080 以模拟 SageMaker AI 向其发送 HTTP 请求的端口。
+  `--volume '<path_to_model>:/opt/ml/model:ro'` –将测试模型构件在主机上存储的路径绑定挂载为只读，以便容器中的推理代码可以使用它们。
+  `--detach` – 在后台运行容器。
+  `--name my-inference-container` – 为正在运行的容器提供名称。
+  `my-inference-image` – 运行构建的映像。
+  `serve`— 运行 SageMaker AI 在运行容器时运行的相同脚本。

 运行此命令后，Docker 会根据推理映像创建一个容器并在后台运行它。容器运行 `serve` 脚本，该脚本会启动您的 Web 服务器以进行测试。

#### 测试 ping HTTP 端点
<a name="ml-test-the-ping-http-endpoint-1"></a>

 当 SageMaker AI 运行您的容器时，它会定期 ping 终端节点。 当终端节点返回状态代码为 200 的 HTTP 响应时，它会向 SageMaker AI 发出信号，表示容器已准备好进行推理。

 运行以下命令以测试端点并包含响应头。

```
curl --include http://127.0.0.1:8080/ping
```

 示例输出如以下示例中所示。

```
HTTP/1.0 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 0
Server: MyServer/0.16.0 Python/3.6.8
Date: Mon, 21 Oct 2019 06:58:54 GMT
```

#### 测试推理 HTTP 端点
<a name="ml-test-the-inference-http-endpoint-1"></a>

 当容器通过返回 200 状态码表示已准备就绪时， SageMaker AI 会通过`POST`请求将推理数据传递到 `/invocations` HTTP 终端节点。

 运行以下命令以测试推理端点。

```
curl \
  --request POST \
  --data "hello world" \
  http://127.0.0.1:8080/invocations
```

 示例输出如以下示例中所示：

```
{"prediction": "a", "text": "hello world"}
```

 在这两个 HTTP 端点工作后，推理图像现在与 SageMaker AI 兼容。

**注意**  
 您的算法产品的模型可以通过两种方式部署：实时部署和批量部署。对于这两种部署， SageMaker AI 在运行 Docker 容器时使用相同的 HTTP 端点。

 要停止容器，请运行以下命令。

```
sudo docker container stop my-inference-container
```

 算法产品的训练和推理映像都准备好并经过测试后，请继续[将映像上传到 Amazon Elastic Container Registry](ml-uploading-your-images.md)。