

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

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

在本教學課程中，您會使用適用於 Kubeflow 管道的 SageMaker AI 元件來執行管道，以使用 Kmeans 搭配 SageMaker AI 上的 MNIST 資料集來訓練分類模型。此工作流程使用 Kubeflow 管道作為協調器，並使用 SageMaker AI 來執行工作流程的每個步驟。此範例取自現有的 [SageMaker AI 範例](https://github.com/aws/amazon-sagemaker-examples/blob/8279abfcc78bad091608a4a7135e50a0bd0ec8bb/sagemaker-python-sdk/1P_kmeans_highlevel/kmeans_mnist.ipynb)，並經過修改，以使用適用於 Kubeflow 管道的 SageMaker AI 元件。

您可以在 Python 中使用 定義管道， 適用於 Python (Boto3) 的 AWS SDK 然後使用 KFP 儀表板、KFP CLI 或 Boto3 來編譯、部署和執行工作流程。MNIST 分類管道範例的完整程式碼可在 [Kubeflow Github 儲存庫](https://github.com/kubeflow/pipelines/tree/master/samples/contrib/aws-samples/mnist-kmeans-sagemaker#mnist-classification-with-kmeans)中取得。要使用它，請將 Python 檔案複製到您的網關節點。

您可以在 GitHub 上找到其他 [SageMaker AI Kubeflow 管道範例](https://github.com/kubeflow/pipelines/tree/master/samples/contrib/aws-samples)。如需與所使用元件相關的資訊，請參閱 [KubeFlow 管道 GitHub 儲存庫](https://github.com/kubeflow/pipelines/tree/master/components/aws/sagemaker)。

若要執行分類管道範例，請建立 SageMaker AI IAM 執行角色，授予訓練任務存取 AWS 資源的許可，然後繼續執行與您的部署選項對應的步驟。

## 建立一個 SageMaker AI 執行角色
<a name="create-an-amazonsagemaker-execution-role"></a>

IAM `kfp-example-sagemaker-execution-role` 角色是由 SageMaker AI 任務擔任的執行期角色，用於存取 AWS 資源。在下列命令中，您可以建立名為 的 IAM 執行角色`kfp-example-sagemaker-execution-role`，連接兩個受管政策 (AmazonSageMakerFullAccess、AmazonS3FullAccess)，並與 SageMaker AI 建立信任關係，以授予 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'
```

## AWS 部署時的完整 Kubeflow
<a name="run-pipelines-on-full-kubeflow-deployment"></a>

請遵循 [SageMaker 訓練管道教學課程中的指示，使用 K 平均數對 MNIST 進行分類](https://awslabs.github.io/kubeflow-manifests/docs/amazon-sagemaker-integration/sagemaker-components-for-kubeflow-pipelines/)。

## 獨立 Kubeflow 管道部署
<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 管道服務。中繼表示形式是壓縮成 tar.gz 檔案的 YAML 檔案形式的工作流程規格。您需要 KFP SDK 來編譯管道。

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

從閘道節點的命令列執行下列命令：

1. 按照 [Kubeflow 管道文件](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 管道互動：KFP UI、KFP CLI 或 KFP SDK。以下各節說明使用 KFP 使用者介面和 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. 導覽至使用者介面以檢查工作進度。

#### 使用 KFP 使用者介面上傳並執行管道
<a name="upload-and-run-the-pipeline-using-the-kfp-ui"></a>

1. 在左側面板中，選擇**管道**標籤。

1. 在右上角選擇 **\+ 上傳管道**。

1. 輸入名稱和描述。

1. 選擇**上傳檔案**，然後輸入您使用 CLI 或使用 適用於 Python (Boto3) 的 AWS SDK建立之 tar.gz 檔案的路徑。

1. 在左側面板中，選擇**管道**標籤。

1. 尋找您建立的管道。

1. 選擇 **\+ 建立執行**。

1. 輸入您的輸入參數。

1. 選擇**執行**。

### 執行預測
<a name="running-predictions"></a>

部署分類管道後，您可以針對由部署元件建立的端點執行分類預測。使用 KFP 使用者介面檢查 `sagemaker-deploy-model-endpoint_name` 的輸出成品。下載 .tgz 檔案以擷取端點名稱，或檢查您所使用區域中的 SageMaker AI 主控台。

#### 設定執行預測的許可
<a name="configure-permissions-to-run-predictions"></a>

如果要從閘道節點執行預測，請略過本節。

**若要使用任何其他機器執行預測，請將 `sagemaker:InvokeEndpoint` 許可指派給用戶端機器使用的 IAM 角色。**

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 要求並建立了 SageMaker AI 工作，則 KFP UI 中的元件日誌會提供在 SageMaker AI 中建立之任務的連結。如果成功建立工作，也會提供 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 您的帳戶登入 SageMaker AI 服務。手動停止所有訓練、批次轉換和 HPO 工作。刪除模型、資料儲存貯體和端點，以避免產生任何額外費用。終止管道執行並不會停止 SageMaker AI 中的任務。