簡體   English   中英

調用端點錯誤 - AWS Sagemaker 上的 detectron2:ValueError:類型 [application/x-npy] 尚不支持此類型

[英]Invoke endpoint error - detectron2 on AWS Sagemaker: ValueError: Type [application/x-npy] not support this type yet

我一直在按照本指南在 Sagemaker 上實施 Detectron2 model。 一切看起來都不錯,無論是在訓練方面還是在批量轉換方面。

但是,我嘗試稍微調整一下代碼以創建一個可以通過發送有效負載來調用的端點,但我遇到了一些麻煩。

本筆記本的最后,創建 SageMaker model object 后:

model = PyTorchModel(
    name="d2-sku110k-model",
    model_data=training_job_artifact,
    role=role,
    sagemaker_session=sm_session,
    entry_point="predict_sku110k.py",
    source_dir="container_serving",
    image_uri=serve_image_uri,
    framework_version="1.6.0",
    code_location=f"s3://{bucket}/{prefix_code}",
)

我添加了以下代碼:

predictor = model.deploy(initial_instance_count=1, instance_type='ml.m5.xlarge')

我可以看到 model 已成功部署。

但是,當我嘗試預測圖像時:

predictor.predict(input)

我收到以下錯誤:

ModelError:調用 InvokeEndpoint 操作時發生錯誤(ModelError):從主服務器收到服務器錯誤(500),消息為“Type [application/x-npy] 尚不支持此類型 Traceback(最近一次調用):文件”/opt /conda/lib/python3.6/site-packages/sagemaker_inference/transformer.py”,第 126 行,在 transform result = self._transform_fn(self._model, input_data, content_type, accept) 文件“/opt/conda/lib/ python3.6/site-packages/sagemaker_inference/transformer.py”,第 215 行,在 _default_transform_fn data = self._input_fn(input_data, content_type) 文件“/opt/ml/model/code/predict_sku110k.py”,第 98 行,在input_fn raise ValueError(err_msg) ValueError: Type [application/x-npy] 還不支持這種類型

我嘗試了一堆不同的輸入類型:圖像字節編碼(使用 cv2.imencode('.jpg', cv_img)[1].tobytes() 創建),numpy 數組,BytesIO object(使用 io 模塊創建) ,形式為 {'input': image} 的字典,其中 image 是之前的任何一個(這是因為我之前創建的 tensorflow 端點使用了這種格式)。

因為我認為這可能是相關的,所以我還在此處復制粘貼用作入口點的推理腳本

"""Code used for sagemaker batch transform jobs"""
from typing import BinaryIO, Mapping
import json
import logging
import sys
from pathlib import Path

import numpy as np
import cv2
import torch

from detectron2.engine import DefaultPredictor
from detectron2.config import CfgNode

##############
# Macros
##############

LOGGER = logging.Logger("InferenceScript", level=logging.INFO)
HANDLER = logging.StreamHandler(sys.stdout)
HANDLER.setFormatter(logging.Formatter("%(levelname)s | %(name)s | %(message)s"))
LOGGER.addHandler(HANDLER)

##########
# Deploy
##########
def _load_from_bytearray(request_body: BinaryIO) -> np.ndarray:
    npimg = np.frombuffer(request_body, np.uint8)
    return cv2.imdecode(npimg, cv2.IMREAD_COLOR)


def model_fn(model_dir: str) -> DefaultPredictor:
    r"""Load trained model

    Parameters
    ----------
    model_dir : str
        S3 location of the model directory

    Returns
    -------
    DefaultPredictor
        PyTorch model created by using Detectron2 API
    """
    path_cfg, path_model = None, None
    for p_file in Path(model_dir).iterdir():
        if p_file.suffix == ".json":
            path_cfg = p_file
        if p_file.suffix == ".pth":
            path_model = p_file

    LOGGER.info(f"Using configuration specified in {path_cfg}")
    LOGGER.info(f"Using model saved at {path_model}")

    if path_model is None:
        err_msg = "Missing model PTH file"
        LOGGER.error(err_msg)
        raise RuntimeError(err_msg)
    if path_cfg is None:
        err_msg = "Missing configuration JSON file"
        LOGGER.error(err_msg)
        raise RuntimeError(err_msg)

    with open(str(path_cfg)) as fid:
        cfg = CfgNode(json.load(fid))

    cfg.MODEL.WEIGHTS = str(path_model)
    cfg.MODEL.DEVICE = "cuda" if torch.cuda.is_available() else "cpu"

    return DefaultPredictor(cfg)


def input_fn(request_body: BinaryIO, request_content_type: str) -> np.ndarray:
    r"""Parse input data

    Parameters
    ----------
    request_body : BinaryIO
        encoded input image
    request_content_type : str
        type of content

    Returns
    -------
    np.ndarray
        input image

    Raises
    ------
    ValueError
        ValueError if the content type is not `application/x-image`
    """
    if request_content_type == "application/x-image":
        np_image = _load_from_bytearray(request_body)
    else:
        err_msg = f"Type [{request_content_type}] not support this type yet"
        LOGGER.error(err_msg)
        raise ValueError(err_msg)
    return np_image


def predict_fn(input_object: np.ndarray, predictor: DefaultPredictor) -> Mapping:
    r"""Run Detectron2 prediction

    Parameters
    ----------
    input_object : np.ndarray
        input image
    predictor : DefaultPredictor
        Detectron2 default predictor (see Detectron2 documentation for details)

    Returns
    -------
    Mapping
        a dictionary that contains: the image shape (`image_height`, `image_width`), the predicted
        bounding boxes in format x1y1x2y2 (`pred_boxes`), the confidence scores (`scores`) and the
        labels associated with the bounding boxes (`pred_boxes`)
    """
    LOGGER.info(f"Prediction on image of shape {input_object.shape}")
    outputs = predictor(input_object)
    fmt_out = {
        "image_height": input_object.shape[0],
        "image_width": input_object.shape[1],
        "pred_boxes": outputs["instances"].pred_boxes.tensor.tolist(),
        "scores": outputs["instances"].scores.tolist(),
        "pred_classes": outputs["instances"].pred_classes.tolist(),
    }
    LOGGER.info(f"Number of detected boxes: {len(fmt_out['pred_boxes'])}")
    return fmt_out


# pylint: disable=unused-argument
def output_fn(predictions, response_content_type):
    r"""Serialize the prediction result into the desired response content type"""
    return json.dumps(predictions)

誰能指出調用 model 的正確格式是什么(或如何調整代碼以使用端點)? 我正在考慮將 request_content_type 更改為“application/json”,但我不確定它會有多大幫助。

編輯:我嘗試了一個受此SO 線程啟發的解決方案,但它對我的情況不起作用。

你問這個問題已經有一段時間了,所以我希望你已經找到了解決方案,但是對於將來看到這個的人......

該錯誤似乎是因為您使用默認的 content_type 發送請求(沒有在請求中指定內容類型,也沒有指定序列化程序),但是您的代碼是以僅響應內容類型附帶的請求的方式制作的“應用程序/x圖像”

默認的內容類型是“application/json”

您在這里有 2 個選項,您可以修改代碼以能夠處理“application/json”內容類型,或者在調用端點時添加具有正確值的內容類型 header。 您可以通過如下更改預測方法來做到這一點:

代替:

predictor.predict(input)

嘗試:

predictor.predict(input, initial_args={"ContentType":"application/x-image"})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM