AWS Lambda调用TensorFlow SageMaker端点请求体格式验证错误排查
问题:SageMaker TensorFlow端点请求体格式验证错误
在AWS上训练并部署TensorFlow模型为SageMaker推理端点后,通过Lambda+API Gateway触发8×8矩阵推理时,始终出现请求体格式验证错误,预期输出单个数值。
错误信息
{"errorMessage": "Parameter validation failed:\nInvalid type for parameter Body, value: {'instances': [[[0.30050477, 0.31565664, 0.03535339, 0.25252531, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.26515138, 0.32828271, 0.11616141, 0.25757545, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.29292932, 0.45707068, 0.20959599, 0.44696943, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.4242426, 0.44949475, 0.05808071, 0.06565664, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.09595941, 0.44696943, 0.0, 0.36868672, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.33838396, 0.89898997, 0.3055554, 0.85101003, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.84090927, 0.89646466, 0.77272732, 0.85858596, 0.51226546, 0.62584169, 0.66940236, 0.0], [0.85606065, 0.85606065, 0.76262607, 0.7878787, 0.5910121, 0.62584169, 0.66940236, 0.0]]]}, type: <class 'dict'>, valid types: <class 'bytes'>, <class 'bytearray'>, file-like object", "errorType": "ParamValidationError", "requestId": "a1d05ff9-86fb-4a30-9dcb-2651bb001b6c", "stackTrace": [" File \"/var/task/lambda_function.py\", line 19, in lambda_handler\n response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME,\n", " File \"/var/runtime/botocore/client.py\", line 391, in _api_call\n return self._make_api_call(operation_name, kwargs)\n", " File \"/var/runtime/botocore/client.py\", line 691, in _make_api_call\n request_dict = self._convert_to_request_dict(\n", " File \"/var/runtime/botocore/client.py\", line 739, in _convert_to_request_dict\n request_dict = self._serializer.serialize_to_request(\n", " File \"/var/runtime/botocore/validate.py\", line 360, in serialize_to_request\n raise ParamValidationError(report=report.generate_report())\n"]}
测试用请求体
{"instances": [[[0.30050477, 0.31565664, 0.03535339, 0.25252531, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.26515138, 0.32828271, 0.11616141, 0.25757545, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.29292932, 0.45707068, 0.20959599, 0.44696943, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.4242426, 0.44949475, 0.05808071, 0.06565664, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.09595941, 0.44696943, 0.0, 0.36868672, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.33838396, 0.89898997, 0.3055554, 0.85101003, 0.37373726, 0.62584169, 0.66940236, 0.0], [0.84090927, 0.89646466, 0.77272732, 0.85858596, 0.51226546, 0.62584169, 0.66940236, 0.0], [0.85606065, 0.85606065, 0.76262607, 0.7878787, 0.5910121, 0.62584169, 0.66940236, 0.0]]]}
原Lambda函数代码
import os import json import boto3 ENDPOINT_NAME = os.environ['ENDPOINT_NAME'] runtime = boto3.client('runtime.sagemaker') def lambda_handler(event, context): data = json.loads(json.dumps(event)) payload = data['instances'] response = runtime.invoke_endpoint(EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=data) result = json.loads(response['Body'].read().decode()) return result
成功的Notebook调用示例
在SageMaker Jupyter Notebook中使用以下代码可成功触发端点,得到预测结果{'predictions': [[0.875023425]]}:
import numpy as np import json import boto3 runtime = boto3.client('runtime.sagemaker') payload = {'instances': np.array([[[0.30050477, 0.31565664, 0.03535339, 0.25252531, 0.37373726, 0.62584169, 0.66940236, 0. ], [0.26515138, 0.32828271, 0.11616141, 0.25757545, 0.37373726, 0.62584169, 0.66940236, 0. ], [0.29292932, 0.45707068, 0.20959599, 0.44696943, 0.37373726, 0.62584169, 0.66940236, 0. ], [0.4242426 , 0.44949475, 0.05808071, 0.06565664, 0.37373726, 0.62584169, 0.66940236, 0. ], [0.09595941, 0.44696943, 0. , 0.36868672, 0.37373726, 0.62584169, 0.66940236, 0. ], [0.33838396, 0.89898997, 0.3055554 , 0.85101003, 0.37373726, 0.62584169, 0.66940236, 0. ], [0.84090927, 0.89646466, 0.77272732, 0.85858596, 0.51226546, 0.62584169, 0.66940236, 0. ], [0.85606065, 0.85606065, 0.76262607, 0.7878787 , 0.5910121 , 0.62584169, 0.66940236, 0. ]]])} response = runtime.invoke_endpoint(EndpointName='your-endpoint-name', ContentType='application/json', Body=json.dumps(payload)) result = json.loads(response['Body'].read().decode()) print(result)
解决方案
1. 修正Lambda函数的核心错误
错误根源是invoke_endpoint的Body参数要求传入bytes/bytearray/file-like对象,不能直接传Python字典。同时需处理API Gateway的请求结构:
- 如果API Gateway使用Lambda代理集成,请求体在
event['body']中,需先解析为字典 - 最终要把请求体序列化为JSON字符串再转成bytes
修正后的Lambda代码:
import os import json import boto3 ENDPOINT_NAME = os.environ['ENDPOINT_NAME'] runtime = boto3.client('runtime.sagemaker') def lambda_handler(event, context): # 处理API Gateway代理集成的请求体 if 'body' in event: data = json.loads(event['body']) else: # 本地测试时直接使用event作为请求体 data = event # 将字典序列化为JSON字节流 payload_bytes = json.dumps(data).encode('utf-8') response = runtime.invoke_endpoint( EndpointName=ENDPOINT_NAME, ContentType='application/json', Body=payload_bytes ) result = json.loads(response['Body'].read().decode()) # 返回符合API Gateway代理集成要求的格式 return { 'statusCode': 200, 'body': json.dumps(result) }
2. API Gateway请求格式要求
发送请求时需满足:
- 请求方法:POST
- 请求头:
Content-Type: application/json - 请求体:使用测试用的JSON结构(嵌套列表,无需numpy数组),和Notebook中的
instances结构一致
3. 验证关键点
- 确保Lambda执行角色拥有
sagemaker:InvokeEndpoint权限 - 确认SageMaker端点状态为
InService - 测试时可先在Lambda控制台直接传入测试用JSON(无需
body包装),验证端点调用成功后再通过API Gateway测试
内容的提问来源于stack exchange,提问作者Philippe
相关产品推荐
相关产品推荐

