Sagemaker 无服务器验证错误:主体过大

问题描述 投票:0回答:1

我有一个图像分类模型存储在 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

serverless amazon-sagemaker aws-serverless
1个回答
0
投票

您在 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 输入(如 在这个问题中)。

© www.soinside.com 2019 - 2024. All rights reserved.