AWS Lambda调用SageMaker推理端点报错:instances列表含义及输入格式问题
SageMaker端点Lambda调用400报错排查与配置指南
报错中instances列表的含义
这个字段是SageMaker托管推理端点默认遵循的JSON请求规范里的顶层必填字段,是承载所有待推理样本的数组:
- 不管是单条还是多条推理请求,所有待预测数据都要放在这个数组下,数组的每个元素对应一条待处理的样本
- 你现在看到这个报错,核心原因是Notebook里的
model.predict方法和Lambda里直接调用boto3的invoke_endpoint逻辑不一样:SageMaker Python SDK的predict方法内置了自动序列化、格式包装逻辑,你传入{"input1": "hello world"}时,SDK在底层自动帮你把数据包装成端点服务能识别的结构再发送;而Lambda里用boto3发请求是裸调用,不会做这层自动转换,你直接把裸JSON传给端点,端点的默认推理处理逻辑会把整个请求体识别为instances列表的第0个元素,解析时找不到模型期望的输入结构就抛错。
Lambda侧正确的请求配置
1. 必选参数不要遗漏
调用invoke_endpoint时必须显式指定ContentType为application/json,否则端点会按默认的二进制格式解析请求,必然报错。
2. 正确的请求体格式
按SageMaker默认JSON推理规范包装你的输入,单条请求的结构如下:
{ "instances": [ {"input1": "hello world"} ] }
3. 可直接运行的Lambda调用示例
import boto3 import json # 初始化SageMaker Runtime客户端 sagemaker_runtime = boto3.client("sagemaker-runtime") ENDPOINT_NAME = "你配置好的端点名称" def lambda_handler(event, context): # 构造符合规范的请求体 request_body = { "instances": [ {"input1": "hello world"} ] } # 调用端点 resp = sagemaker_runtime.invoke_endpoint( EndpointName=ENDPOINT_NAME, ContentType="application/json", Accept="application/json", Body=json.dumps(request_body) ) # 解析返回结果 predict_result = json.loads(resp["Body"].read().decode("utf-8")) return { "statusCode": 200, "body": json.dumps(predict_result) }
4. 格式仍然不对时的排查方法
如果按上面的格式配置后还是报相同错误,直接在Notebook里执行以下代码,查看SDK底层实际发送的请求结构,照着这个结构在Lambda里构造payload即可,不需要猜格式:
# 打印当前predictor使用的序列化器 print(predictor.serializer) # 模拟序列化过程,输出SDK实际发送的原始字节内容 serialized_data = predictor.serializer.serialize({"input1": "hello world"}) print(serialized_data.decode("utf-8"))
如果你的模型部署时用了自定义input_fn推理脚本,直接对应input_fn里的解析逻辑构造请求体即可,不需要强行套instances结构。
内容的提问来源于stack exchange,提问作者solitaria
相关产品推荐
相关产品推荐

