

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

# 使用 在自訂標記工作流程中處理資料 AWS Lambda
<a name="sms-custom-templates-step3"></a>

在本主題中，您可以了解如何在建立自訂標籤工作流程時部署選用 [AWS Lambda](https://aws.amazon.com/lambda/) 函式。您可以指定兩種 Lambda 函式類型，以搭配使用自訂標籤工作流程。
+ *註釋前 Lambda*：此函式在傳送每個資料物件給工作者之前，會先進行預先處理。
+ *註釋後 Lambda*：此函式會在工作者提交任務之後處理結果。如您為每個資料物件指定多個工作者，則此函式可能包含合併註釋邏輯。

如您是 Lambda 與 Ground Truth 新使用者，建議您運用本節頁面，如下所示：

1. 首先，檢閱[使用註釋前與註釋後 Lambda 函式使用 Lambda 函式](sms-custom-templates-step3-lambda-requirements.md)。

1. 然後，利用頁面[新增與 Ground Truth AWS Lambda 搭配使用的必要許可](sms-custom-templates-step3-lambda-permissions.md)了解安全性與權限要求，以便在 Ground Truth 自訂標籤工作運用註釋前和註釋後 Lambda 函式。

1. 接著，您必須先前往 Lambda 主控台或運用 Lambda API 來建立您的函式。您可利用[使用 Ground Truth 範本建立 Lambda 函式](sms-custom-templates-step3-lambda-create.md)一節了解如何建立 Lambda 函式。

1. 了解如何測試您的 Lambda 函式，請參閱[測試註釋前與註釋後 Lambda 函式](sms-custom-templates-step3-lambda-test.md)。

1. 在建立預先處理及事後處理 Lambda 函式之後，請從 **Lambda 函式**區段加以選取，該區段位於 Ground Truth 主控台的自訂 HTML 程式碼編輯器之後。若要了解如何在 `CreateLabelingJob` API 請求運用這些函式，請參閱[建立標籤工作 (API)](sms-create-labeling-job-api.md)。

如需自訂標籤工作流程教學課程 (其中包含註釋前及註釋後 Lambda 函式範例)，請參閱 [示範範本：使用 `crowd-bounding-box` 註釋影像](sms-custom-templates-step2-demo1.md)。

**Topics**
+ [使用註釋前與註釋後 Lambda 函式](sms-custom-templates-step3-lambda-requirements.md)
+ [新增與 Ground Truth AWS Lambda 搭配使用的必要許可](sms-custom-templates-step3-lambda-permissions.md)
+ [使用 Ground Truth 範本建立 Lambda 函式](sms-custom-templates-step3-lambda-create.md)
+ [測試註釋前與註釋後 Lambda 函式](sms-custom-templates-step3-lambda-test.md)

# 使用註釋前與註釋後 Lambda 函式
<a name="sms-custom-templates-step3-lambda-requirements"></a>

您可以利用這些主題了解請求語法以便傳送至註釋前及註釋後 Lambda 函式，以及 Ground Truth 在自訂標籤工作流程中使用的必要回應語法。

**Topics**
+ [註釋前 Lambda](#sms-custom-templates-step3-prelambda)
+ [註釋後 Lambda](#sms-custom-templates-step3-postlambda)

## 註釋前 Lambda
<a name="sms-custom-templates-step3-prelambda"></a>

在傳送標籤任務給工作者之前，可以調用選用註釋前 Lambda 函式。

Ground Truth 會向 Lambda 函式傳送 JSON 格式請求，以便針對標籤工作與資料物件提供詳細資訊。

以下是 2 個 JSON 格式請求範例。

------
#### [ Data object identified with "source-ref" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": <labelingJobArn>
    "dataObject" : {
        "source-ref": <s3Uri>
    }
}
```

------
#### [ Data object identified with "source" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": <labelingJobArn>
    "dataObject" : {
        "source": <string>
    }
}
```

------

 下列清單包含註釋前請求結構描述。每個參數如下所述。
+ `version` (字串)：這是 Ground Truth 內部使用的版本號碼。
+ `labelingJobArn` (字串)：這是標籤工作的 Amazon Resource Name 或 ARN。當利用 Ground Truth API 作業 (例如 `DescribeLabelingJob`) 時，此 ARN 可用於參照標籤工作。
+ `dataObject` (JSON 物件)：此索引鍵包含單一 JSON 行，可能是從您的輸入資訊清單檔案或從 Amazon SNS 傳送。資訊清單中的 JSON line 物件最大為 100 KB，並且可包含各式各樣的資料。對於非常基本的影像註釋工作，`dataObject` JSON 可能僅包含 `source-ref` 鍵，用於識別要註釋的影像。如資料物件 (例如，一行文字) 直接包含在輸入資訊清單檔案，則會識別資料物件為 `source`。如您建立驗證或調整工作，則此行可能包含先前標籤工作的標籤資料與中繼資料。

下列標籤範例是註釋前請求範例。這些範例請求的每個參數都會在標籤式表格下方說明。

------
#### [ Data object identified with "source-ref" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": "arn:aws:sagemaker:us-west-2:111122223333:labeling-job/<labeling_job_name>"
    "dataObject" : {
        "source-ref": "s3://input-data-bucket/data-object-file-name"
    }
}
```

------
#### [ Data object identified with "source" ]

```
{
    "version": "2018-10-16",
    "labelingJobArn": "arn:aws:sagemaker:<aws_region>:111122223333:labeling-job/<labeling_job_name>"
    "dataObject" : {
        "source": "Sue purchased 10 shares of the stock on April 10th, 2020"
    }
}
```

------

作為回報，Ground Truth 需要格式如下的回應：

**Example 預期傳回的資料**  

```
{
    "taskInput": <json object>,
    "isHumanAnnotationRequired": <boolean> # Optional
}
```

在上述範例，`<json object>` 需要包含自訂工作者任務範本所需的*所有*資料。如果您正在執行其中說明一律保持不變的邊界框任務，則其可能只是影像檔案的 HTTP(S) 或 Amazon S3 資源。如果其為情感分析任務，且不同物件可能有不同的選擇，那麼其是做為字串的物件參考、做為字串陣列的選擇。

**`isHumanAnnotationRequired` 的意義**  
這個值是選用的，因為它預設為 `true`。明確設定此值的主要使用案例是，您希望排除此資料物件不被人力工作者標籤。

如果資訊清單中有混合的物件，其中有一些需要人工註釋，而有些則不需要，則您可以在每個資料物件中包含 `isHumanAnnotationRequired` 值。您可新增邏輯至註釋前 Lambda，以便動態判斷物件是否需要註釋，並相應設定此布林值。

### 註釋前 Lambda 函式範例
<a name="sms-custom-templates-step3-prelambda-example"></a>

以下基本註釋前 Lambda 函式從初始請求的 `dataObject` 存取 JSON 物件，並以 `taskInput` 參數將其傳回。

```
import json

def lambda_handler(event, context):
    return {
        "taskInput":  event['dataObject']
    }
```

假設輸入資訊清單檔案使用 `"source-ref"` 來識別資料物件，則與此註釋前 Lambda 相同標籤工作所用的工作者任務範本必須包含如下所示的 Liquid 元素才能擷取 `dataObject`：

```
{{ task.input.source-ref | grant_read_access }}
```

如果輸入資訊清單檔案利用 `source` 來識別資料物件，則工作任務範本可利用下列內容擷取 `dataObject`：

```
{{ task.input.source }}
```

下列註釋前 Lambda 範例包含邏輯，可用於識別 `dataObject` 所用的索引鍵，並使用 Lambda return 陳述式的 `taskObject` 來指向該資料物件。

```
import json

def lambda_handler(event, context):

    # Event received
    print("Received event: " + json.dumps(event, indent=2))

    # Get source if specified
    source = event['dataObject']['source'] if "source" in event['dataObject'] else None

    # Get source-ref if specified
    source_ref = event['dataObject']['source-ref'] if "source-ref" in event['dataObject'] else None

    # if source field present, take that otherwise take source-ref
    task_object = source if source is not None else source_ref

    # Build response object
    output = {
        "taskInput": {
            "taskObject": task_object
        },
        "humanAnnotationRequired": "true"
    }

    print(output)
    # If neither source nor source-ref specified, mark the annotation failed
    if task_object is None:
        print(" Failed to pre-process {} !".format(event["labelingJobArn"]))
        output["humanAnnotationRequired"] = "false"

    return output
```

## 註釋後 Lambda
<a name="sms-custom-templates-step3-postlambda"></a>

當所有工作者已註釋資料物件，或在已達到 [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanLoopConfig.html#SageMaker-Type-HumanLoopConfig-TaskAvailabilityLifetimeInSeconds](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_HumanLoopConfig.html#SageMaker-Type-HumanLoopConfig-TaskAvailabilityLifetimeInSeconds) 時 (以先發生者為準)，Ground Truth 會將這些註釋傳送到您的註釋後 Lambda。此 Lambda 通常用於[註釋整合](sms-annotation-consolidation.md)。

**注意**  
若要查看合併後 Lambda 函式範例，請參閱 GitHub 儲存庫 [aws-sagemaker-ground-truth-recipe](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe) 的 [annotation\$1consolidation\$1lambda.py](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe/blob/master/aws_sagemaker_ground_truth_sample_lambda/annotation_consolidation_lambda.py)。

下列程式碼區塊包含註釋後請求結構描述。每個參數皆詳述於下列項目符號清單。

```
{
    "version": "2018-10-16",
    "labelingJobArn": <string>,
    "labelCategories": [<string>],
    "labelAttributeName": <string>,
    "roleArn" : <string>,
    "payload": {
        "s3Uri": <string>
    }
 }
```
+ `version` (字串)：Ground Truth 內部使用的版本號碼。
+ `labelingJobArn` (字串)：標籤工作的 Amazon Resource Name 或 ARN。當利用 Ground Truth API 作業 (例如 `DescribeLabelingJob`) 時，此 ARN 可用於參照標籤工作。
+ `labelCategories` (字串清單)：包括您在主控台指定的標籤類別與其他屬性，或包含在標籤類別組態檔案的標籤類別與其他屬性。
+ `labelAttributeName` (字串)：標籤工作的名稱，或在建立標籤工作時指定的標籤屬性名稱。
+ `roleArn` (字串)：在建立標籤工作時針對 IAM 執行角色指定的 Amazon Resource Name (ARN)。
+ `payload` (JSON 物件)：包含 `s3Uri` 索引鍵的 JSON，可識別該資料物件在 Amazon S3 的註釋資料位置。下列第二個程式碼區塊顯示此註釋檔案範例。

下列程式碼區塊包含註釋後請求範例。此範例請求的每個參數都會在程式碼區塊下方說明。

**Example 註釋後 Lambda 請求**  

```
{
    "version": "2018-10-16",
    "labelingJobArn": "arn:aws:sagemaker:us-west-2:111122223333:labeling-job/labeling-job-name",
    "labelCategories": ["Ex Category1","Ex Category2", "Ex Category3"],
    "labelAttributeName": "labeling-job-attribute-name",
    "roleArn" : "arn:aws:iam::111122223333:role/role-name",
    "payload": {
        "s3Uri": "s3://amzn-s3-demo-bucket/annotations.json"
    }
 }
```

**注意**  
如無工作者處理資料物件，且已達到 `TaskAvailabilityLifetimeInSeconds`，則會標記資料物件為失敗，也不會納入註釋後 Lambda 調用。

下列程式碼區塊包含承載結構描述。這是由註釋後 Lambda 請求 `payload` JSON 物件的 `s3Uri` 參數指示的檔案。例如，如先前的程式碼區塊是註釋後 Lambda 請求，則下列註釋檔案位於 `s3://amzn-s3-demo-bucket/annotations.json`。

每個參數皆詳述於下列項目符號清單。

**Example 註釋檔案**  

```
[
    {
        "datasetObjectId": <string>,
        "dataObject": {
            "s3Uri": <string>,
            "content": <string>
        },
        "annotations": [{
            "workerId": <string>,
            "annotationData": {
                "content": <string>,
                "s3Uri": <string>
            }
       }]
    }
]
```
+ `datasetObjectId` (字串)：針對您傳送至標籤工作的每個資料物件識別 Ground Truth 向其指派的唯一 ID。
+ `dataObject` (JSON 物件)：已標籤的資料物件。如資料物件包含在輸入資訊清單檔案，且利用 `source` 索引鍵 (例如字串) 加以識別，則 `dataObject` 會包含可識別該資料物件的 `content` 索引鍵。否則，該資料物件的位置 (例如，連結或 S3 URI) 會識別為 `s3Uri`。
+ `annotations` (JSON 物件清單)：此清單包含工作者針對此 `dataObject` 所提交每個註釋的單一 JSON 物件。單一 JSON 物件包含唯一 `workerId`，可用來識別提交該註釋的工作者。`annotationData` 索引鍵包含以下其中一項：
  + `content` (字串)：包含註釋資料。
  + `s3Uri` (字串)：包含可識別註釋資料位置的 S3 URI。

下表包含在不同類型註釋的承載您可能找到的內容範例。

------
#### [ Named Entity Recognition Payload ]

```
[
    {
      "datasetObjectId": "1",
      "dataObject": {
        "content": "Sift 3 cups of flour into the bowl."
      },
      "annotations": [
        {
          "workerId": "private.us-west-2.ef7294f850a3d9d1",
          "annotationData": {
            "content": "{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":4,\"label\":\"verb\",\"startOffset\":0},{\"endOffset\":6,\"label\":\"number\",\"startOffset\":5},{\"endOffset\":20,\"label\":\"object\",\"startOffset\":15},{\"endOffset\":34,\"label\":\"object\",\"startOffset\":30}]}}"
          }
        }
      ]
    }
]
```

------
#### [ Semantic Segmentation Payload ]

```
[
    {
      "datasetObjectId": "2",
      "dataObject": {
        "s3Uri": "s3://amzn-s3-demo-bucket/gt-input-data/images/bird3.jpg"
      },
      "annotations": [
        {
          "workerId": "private.us-west-2.ab1234c5678a919d0",
          "annotationData": {
            "content": "{\"crowd-semantic-segmentation\":{\"inputImageProperties\":{\"height\":2000,\"width\":3020},\"labelMappings\":{\"Bird\":{\"color\":\"#2ca02c\"}},\"labeledImage\":{\"pngImageData\":\"iVBOR...\"}}}"
          }
        }
      ]
    }
  ]
```

------
#### [ Bounding Box Payload ]

```
[
    {
      "datasetObjectId": "0",
      "dataObject": {
        "s3Uri": "s3://amzn-s3-demo-bucket/gt-input-data/images/bird1.jpg"
      },
      "annotations": [
        {
          "workerId": "private.us-west-2.ab1234c5678a919d0",
          "annotationData": {
            "content": "{\"boundingBox\":{\"boundingBoxes\":[{\"height\":2052,\"label\":\"Bird\",\"left\":583,\"top\":302,\"width\":1375}],\"inputImageProperties\":{\"height\":2497,\"width\":3745}}}"
          }
        }
      ]
    }
 ]
```

------

您的註釋後 Lambda 函式可能包含類似以下內容的邏輯，以便循環檢視並存取請求所包含的所有註釋。如需完整範例，請參閱 GitHub 儲存庫 [aws-sagemaker-ground-truth-recipe](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe) 的 [annotation\$1consolidation\$1lambda.py](https://github.com/aws-samples/aws-sagemaker-ground-truth-recipe/blob/master/aws_sagemaker_ground_truth_sample_lambda/annotation_consolidation_lambda.py)。在此 GitHub 範例，您必須新增自己的註釋合併邏輯。

```
for i in range(len(annotations)):
    worker_id = annotations[i]["workerId"]
    annotation_content = annotations[i]['annotationData'].get('content')
    annotation_s3_uri = annotations[i]['annotationData'].get('s3uri')
    annotation = annotation_content if annotation_s3_uri is None else s3_client.get_object_from_s3(
        annotation_s3_uri)
    annotation_from_single_worker = json.loads(annotation)

    print("{} Received Annotations from worker [{}] is [{}]"
            .format(log_prefix, worker_id, annotation_from_single_worker))
```

**提示**  
當您執行資料合併演算法時，您可利用 AWS 資料庫服務來儲存結果，或者您可將處理結果傳回 Ground Truth。您傳回 Ground Truth 的資料會儲存在 S3 儲存貯體 (已於標籤工作設定期間指定用於輸出) 的合併註釋清單檔案。

作為回報，Ground Truth 需要格式如下的回應：

**Example 預期傳回的資料**  

```
[
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    },
   {        
        "datasetObjectId": <string>,
        "consolidatedAnnotation": {
            "content": {
                "<labelattributename>": {
                    # ... label content
                }
            }
        }
    }
    .
    .
    .
]
```
此時，所有傳送到您 S3 儲存貯體的資料 (除了 `datasetObjectId` 之外) 位於 `content` 物件。

當您傳回 `content` 的註釋時，會在工作輸出資訊清單檔案產生項目，如下所示：

**Example 輸出資訊清單中的標籤格式**  

```
{  "source-ref"/"source" : "<s3uri or content>", 
   "<labelAttributeName>": {
        # ... label content from you
    },   
   "<labelAttributeName>-metadata": { # This will be added by Ground Truth
        "job_name": <labelingJobName>,
        "type": "groundTruth/custom",
        "human-annotated": "yes", 
        "creation_date": <date> # Timestamp of when received from Post-labeling Lambda
    }
}
```

由於自訂範本及其收集的資訊可能相當複雜，因此 Ground Truth 不會針對資料提供進一步處理。

# 新增與 Ground Truth AWS Lambda 搭配使用的必要許可
<a name="sms-custom-templates-step3-lambda-permissions"></a>

您可能需要設定以下部分或所有內容才能建立 AWS Lambda 並搭配使用 Ground Truth。
+ 您需要授予 IAM 角色或使用者 （統稱為 IAM 實體） 使用 建立註釋前和註釋後 Lambda 函數的許可 AWS Lambda，並在建立標籤任務時選擇它們。
+ 在設定標籤工作時指定的 IAM 執行角色需要權限才能調用註釋前與註釋後 Lambda 函式。
+ 註釋後 Lambda 函式可能需要權限才能存取 Amazon S3。

請參閱以下各節，了解如何建立 IAM 實體並授予上述權限。

**Topics**
+ [授予建立和選取 AWS Lambda 函數的許可](#sms-custom-templates-step3-postlambda-create-perms)
+ [授予 IAM 執行角色叫用 AWS Lambda 函數的許可](#sms-custom-templates-step3-postlambda-execution-role-perms)
+ [授予註釋後 Lambda 權限以便存取註釋](#sms-custom-templates-step3-postlambda-perms)

## 授予建立和選取 AWS Lambda 函數的許可
<a name="sms-custom-templates-step3-postlambda-create-perms"></a>

如果您不需要精細的許可來開發註釋前和註釋後 Lambda 函數，您可以將 AWS 受管政策連接到`AWSLambda_FullAccess`使用者或角色。此政策授予廣泛的許可，以使用所有 Lambda 功能，以及在 Lambda 與之互動的其他 AWS 服務中執行動作的許可。

若要為安全敏感的使用案例建立更精細的政策，請參閱《 AWS Lambda 開發人員指南》中的 [Lambda 的身分型 IAM 政策](https://docs.aws.amazon.com/lambda/latest/dg/access-control-identity-based.html)文件，了解如何建立適合您使用案例的 IAM 政策。

**使用 Lambda 主控台政策**

如果您想要授予 IAM 實體使用 Lambda 主控台的許可，請參閱《 AWS Lambda 開發人員指南》中的[使用 Lambda 主控台](https://docs.aws.amazon.com/lambda/latest/dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-console)。

此外，如果您希望使用者能夠在 Lambda 主控台 AWS Serverless Application Repository 中使用 存取和部署 Ground Truth 啟動者註釋前和註釋後函數，您必須指定要部署函數的 *`<aws-region>`* （這應該與用來建立標記任務 AWS 的區域相同），並將下列政策新增至 IAM 角色。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "serverlessrepo:ListApplicationVersions",
                "serverlessrepo:GetApplication",
                "serverlessrepo:CreateCloudFormationTemplate"
            ],
            "Resource": "arn:aws:serverlessrepo:us-east-1:838997950401:applications/aws-sagemaker-ground-truth-recipe"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "serverlessrepo:SearchApplications",
            "Resource": "*"
        }
    ]
}
```

------

**查看 Ground Truth 主控台 Lambda 函式的政策**

若要在使用者建立自訂標籤工作時，授予 IAM 實體權限以便檢視 Ground Truth 主控台的 Lambda 函式，該實體必須具有[授予 IAM 許可以使用 Amazon SageMaker Ground Truth 主控台](sms-security-permission-console-access.md)所述的權限，包括[自訂標籤工作流程許可](sms-security-permission-console-access.md#sms-security-permissions-custom-workflow)一節所述的權限。

## 授予 IAM 執行角色叫用 AWS Lambda 函數的許可
<a name="sms-custom-templates-step3-postlambda-execution-role-perms"></a>

如您新增 IAM 受管政策 [AmazonSageMakerGroundTruthExecution](https://console.aws.amazon.com/iam/home?#/policies/arn:aws:iam::aws:policy/AmazonSageMakerGroundTruthExecution) 至用於建立標籤工作的 IAM 執行角色，則此角色擁有權限可列出及調用 Lambda 函式，前提是其函式名稱必須具下列其中一個字串：`GtRecipe`、`SageMaker`、`Sagemaker`、`sagemaker` 或 `LabelingFunction`。

如註釋前或註釋後 Lambda 函式名稱未包含前段所述其中一個術語，或者您需要比 `AmazonSageMakerGroundTruthExecution` 受管政策所含更精細的權限，則可新增類似下列政策，以便授予執行角色權限來調用註釋前與註釋後函式。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "lambda:InvokeFunction",
            "Resource": [
                "arn:aws:lambda:us-east-1:111122223333:function:<pre-annotation-lambda-name>",
                "arn:aws:lambda:us-east-1:111122223333:function:<post-annotation-lambda-name>"
            ]
        }
    ]
}
```

------

## 授予註釋後 Lambda 權限以便存取註釋
<a name="sms-custom-templates-step3-postlambda-perms"></a>

如[註釋後 Lambda](sms-custom-templates-step3-lambda-requirements.md#sms-custom-templates-step3-postlambda)所述，註釋後 Lambda 請求包括註釋資料的 Amazon S3 位置。此位置由 `payload` 物件的 `s3Uri` 字串識別。若要處理註釋 (即使是簡單的傳遞函式)，您也需要向註釋後 [Lambda 執行角色](https://docs.aws.amazon.com/lambda/latest/dg/lambda-intro-execution-role.html)指派必要權限，以便從 Amazon S3 讀取檔案。

您可利用許多方法來設定 Lambda 並存取 Amazon S3 的註釋資料。兩種常見方法是：
+ 允許 Lambda 執行角色擔任 SageMaker AI 執行角色 (於註釋後 Lambda 請求的 `roleArn` 識別)。此 SageMaker AI 執行角色是用來建立標籤工作的角色，可存取儲存註釋資料的 Amazon S3 輸出儲存貯體。
+ 授予 Lambda 執行角色權限，以便直接存取 Amazon S3 輸出儲存貯體。

請參閱下列各節來了解如何設定這些選項。

**授予 Lambda 權限以便擔任 SageMaker AI 執行角色**

若要允許 Lambda 函式擔任 SageMaker AI 執行角色，您必須附加政策至 Lambda 函式的執行角色，並修改 SageMaker AI 執行角色的信任關係，以便允許 Lambda 擔任該角色。

1. [附加下列 IAM 政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html)至 Lambda 函式的執行角色，以便擔任 `Resource` 所識別的 SageMaker AI 執行角色。將 `222222222222` 取代為 [AWS 帳戶 ID](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html)。將 `sm-execution-role` 取代為所擔任角色的名稱。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": {
           "Effect": "Allow",
           "Action": "sts:AssumeRole",
           "Resource": "arn:aws:iam::222222222222:role/sm-execution-role"
       }
   }
   ```

------

1. [修改 SageMaker AI 執行角色的信任政策](https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-managingrole-editing-console.html#roles-managingrole_edit-trust-policy)，並納入下列 `Statement`。將 `222222222222` 取代為 [AWS 帳戶 ID](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html)。將 `my-lambda-execution-role` 取代為所擔任角色的名稱。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Principal": {
                   "AWS": "arn:aws:iam::222222222222:role/my-lambda-execution-role"
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

**授予 Lambda 執行角色權限以便存取 S3**

您可新增類似下列內容的政策至註釋後 Lambda 函式執行角色，以授予其 S3 讀取權限。使用您在建立標籤工作時指定的輸出儲存貯體名稱來取代 *amzn-s3-demo-bucket*。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
        }
    ]
}
```

------

若要新增 S3 讀取權限至 Lambda 主控台的 Lambda 執行角色，請採用下列程序。

**新增 S3 讀取權限至註釋後 Lambda：**

1. 開啟 Lambda 主控台的 [**Functions** (函式) 頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選擇註釋後函式的名稱。

1. 選擇 **Configuration** (組態)，然後選擇 **Permissions** (權限)。

1. 選取 **Role name** (角色名稱)，該角色的摘要頁面立即在 IAM 主控台的新索引標籤開啟。

1. 選取 **Attach policies** (附加政策)。

1. 執行以下任意一項：
   + 搜尋並選取 **`AmazonS3ReadOnlyAccess`**，以便授予函式權限來讀取帳戶的所有儲存貯體與物件。
   + 如您需要更精細的權限，請選取 **Create policy** (建立政策)，然後利用上一節的政策範例來建立政策。請注意，在建立政策之後，您必須導覽回執行角色摘要頁面。

1. 如您採用 `AmazonS3ReadOnlyAccess` 受管政策，請選取 **Attach policy** (附加政策)。

   如您已建立新政策，請導覽回 Lambda 執行角色摘要頁面，並附加您剛建立的政策。

# 使用 Ground Truth 範本建立 Lambda 函式
<a name="sms-custom-templates-step3-lambda-create"></a>

您可以使用 Lambda 主控台 AWS CLI、 或 AWS SDK，以您選擇的支援程式設計語言來建立 Lambda 函數。使用 AWS Lambda 開發人員指南進一步了解下列每個選項：
+ 若要了解如何使用主控台建立 Lambda 函式，請參閱[使用主控台建立 Lambda 函式](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html)。
+ 若要了解如何使用 建立 Lambda 函數 AWS CLI，請參閱[搭配 AWS 命令列界面使用 AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html)。
+ 選取目錄的相關章節，進一步了解如何透過您選擇的語言運用 Lambda。例如，選取[運用 Python](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html) 來進一步了解如何搭配 適用於 Python (Boto3) 的 AWS SDK使用 Lambda。

Ground Truth 透過 AWS Serverless Application Repository (SAR) *配方*提供註釋前和註釋後範本。利用以下程序在 Lambda 主控台選取 Ground Truth 配方。

**利用 Ground Truth SAR 配方來建立註釋前與註釋後 Lambda 函式：**

1. 開啟 Lambda 主控台的 [**Functions** (函式) 頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 選取 **Create function** (建立函式)。

1. 選取 **Browse serverless app repository** (瀏覽無伺服器應用程式儲存庫)。

1. 在搜尋文字方塊輸入 **aws-sagemaker-ground-truth-recipe**，然後選取該應用程式。

1. 選取 **Deploy** (部署)。該應用程式可能需要幾分鐘時間來部署。

   在部署應用程式之後，Lambda 主控台的 **Functions** (函式) 區段會出現兩個函式：`serverlessrepo-aws-sagema-GtRecipePreHumanTaskFunc-<id>` 與 `serverlessrepo-aws-sagema-GtRecipeAnnotationConsol-<id>`。

1. 選取其中一個函式，然後在 **Code** (程式碼) 區段新增您的自訂邏輯。

1. 在完成變更之後，選取 **Deploy** (部署) 即可進行部署。

# 測試註釋前與註釋後 Lambda 函式
<a name="sms-custom-templates-step3-lambda-test"></a>

您可在 Lambda 主控台測試註釋前與註釋後 Lambda 函式。如您是 Lambda 的新使用者，可透過 AWS Lambda 開發人員指南的主控台利用[建立 Lambda 函式](https://docs.aws.amazon.com/lambda/latest/dg/getting-started-create-function.html#gettingstarted-zip-function)教學課程來了解如何在主控台測試或*調用* Lambda 函式。您可以使用此頁面上的區段，了解如何測試透過 AWS Serverless Application Repository (SAR) 提供的 Ground Truth 註釋前和註釋後範本。

**Topics**
+ [先決條件](#sms-custom-templates-step3-lambda-test-pre)
+ [測試註釋前 Lambda 函式](#sms-custom-templates-step3-lambda-test-pre-annotation)
+ [測試註釋後 Lambda 函式](#sms-custom-templates-step3-lambda-test-post-annotation)

## 先決條件
<a name="sms-custom-templates-step3-lambda-test-pre"></a>

您必須執行下列動作，才能採用本頁所述的測試。
+ 您需要 Lambda 主控台的存取權，且您需要權限以便建立及調用 Lambda 函式。若要了解如何設定這些權限，請參閱[授予建立和選取 AWS Lambda 函數的許可](sms-custom-templates-step3-lambda-permissions.md#sms-custom-templates-step3-postlambda-create-perms)。
+ 如您尚未部署 Ground Truth SAR 配方，請利用[使用 Ground Truth 範本建立 Lambda 函式](sms-custom-templates-step3-lambda-create.md)的程序來執行此操作。
+ 若要測試註釋後 Lambda 函式，您必須在 Amazon S3 擁有包含範例註釋資料的資料檔案。對於簡單測試，您可將下列程式碼複製並貼到檔案，然後另存新檔為 `sample-annotations.json` 並[將其上傳到 Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)。請注意此檔案的 S3 URI，您需要此資訊才能設定註釋後 Lambda 測試。

  ```
  [{"datasetObjectId":"0","dataObject":{"content":"To train a machine learning model, you need a large, high-quality, labeled dataset. Ground Truth helps you build high-quality training datasets for your machine learning models."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":8,\"label\":\"verb\",\"startOffset\":3},{\"endOffset\":27,\"label\":\"adjective\",\"startOffset\":11},{\"endOffset\":33,\"label\":\"object\",\"startOffset\":28},{\"endOffset\":51,\"label\":\"adjective\",\"startOffset\":46},{\"endOffset\":65,\"label\":\"adjective\",\"startOffset\":53},{\"endOffset\":74,\"label\":\"adjective\",\"startOffset\":67},{\"endOffset\":82,\"label\":\"adjective\",\"startOffset\":75},{\"endOffset\":102,\"label\":\"verb\",\"startOffset\":97},{\"endOffset\":112,\"label\":\"verb\",\"startOffset\":107},{\"endOffset\":125,\"label\":\"adjective\",\"startOffset\":113},{\"endOffset\":134,\"label\":\"adjective\",\"startOffset\":126},{\"endOffset\":143,\"label\":\"object\",\"startOffset\":135},{\"endOffset\":169,\"label\":\"adjective\",\"startOffset\":153},{\"endOffset\":176,\"label\":\"object\",\"startOffset\":170}]}}"}}]},{"datasetObjectId":"1","dataObject":{"content":"Sift 3 cups of flour into the bowl."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":4,\"label\":\"verb\",\"startOffset\":0},{\"endOffset\":6,\"label\":\"number\",\"startOffset\":5},{\"endOffset\":20,\"label\":\"object\",\"startOffset\":15},{\"endOffset\":34,\"label\":\"object\",\"startOffset\":30}]}}"}}]},{"datasetObjectId":"2","dataObject":{"content":"Jen purchased 10 shares of the stock on Janurary 1st, 2020."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":3,\"label\":\"person\",\"startOffset\":0},{\"endOffset\":13,\"label\":\"verb\",\"startOffset\":4},{\"endOffset\":16,\"label\":\"number\",\"startOffset\":14},{\"endOffset\":58,\"label\":\"date\",\"startOffset\":40}]}}"}}]},{"datasetObjectId":"3","dataObject":{"content":"The narrative was interesting, however the character development was weak."},"annotations":[{"workerId":"private.us-west-2.0123456789","annotationData":{"content":"{\"crowd-entity-annotation\":{\"entities\":[{\"endOffset\":29,\"label\":\"adjective\",\"startOffset\":18},{\"endOffset\":73,\"label\":\"adjective\",\"startOffset\":69}]}}"}}]}]
  ```
+ 您必須遵循[授予註釋後 Lambda 權限以便存取註釋](sms-custom-templates-step3-lambda-permissions.md#sms-custom-templates-step3-postlambda-perms)的指示，授予註釋後 Lambda 函式的執行角色權限，以便擔任您用來建立標籤工作的 SageMaker AI 執行角色。註釋後 Lambda 函式使用 SageMaker AI 執行角色來存取 S3 的註釋資料檔案 `sample-annotations.json`。



## 測試註釋前 Lambda 函式
<a name="sms-custom-templates-step3-lambda-test-pre-annotation"></a>

使用下列程序來測試部署 Ground Truth AWS Serverless Application Repository (SAR) 配方時建立的註釋前 Lambda 函數。

**測試 Ground Truth SAR 配方註釋前 Lambda 函式**

1. 開啟 Lambda 主控台的 [**Functions** (函式) 頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 從 Ground Truth SAR 配方選取部署的註釋前函式。此函式名稱類似 `serverlessrepo-aws-sagema-GtRecipePreHumanTaskFunc-<id>`。

1. 在 **Code source** (程式碼來源) 區段，選取 **Test** (測試) 旁邊的箭頭。

1. 選取 **Configure test event** (設定測試事件)。

1. 保持選取 **Create new test event** (建立新測試事件) 選項。

1. 從 **Event template** (事件範本)，選取 **SageMaker Ground Truth PreHumanTask**。

1. 為測試指定 **Event name** (事件名稱)。

1. 選取**建立**。

1. 再次選取 **Test** (測試) 旁邊的箭頭，您應會看到已選取您建立的測試 (由事件名稱以點表示)。如未選取，請選取。

1. 選取 **Test** (測試)，即可執行測試。

在執行測試之後，您可看到 **Execution results** (執行結果)。您應會在 **Function logs** (函式日誌) 看到類似下列回應：

```
START RequestId: cd117d38-8365-4e1a-bffb-0dcd631a878f Version: $LATEST
Received event: {
  "version": "2018-10-16",
  "labelingJobArn": "arn:aws:sagemaker:us-east-2:123456789012:labeling-job/example-job",
  "dataObject": {
    "source-ref": "s3://sagemakerexample/object_to_annotate.jpg"
  }
}
{'taskInput': {'taskObject': 's3://sagemakerexample/object_to_annotate.jpg'}, 'isHumanAnnotationRequired': 'true'}
END RequestId: cd117d38-8365-4e1a-bffb-0dcd631a878f
REPORT RequestId: cd117d38-8365-4e1a-bffb-0dcd631a878f	Duration: 0.42 ms	Billed Duration: 1 ms	Memory Size: 128 MB	Max Memory Used: 43 MB
```

我們可在此回應看到 Lambda 函式的輸出符合所需的註釋前回應語法：

```
{'taskInput': {'taskObject': 's3://sagemakerexample/object_to_annotate.jpg'}, 'isHumanAnnotationRequired': 'true'}
```

## 測試註釋後 Lambda 函式
<a name="sms-custom-templates-step3-lambda-test-post-annotation"></a>

使用下列程序來測試部署 Ground Truth AWS Serverless Application Repository (SAR) 配方時建立的註釋後 Lambda 函數。

**測試 Ground Truth SAR 配方註釋後 Lambda**

1. 開啟 Lambda 主控台的 [**Functions** (函式) 頁面](https://console.aws.amazon.com/lambda/home#/functions)。

1. 從 Ground Truth SAR 配方選取部署的註釋後函式。此函式名稱類似 `serverlessrepo-aws-sagema-GtRecipeAnnotationConsol-<id>`。

1. 在 **Code source** (程式碼來源) 區段，選取 **Test** (測試) 旁邊的箭頭。

1. 選取 **Configure test event** (設定測試事件)。

1. 保持選取 **Create new test event** (建立新測試事件) 選項。

1. 在 **Event template** (事件範本)，選取 **SageMaker Ground Truth AnnotationConsolidation**。

1. 為測試指定 **Event name** (事件名稱)。

1. 修改提供的範本程式碼，如下所示：
   + 將 `roleArn` 的 Amazon Resource Name (ARN) 取代為用於建立標籤工作的 SageMaker AI 執行角色 ARN。
   + 將 `s3Uri` 的 S3 URI 取代為您新增至 Amazon S3 `sample-annotations.json` 檔案的 URI。

   在進行這些修改之後，測試會看起來類似以下內容：

   ```
   {
     "version": "2018-10-16",
     "labelingJobArn": "arn:aws:sagemaker:us-east-2:123456789012:labeling-job/example-job",
     "labelAttributeName": "example-attribute",
     "roleArn": "arn:aws:iam::222222222222:role/sm-execution-role",
     "payload": {
       "s3Uri": "s3://your-bucket/sample-annotations.json"
     }
   }
   ```

1. 選取**建立**。

1. 再次選取 **Test** (測試) 旁邊的箭頭，您應會看到已選取您建立的測試 (由事件名稱以點表示)。如未選取，請選取。

1. 選擇 **Test** (測試)，即可執行測試。

在執行測試之後，您應會在 **Function Logs** (函式日誌) 看見 `-- Consolidated Output --` 區段，其中包含 `sample-annotations.json` 的所有註釋清單。