"errorMessage": "Lambda 调用 SageMaker 端点时参数验证失败

"errorMessage": "Parameter validation failed in Lambda calling SageMaker endpoint

我正在尝试使用 lambda 函数从 AWS Lambda 调用 SageMaker enpoint。

这是从 SageMaker Studio 调用端点的示例 API,按预期工作:

这是我的 Lambda 函数 (inspired from documentation):

import os
import io
import boto3
import json


ENDPOINT_NAME = 'iris-autoscale-6'
runtime= boto3.client('runtime.sagemaker')

def lambda_handler(event, context):
    # print("Received event: " + json.dumps(event, indent=2))
    payload = json.loads(json.dumps(event))
    print(payload)
    
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)
    print(response)
    result = json.loads(response['Body'].read().decode())
    print(result)
    
    return result

我的错误信息:

Test Event Name
ProperTest

Response
{
  "errorMessage": "Parameter validation failed:\nInvalid type for parameter Body, value: {'sepal_length': [5.1, 4.9, 4.7, 4.6, 5], 'sepal_width': [3.5, 3, 3.2, 3.1, 3.6], 'petal_length': [1.4, 1.4, 1.3, 1.5, 1.4], 'petal_width': [0.2, 0.2, 0.2, 0.2, 0.2]}, type: <class 'dict'>, valid types: <class 'bytes'>, <class 'bytearray'>, file-like object",
  "errorType": "ParamValidationError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 17, in lambda_handler\n    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)\n",
    "  File \"/var/runtime/botocore/client.py\", line 386, in _api_call\n    return self._make_api_call(operation_name, kwargs)\n",
    "  File \"/var/runtime/botocore/client.py\", line 678, in _make_api_call\n    api_params, operation_model, context=request_context)\n",
    "  File \"/var/runtime/botocore/client.py\", line 726, in _convert_to_request_dict\n    api_params, operation_model)\n",
    "  File \"/var/runtime/botocore/validate.py\", line 319, in serialize_to_request\n    raise ParamValidationError(report=report.generate_report())\n"
  ]
}

Function Logs
START RequestId: 70278b9f-f75e-4ac9-a827-7ad35d162512 Version: $LATEST
{'sepal_length': [5.1, 4.9, 4.7, 4.6, 5], 'sepal_width': [3.5, 3, 3.2, 3.1, 3.6], 'petal_length': [1.4, 1.4, 1.3, 1.5, 1.4], 'petal_width': [0.2, 0.2, 0.2, 0.2, 0.2]}
[ERROR] ParamValidationError: Parameter validation failed:
Invalid type for parameter Body, value: {'sepal_length': [5.1, 4.9, 4.7, 4.6, 5], 'sepal_width': [3.5, 3, 3.2, 3.1, 3.6], 'petal_length': [1.4, 1.4, 1.3, 1.5, 1.4], 'petal_width': [0.2, 0.2, 0.2, 0.2, 0.2]}, type: <class 'dict'>, valid types: <class 'bytes'>, <class 'bytearray'>, file-like object
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 17, in lambda_handler
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload)
  File "/var/runtime/botocore/client.py", line 386, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/var/runtime/botocore/client.py", line 678, in _make_api_call
    api_params, operation_model, context=request_context)
  File "/var/runtime/botocore/client.py", line 726, in _convert_to_request_dict
    api_params, operation_model)
  File "/var/runtime/botocore/validate.py", line 319, in serialize_to_request
    raise ParamValidationError(report=report.generate_report())
END RequestId: 70278b9f-f75e-4ac9-a827-7ad35d162512
REPORT RequestId: 70278b9f-f75e-4ac9-a827-7ad35d162512  Duration: 26.70 ms  Billed Duration: 27 ms  Memory Size: 128 MB Max Memory Used: 76 MB  Init Duration: 343.10 ms

这是附加到 lambda 函数的策略:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "sagemaker:InvokeEndpoint",
            "Resource": "arn:aws:sagemaker:ap-south-1:<my-account-id>:endpoint/iris-autoscale-6"
        }
    ]
}

问题是您的 payload 格式无效。它应该是以下之一:

<class 'bytes'>, <class 'bytearray'>, file-like object

以下应该可以解决错误(注意:您的代码中可能还有许多其他问题):

    payload = json.dumps(event)
    print(payload)
    
    response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload.encode())