我有一个图像分类模型存储在 s3 位置。 如果我将模型部署为实时推理,那么我就能够预测任何图像大小,但是,如果我将模型部署为无服务器,那么我无法预测大于 400x400 大小的图像。 出现以下错误: ValidationError:调用 InvokeEndpoint 操作时发生错误 (ValidationError):请求 {request-id} 的正文过大。
重现
将模型部署为无服务器:
from sagemaker.tensorflow import TensorFlowModel
from sagemaker import get_execution_role
from sagemaker import Session
import boto3
from sagemaker.serverless import ServerlessInferenceConfig
print('starting ...')
model_data = "s3://datascience--sagemaker/model_repository/Reimbursement Flow/blur_classifier/model.tar.gz"
role = get_execution_role()
sess = Session()
bucket = sess.default_bucket()
region = boto3.Session().region_name
tf_framework_version = '2.0.0'
sm_model = TensorFlowModel(model_data = model_data,
framework_version = tf_framework_version,
role=role)
predictor = sm_model.deploy(
endpoint_name = 'blur-classifier-serverless',
serverless_inference_config = ServerlessInferenceConfig(
memory_size_in_mb= 2048,
max_concurrency= 1,
)
)
预测为:
from PIL import Image
import numpy as np
import boto3
runtime = boto3.client("sagemaker-runtime")
import json
img_file="doc_classifier_images/012_0205.jpg"
img_file="0ed2d3e1-fe50-4026-b3bf-9aef535f48cc.jpg"
img = Image.open(img_file)
size = 600
img = img.resize((size, size))
img = np.array(img)
img = img.reshape((1, size, size, 3))
img = img/255.
img = np.around(img, decimals=3)
payload = json.dumps(np.asarray(img).astype(float).tolist())
model_name = "blur-classifier-serverless"
content_type = "application/json"
response = runtime.invoke_endpoint( EndpointName=model_name, ContentType=content_type, Body=payload)
pred=json.load(response['Body'])
预期行为
应该做出预测。 如果我保留
size = 400
那么它工作正常。
或者,如果我将模型部署为实时推理,那么它对于 400 和 600 尺寸的图像都可以正常工作。
其他背景
将模型部署为实时模型的部署脚本:
from sagemaker.tensorflow import TensorFlowModel
from sagemaker import get_execution_role
from sagemaker import Session
print('starting ...')
model_data = "s3://datascience--sagemaker/model_repository/Reimbursement Flow/blur_classifier/model.tar.gz"
instance_type = "ml.m4.xlarge"
role = get_execution_role()
sess = Session()
bucket = sess.default_bucket()
instance_type = 'ml.m4.xlarge'
tf_framework_version = '2.0.0'
temp_endpoint_name = "temp"
sm_model = TensorFlowModel(model_data = model_data,
framework_version = tf_framework_version,
role=role)
# Now to deploy the model
tf_predictor = sm_model.deploy(endpoint_name="blurclassifier-server",
initial_instance_count=1,
instance_type=instance_type,
)
更新:
大小超过 6MB 主要是由于转换为 numpy 数组和其他相关操作。
这是对象大小的快速视图:
size = 600
img = img.resize((size, size))
print('2', sys.getsizeof(img))
img = np.array(img)
print('3', sys.getsizeof(img))
img = img.reshape((1, size, size, 3))
print('4', sys.getsizeof(img))
img = img / 255.0
print('5', sys.getsizeof(img))
img = np.around(img, decimals=3)
print('6', sys.getsizeof(img))
payload = json.dumps(img.tolist())
byte_ = payload.encode("utf-8")
size_in_bytes = len(byte_)
print('7', size_in_bytes)
输出:
1 48
2 48
3 1080144
4 160
5 8640160
6 8640160
如何在执行这些操作时保持最小大小并在 sagemaker 无服务器模型中进行预测? 7 8136202
您在 AWS SageMaker 无服务器推理中遇到的问题可能与负载大小限制有关。与实时端点相比,无服务器端点对有效负载大小有更严格的限制,这就是为什么较大的图像尺寸会因负载过大而导致
ValidationError
。
为了进行测试,您可能会考虑降低图像的分辨率。这可能会影响模型的准确性,但这是满足有效负载大小限制的权衡。
不要使用 numpy 数组,而是考虑使用尺寸更高效的图像格式(例如 JPEG)作为有效负载。
简化或优化图像处理管道以减少数据大小。并确保您使用的是最节省大小的数据类型。例如,如果精度允许,使用 float32 而不是 float64。
如果可行,您可以在发送图像数据之前对其进行压缩,并在模型的预处理步骤中对其进行解压缩。
您的预测脚本将是:
from PIL import Image
import boto3
import io
import base64
img_file = "0ed2d3e1-fe50-4026-b3bf-9aef535f48cc.jpg"
size = 400 # Reduced size
quality = 85 # JPEG quality
# Open, resize and convert to JPEG
img = Image.open(img_file)
img = img.resize((size, size))
buffer = io.BytesIO()
img.save(buffer, format="JPEG", quality=quality)
jpeg_encoded = base64.b64encode(buffer.getvalue()).decode() # Base64 encode
# Prepare payload
payload = json.dumps({"instances": [{"b64": jpeg_encoded}]})
runtime = boto3.client("sagemaker-runtime")
model_name = "blur-classifier-serverless"
content_type = "application/json"
# Invoke endpoint
response = runtime.invoke_endpoint(EndpointName=model_name, ContentType=content_type, Body=payload)
pred = json.load(response['Body'])
此处,图像大小调整为较小尺寸 (400x400)。然后将其编码为具有质量设置的 JPEG,从而显着减小有效负载大小。 JPEG 数据采用 base64 编码以兼容 JSON。
有效负载以 SageMaker 模型可以解码和处理的格式发送。
确保您的 SageMaker 模型的预处理步骤可以处理 Base64 编码的 JPEG 输入(如 在这个问题中)。