Python中如何减小发送至SageMaker端点的POST请求数据大小
SageMaker端点numpy数组推理请求413报错解决方案
核心原因是JSON序列化numpy数组的效率极低:数组内的数值会被转为字符串存储,叠加JSON分隔符的额外开销,体积通常会膨胀10~20倍,0.5MB的数组序列化后达到10MB属于正常现象,超过SageMaker单请求5MB限制就会触发413错误。直接改用二进制传输即可解决问题,操作步骤如下:
1. 客户端请求数据准备
使用requests.post发送二进制流,无需JSON序列化,有两种常用实现方案:
- 方案A(推荐):用npy格式将数组数据+形状、类型等元信息统一打包,无需额外传递参数
示例代码:
import requests import numpy as np import io # 你的预处理后的numpy数组 processed_arr = 预处理得到的ndarray对象 # 打包为npy格式二进制流 buf = io.BytesIO() np.save(buf, processed_arr) buf.seek(0) binary_payload = buf.read() # 发送请求 endpoint_url = "你的SageMaker端点访问地址" response = requests.post( url=endpoint_url, data=binary_payload, headers={"Content-Type": "application/octet-stream"} )
- 方案B:直接序列化数组数据,通过请求头传递元信息,适合需要极致压缩的场景
示例代码:
import requests import numpy as np processed_arr = 预处理得到的ndarray对象 binary_payload = processed_arr.tobytes() endpoint_url = "你的SageMaker端点访问地址" response = requests.post( url=endpoint_url, data=binary_payload, headers={ "Content-Type": "application/octet-stream", "X-Array-Shape": ",".join(map(str, processed_arr.shape)), "X-Array-Dtype": str(processed_arr.dtype) } )
2. 服务端输入解析逻辑修改
对应客户端的方案调整SageMaker端点的输入处理逻辑即可,复用你原有适配ndarray的推理流程:
- 对应方案A的解析代码:
import numpy as np from io import BytesIO def input_handler(data, context): # 读取请求体二进制数据 raw_data = data.read() # 直接加载得到预处理后的ndarray input_arr = np.load(BytesIO(raw_data)) # 后续走原有推理逻辑即可 return input_arr
- 对应方案B的解析代码:
import numpy as np def input_handler(data, context): raw_data = data.read() # 从请求头读取数组元信息 req_headers = context.request_header arr_shape = tuple(map(int, req_headers["X-Array-Shape"].split(","))) arr_dtype = req_headers["X-Array-Dtype"] # 还原为ndarray input_arr = np.frombuffer(raw_data, dtype=arr_dtype).reshape(arr_shape) return input_arr
可选优化
如果后续需要传输更大体积的数组,可在客户端对二进制流做gzip压缩,服务端对应增加解压逻辑即可,numpy数组的压缩率通常可以达到70%以上,进一步降低传输体积。
内容的提问来源于stack exchange,提问作者Jacques Thibodeau
相关产品推荐
相关产品推荐

