

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

# 使用 SageMaker AI 组件
<a name="kubernetes-sagemaker-components-tutorials"></a>

在本教程中，您将使用适用于 Kubeflow Pipelines 的 SageMaker AI 组件运行管道，在 AI 上使用 Kmeans 和 MNIST 数据集训练分类模型。 SageMaker 该工作流程使用 Kubeflow Pipelines 作为协调器，并使用 SageMaker AI 来执行工作流程的每个步骤。该示例取自现有的 [ SageMaker AI 示例](https://github.com/aws/amazon-sagemaker-examples/blob/8279abfcc78bad091608a4a7135e50a0bd0ec8bb/sagemaker-python-sdk/1P_kmeans_highlevel/kmeans_mnist.ipynb)，并进行了修改以与 Kubeflow P SageMaker ipelines 的 AI 组件配合使用。

你可以使用 Python 定义管道， 适用于 Python (Boto3) 的 AWS SDK 然后使用 KFP 控制面板、KFP CLI 或 Boto3 来编译、部署和运行工作流程。[Kubeflow GitHub 存储库](https://github.com/kubeflow/pipelines/tree/master/samples/contrib/aws-samples/mnist-kmeans-sagemaker#mnist-classification-with-kmeans)中提供了 MNIST 分类管道示例的完整代码。要使用该代码，请将 Python 文件克隆到您的网关节点。

你可以在上找到更多 [ SageMaker AI Kubeflow Pipelines 示例](https://github.com/kubeflow/pipelines/tree/master/samples/contrib/aws-samples)。 GitHub有关所用组件的信息，请参阅 Pipelin [KubeFlow es GitHub 存储库](https://github.com/kubeflow/pipelines/tree/master/components/aws/sagemaker)。

要运行分类管道示例，请创建一个 A SageMaker I IAM 执行角色，向您的训练作业授予访问 AWS 资源的权限，然后继续执行与您的部署选项相对应的步骤。

## 创建 A SageMaker I 执行角色
<a name="create-an-amazonsagemaker-execution-role"></a>

I `kfp-example-sagemaker-execution-role` AM 角色是 A SageMaker I 作业担任的 AWS 用于访问资源的运行时角色。在以下命令中，您可以创建名为的 IAM 执行角色`kfp-example-sagemaker-execution-role`，附加两个托管策略（AmazonSageMakerFullAccessAmazonS3FullAccess），并与 A SageMaker I 建立信任关系以授予 SageMaker AI 任务访问这些 AWS 资源的权限。

运行管道时，您可以将此角色作为输入参数提供。

运行以下命令以创建角色。记下在输出中返回的 ARN。

```
SAGEMAKER_EXECUTION_ROLE_NAME=kfp-example-sagemaker-execution-role

TRUST="{ \"Version\": \"2012-10-17		 	 	 \", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"Service\": \"sagemaker.amazonaws.com\" }, \"Action\": \"sts:AssumeRole\" } ] }"
aws iam create-role --role-name ${SAGEMAKER_EXECUTION_ROLE_NAME} --assume-role-policy-document "$TRUST"
aws iam attach-role-policy --role-name ${SAGEMAKER_EXECUTION_ROLE_NAME} --policy-arn arn:aws:iam::aws:policy/AmazonSageMakerFullAccess
aws iam attach-role-policy --role-name ${SAGEMAKER_EXECUTION_ROLE_NAME} --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

aws iam get-role --role-name ${SAGEMAKER_EXECUTION_ROLE_NAME} --output text --query 'Role.Arn'
```

## 部署时已完成 Kubeflow AWS
<a name="run-pipelines-on-full-kubeflow-deployment"></a>

按照 [K-Means 分类的 MNIST SageMaker 训练管道教程中的说明进行](https://awslabs.github.io/kubeflow-manifests/docs/amazon-sagemaker-integration/sagemaker-components-for-kubeflow-pipelines/)操作。

## 独立 Kubeflow Pipelines 部署
<a name="run-pipelines-on-standalone-kubeflow-pipelines-deployment"></a>

### 准备数据集
<a name="prepare-datasets"></a>

要运行管道，您需要将数据提取预处理脚本上传到 Amazon S3 存储桶。此存储桶和本示例的所有资源必须位于 `us-east-1` 区域。有关创建存储桶的信息，请参阅[创建存储桶](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)。

从您在网关节点上克隆的 Kubeflow 存储库的 `mnist-kmeans-sagemaker` 文件夹中，运行以下命令以将 `kmeans_preprocessing.py` 文件上传到 Amazon S3 存储桶。将 `<bucket-name>` 更改为 Amazon S3 存储桶的名称。

```
aws s3 cp mnist-kmeans-sagemaker/kmeans_preprocessing.py s3://{{<bucket-name>}}/mnist_kmeans_example/processing_code/kmeans_preprocessing.py
```

### 编译和部署管道
<a name="compile-and-deploy-your-pipeline"></a>

定义管道后，必须将其编译为中间表示形式，然后才能将其提交给集群上的 Kubeflow Pipelines 服务。中间表示形式是压缩成 tar.gz 文件的 YAML 文件形式的工作流规范。您需要 KFP SDK 来编译管道。

#### 安装 KFP SDK
<a name="install-kfp-sdk"></a>

从网关节点的命令行运行以下命令：

1. 按照 [Kubeflow Pipelines 文档](https://www.kubeflow.org/docs/pipelines/sdk/install-sdk/)中的说明安装 KFP SDK。

1. 使用以下命令验证是否已安装 KFP SDK：

   ```
   pip show kfp
   ```

1. 验证是否已正确安装 `dsl-compile`，如下所示：

   ```
   which dsl-compile
   ```

#### 编译管道
<a name="compile-your-pipeline"></a>

您可以通过三种方式与 Kubeflow Pipelines 进行交互：KFP UI、KFP CLI 或 KFP SDK。以下几节说明了使用 KFP UI 和 CLI 的工作流。

从网关节点完成以下步骤。

1. 使用您的 Amazon S3 存储桶名称和 IAM 角色 ARN 修改 Python 文件。

1. 使用命令行中的 `dsl-compile` 命令按如下方式编译管道。将 `<path-to-python-file>` 替换为管道的路径，将 `<path-to-output>` 替换为要将 tar.gz 文件放入的位置。

   ```
   dsl-compile --py {{<path-to-python-file>}} --output {{<path-to-output>}}
   ```

#### 使用 KFP CLI 上传并运行管道
<a name="upload-and-run-the-pipeline-using-the-kfp-cli"></a>

从网关节点的命令行完成以下步骤。KFP 将管道的运行组织为实验。您可以选择指定实验名称。如果您未指定名称，则运行将列在**默认**实验下。

1. 按如下方式上传管道：

   ```
   kfp pipeline upload --pipeline-name {{<pipeline-name>}} {{<path-to-output-tar.gz>}}
   ```

   您的输出应与以下内容类似。记下管道 `ID`。

   ```
   Pipeline 29c3ff21-49f5-4dfe-94f6-618c0e2420fe has been submitted
   
   Pipeline Details
   ------------------
   ID           29c3ff21-49f5-4dfe-94f6-618c0e2420fe
   Name         sm-pipeline
   Description
   Uploaded at  2020-04-30T20:22:39+00:00
   ...
   ...
   ```

1. 使用以下命令创建运行。KFP CLI 运行命令目前不支持在创建运行时指定输入参数。在编译之前，您需要更新 适用于 Python (Boto3) 的 AWS SDK 管道文件中的参数。将 `<experiment-name>` 和 `<job-name>` 替换为任意名称。将 `<pipeline-id>` 替换为所提交管道的 ID。将 `<your-role-arn>` 替换为 `kfp-example-pod-role` 的 ARN。将 `<your-bucket-name>` 替换为所创建 Amazon S3 存储桶的名称。

   ```
   kfp run submit --experiment-name {{<experiment-name>}} --run-name {{<job-name>}} --pipeline-id {{<pipeline-id>}} role_arn="{{<your-role-arn>}}" bucket_name="{{<your-bucket-name>}}"
   ```

   您也可以使用作为 `dsl-compile` 命令输出创建的已编译管道包直接提交运行。

   ```
   kfp run submit --experiment-name {{<experiment-name>}} --run-name {{<job-name>}} --package-file {{<path-to-output>}} role_arn="{{<your-role-arn>}}" bucket_name="{{<your-bucket-name>}}"
   ```

   您的输出应与以下内容类似：

   ```
   Creating experiment aws.
   Run 95084a2c-f18d-4b77-a9da-eba00bf01e63 is submitted
   +--------------------------------------+--------+----------+---------------------------+
   | run id                               | name   | status   | created at                |
   +======================================+========+==========+===========================+
   | 95084a2c-f18d-4b77-a9da-eba00bf01e63 | sm-job |          | 2020-04-30T20:36:41+00:00 |
   +--------------------------------------+--------+----------+---------------------------+
   ```

1. 导航到 UI 以检查作业的进度。

#### 使用 KFP UI 上传并运行管道
<a name="upload-and-run-the-pipeline-using-the-kfp-ui"></a>

1. 在左侧面板上，选择**管道**选项卡。

1. **在右上角，选择 \+。UploadPipeline**

1. 输入管道名称和描述。

1. 选择**上传文件**，然后输入您使用 CLI 或使用 适用于 Python (Boto3) 的 AWS SDK创建的 tar.gz 文件的路径。

1. 在左侧面板上，选择**管道**选项卡。

1. 找到您创建的管道。

1. 选择 **\+CreateRun**。

1. 输入您的输入参数。

1. 选择**运行**。

### 运行预测
<a name="running-predictions"></a>

一旦部署了分类管道，就可以针对部署组件创建的端点运行分类预测。使用 KFP UI 检查 `sagemaker-deploy-model-endpoint_name` 的输出构件。下载.tgz 文件以提取终端节点名称或查看您使用的区域中的 SageMaker AI 控制台。

#### 配置运行预测的权限
<a name="configure-permissions-to-run-predictions"></a>

如果您想从网关节点运行预测，请跳过本节。

**要使用任何其他计算机运行预测，请为客户端计算机使用的 IAM 角色分配 `sagemaker:InvokeEndpoint` 权限。**

1. 在您的网关节点上，运行以下命令以创建 IAM 策略文件：

   ```
   cat <<EoF > ./sagemaker-invoke.json
   {
       "Version": "2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "sagemaker:InvokeEndpoint"
               ],
               "Resource": "*"
           }
       ]
   }
   EoF
   ```

1. 将策略附加到客户端节点的 IAM 角色。

   运行如下命令。将 `<your-instance-IAM-role>` 替换为 IAM 角色的名称。将 `<path-to-sagemaker-invoke-json>` 替换为所创建策略文件的路径。

   ```
   aws iam put-role-policy --role-name {{<your-instance-IAM-role>}} --policy-name sagemaker-invoke-for-worker --policy-document file://{{<path-to-sagemaker-invoke-json>}}
   ```

#### 运行预测
<a name="run-predictions"></a>

1. 在您的客户端计算机上创建一个名为以下内容`mnist-predictions.py`的 适用于 Python (Boto3) 的 AWS SDK 文件。替换 `ENDPOINT_NAME` 变量。该脚本加载 MNIST 数据集，根据这些数字创建 CSV，然后将 CSV 发送到端点进行预测并打印结果。

   ```
   import boto3
   import gzip
   import io
   import json
   import numpy
   import pickle
   
   ENDPOINT_NAME='{{<endpoint-name>}}'
   region = boto3.Session().region_name
   
   # S3 bucket where the original mnist data is downloaded and stored
   downloaded_data_bucket = f"jumpstart-cache-prod-{region}"
   downloaded_data_prefix = "1p-notebooks-datasets/mnist"
   
   # Download the dataset
   s3 = boto3.client("s3")
   s3.download_file(downloaded_data_bucket, f"{downloaded_data_prefix}/mnist.pkl.gz", "mnist.pkl.gz")
   
   # Load the dataset
   with gzip.open('mnist.pkl.gz', 'rb') as f:
       train_set, valid_set, test_set = pickle.load(f, encoding='latin1')
   
   # Simple function to create a csv from our numpy array
   def np2csv(arr):
       csv = io.BytesIO()
       numpy.savetxt(csv, arr, delimiter=',', fmt='%g')
       return csv.getvalue().decode().rstrip()
   
   runtime = boto3.Session(region).client('sagemaker-runtime')
   
   payload = np2csv(train_set[0][30:31])
   
   response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME,
                                      ContentType='text/csv',
                                      Body=payload)
   result = json.loads(response['Body'].read().decode())
   print(result)
   ```

1. 按如下方式运行该 适用于 Python (Boto3) 的 AWS SDK 文件：

   ```
   python mnist-predictions.py
   ```

### 查看结果和日志
<a name="view-results-and-logs"></a>

当管道正在运行时，您可以选择任何组件来查看执行详细信息，例如输入和输出。这将列出已创建资源的名称。

如果成功处理了 KFP 请求并创建了 A SageMaker I 作业，KFP UI 中的组件日志将提供指向在 AI 中 SageMaker 创建的任务的链接。如果任务成功创建，还会提供 CloudWatch 日志。

如果您在同一集群上运行过多管道作业，则可能会看到一条错误消息，表明您没有足够的 Pod 可用。要解决此问题，请登录您的网关节点，然后删除由您未使用的管道创建的 Pod：

```
kubectl get pods -n kubeflow
kubectl delete pods -n kubeflow {{<name-of-pipeline-pod>}}
```

### 清理
<a name="cleanup"></a>

完成管道后，您需要清理资源。

1. 在 KFP 控制面板中，如果管道运行未正常退出，请选择**终止**来终止管道运行。

1. 如果**终止**选项不起作用，请登录网关节点，然后手动终止由您的管道创建的所有 Pod，如下所示：

   ```
   kubectl get pods -n kubeflow
   kubectl delete pods -n kubeflow {{<name-of-pipeline-pod>}}
   ```

1. 使用您的 AWS 帐户登录 A SageMaker I 服务。手动停止所有训练、批量转换和 HPO 作业。删除模型、数据存储桶和端点，以免产生任何额外费用。终止管道运行并不能停止 SageMaker AI 中的作业。