繁体   English   中英

AWS SageMaker - 如何加载经过训练的 sklearn model 以进行推理?

[英]AWS SageMaker - How to load trained sklearn model to serve for inference?

我正在尝试将使用 sklearn 训练的 model 部署到端点,并将其作为 API 进行预测。 我只想使用 sagemaker 来部署和服务器 model 我已经使用joblib序列化,仅此而已。 我读过的每个博客和 sagemaker python 文档都显示 sklearn model 必须在 sagemaker 上进行培训才能部署在 sagemaker 中。

当我浏览 SageMaker 文档时,我了解到 sagemaker 确实允许用户加载存储在 S3 中的序列化 model ,如下所示:

def model_fn(model_dir):
    clf = joblib.load(os.path.join(model_dir, "model.joblib"))
    return clf

这就是文档中关于参数model_dir的说明:

SageMaker 将注入您的 model 文件和子目录(通过 save 保存)已安装的目录。 Your model function should return a model object that can be used for model serving.

这再次意味着必须在 sagemaker 上进行培训。

那么,有没有办法我可以指定序列化 model 的 S3 位置,并让 sagemaker 从 S3 反序列化(或加载)model 并将其用于推理?

编辑1:

我在应用程序的答案中使用了代码,但在尝试从 SageMaker Studio 的笔记本部署时出现以下错误。 我相信 SageMaker 正在尖叫说没有在 SageMaker 上进行培训。

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-6662bbae6010> in <module>
      1 predictor = model.deploy(
      2     initial_instance_count=1,
----> 3     instance_type='ml.m4.xlarge'
      4 )

/opt/conda/lib/python3.7/site-packages/sagemaker/estimator.py in deploy(self, initial_instance_count, instance_type, serializer, deserializer, accelerator_type, endpoint_name, use_compiled_model, wait, model_name, kms_key, data_capture_config, tags, **kwargs)
    770         """
    771         removed_kwargs("update_endpoint", kwargs)
--> 772         self._ensure_latest_training_job()
    773         self._ensure_base_job_name()
    774         default_name = name_from_base(self.base_job_name)

/opt/conda/lib/python3.7/site-packages/sagemaker/estimator.py in _ensure_latest_training_job(self, error_message)
   1128         """
   1129         if self.latest_training_job is None:
-> 1130             raise ValueError(error_message)
   1131 
   1132     delete_endpoint = removed_function("delete_endpoint")

ValueError: Estimator is not associated with a training job

我的代码:

import sagemaker
from sagemaker import get_execution_role
# from sagemaker.pytorch import PyTorchModel
from sagemaker.sklearn import SKLearn
from sagemaker.predictor import RealTimePredictor, json_serializer, json_deserializer

sm_role = sagemaker.get_execution_role()  # IAM role to run SageMaker, access S3 and ECR

model_file = "s3://sagemaker-manual-bucket/sm_model_artifacts/model.tar.gz"   # Must be ".tar.gz" suffix

class AnalysisClass(RealTimePredictor):
    def __init__(self, endpoint_name, sagemaker_session):
        super().__init__(
            endpoint_name,
            sagemaker_session=sagemaker_session,
            serializer=json_serializer,
            deserializer=json_deserializer,   # To be able to use JSON serialization
            content_type='application/json'   # To be able to send JSON as HTTP body
        )

model = SKLearn(model_data=model_file,
                entry_point='inference.py',
                name='rf_try_1',
                role=sm_role,
                source_dir='code',
                framework_version='0.20.0',
                instance_count=1,
                instance_type='ml.m4.xlarge',
                predictor_cls=AnalysisClass)
predictor = model.deploy(initial_instance_count=1,
                         instance_type='ml.m4.xlarge')

是的你可以。 AWS 文档侧重于 SageMaker 中从培训到部署的端到端,给人的印象是必须在 sagemaker 上进行培训。 AWS 文档和示例应明确区分 Estimator 中的训练、保存和加载 model 以及将 model 部署到 SageMaker 端点。

SageMaker Model

您需要创建AWS::SageMaker::Model资源,它指的是您已训练的“模型”等等 AWS::SageMaker::Model 在 CloudFormation 文档中,但它只是说明您需要什么 AWS 资源。

CreateModel API 创建 SageMaker model 资源。 参数指定要使用的 docker 映像、S3 中的 model 位置、要使用的 IAM 角色等。请参阅SageMaker 如何加载您的 Model Artif

Docker 图像

显然,您需要用于训练 model 的框架,例如 ScikitLearn、TensorFlow、PyTorch 等。 您需要具有框架的 docker 图像和 HTTP 前端来响应预测调用。 请参阅SageMaker 推理工具包使用 SageMaker 训练和推理工具包

建立形象并不容易。 因此,AWS 提供了称为AWS 深度学习容器的预构建图像,可用图像位于Github中。

如果那里列出了您的框架和版本,则可以将其用作图像。 否则,您需要自己构建。 请参阅构建 docker 容器以训练/部署我们的分类器

用于框架的 SageMaker Python SDK

使用 API 自己创建 SageMaker Model 很难。 因此,AWS SageMaker Python SDK 提供了用于为多个框架创建 SageMaker 模型的实用程序。 有关可用框架,请参阅框架 如果它不存在,您仍然可以使用sagemaker.model.FrameworkModelModel来加载经过训练的 model。 对于您的情况,请参阅将 Scikit-learn 与 SageMaker Python SDK 一起使用

model.tar.gz

例如,如果您使用 PyTorch 并将 model 保存为 model.pth。 要加载 model 和推理代码以从 model 获取预测,您需要创建 model.tar.gz 文件。 model.tar.gz 内部的结构在Model 目录结构中进行了说明。 如果您使用 Windows,请注意 CRLF 到 LF。 AWS SageMaker 在 *NIX 环境中运行。 请参阅为 model 文件创建目录结构

|- model.pth        # model file is inside / directory.
|- code/            # Code artefacts must be inside /code
  |- inference.py   # Your inference code for the framework
  |- requirements.txt  # only for versions 1.3.1 and higher. Name must be "requirements.txt"

将 tar.gz 文件保存在 S3 中。 确保 IAM 角色可以访问 S3 存储桶和对象。

加载 model 并得到推断

请参阅创建 PyTorchModel object 在实例化 PyTorchModel class 时,SageMaker 会自动为framework_version中指定的版本选择 PyTorch 的 AWS 深度学习容器映像。 如果该版本的图像不存在,则它会失败。 这尚未在 AWS 中记录,但需要注意。 然后,SageMaker 使用 S3 model 文件位置和 AWS 深度学习容器映像 URL 在内部调用 CreateModel API。

import sagemaker
from sagemaker import get_execution_role
from sagemaker.pytorch import PyTorchModel
from sagemaker.predictor import RealTimePredictor, json_serializer, json_deserializer

role = sagemaker.get_execution_role()  # IAM role to run SageMaker, access S3 and ECR
model_file = "s3://YOUR_BUCKET/YOUR_FOLDER/model.tar.gz"   # Must be ".tar.gz" suffix


class AnalysisClass(RealTimePredictor):
    def __init__(self, endpoint_name, sagemaker_session):
        super().__init__(
            endpoint_name,
            sagemaker_session=sagemaker_session,
            serializer=json_serializer,
            deserializer=json_deserializer,   # To be able to use JSON serialization
            content_type='application/json'   # To be able to send JSON as HTTP body
        )

model = PyTorchModel(
    model_data=model_file,
    name='YOUR_MODEL_NAME_WHATEVER',
    role=role,
    entry_point='inference.py',
    source_dir='code',              # Location of the inference code
    framework_version='1.5.0',      # Availble AWS Deep Learning PyTorch container version must be specified
    predictor_cls=AnalysisClass     # To specify the HTTP request body format (application/json)
)

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

test_data = {"body": "YOUR PREDICTION REQUEST"}
prediction = predictor.predict(test_data)

默认情况下,SageMaker 使用 NumPy 作为序列化格式。 为了能够使用 JSON,需要指定序列化器和 content_type。 您可以将它们指定为预测器,而不是使用 RealTimePredictor class。

predictor.serializer=json_serializer
predictor.predict(test_data)

或者

predictor.serializer=None # As the serializer is None, predictor won't serialize the data
serialized_test_data=json.dumps(test_data) 
predictor.predict(serialized_test_data)

推理代码示例

See Process Model Input , Get Predictions from a PyTorch Model and Process Model Output . 在本例中,预测请求在 HTTP 请求正文中作为 JSON 发送。

import os
import sys
import datetime
import json
import torch
import numpy as np

CONTENT_TYPE_JSON = 'application/json'

def model_fn(model_dir):
    # SageMaker automatically load the model.tar.gz from the S3 and 
    # mount the folders inside the docker container. The  'model_dir'
    # points to the root of the extracted tar.gz file.

    model_path = f'{model_dir}/'
    
    # Load the model
    # You can load whatever from the Internet, S3, wherever <--- Answer to your Question
    # NO Need to use the model in tar.gz. You can place a dummy model file.
    ...

    return model


def predict_fn(input_data, model):
    # Do your inference
    ...

def input_fn(serialized_input_data, content_type=CONTENT_TYPE_JSON):
    input_data = json.loads(serialized_input_data)
    return input_data


def output_fn(prediction_output, accept=CONTENT_TYPE_JSON):
    if accept == CONTENT_TYPE_JSON:
        return json.dumps(prediction_output), accept
    raise Exception('Unsupported content type') 

笔记

SageMaker 团队不断更改实施,文档经常过时。 当您确定您确实遵循了文档并且它不起作用时,很可能是过时的文档。 在这种情况下,需要通过 AWS 支持进行澄清,或在 Github 中提出问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM