AWSSageMaker-如何加载经过训练的sklearn模型以用于推理?

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

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

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

这就是文档对论点的描述model_dir

SageMaker 将注入通过 save 保存的模型文件和子目录的挂载目录。您的模型函数应该返回一个可用于模型服务的模型对象。

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

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

编辑 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 中的训练、保存和加载模型以及部署模型到 SageMaker Endpoint 之间进行明确区分。

SageMaker 模型

您需要创建AWS::SageMaker::Model资源,该资源引用您已训练的“模型”。AWS::SageMaker::Model 位于 CloudFormation 文档中,但仅用于说明您需要哪些 AWS 资源。

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

Docker 镜像

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

建立形象并不容易。因此,AWS 提供了称为AWS Deep Learning Containers 的预构建映像,可用映像位于Github 中。

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

用于框架的 SageMaker Python SDK

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

模型.tar.gz

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

|- 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 存储桶和对象。

加载模型并获得推理

请参阅创建 PyTorchModel 对象。当实例化PyTorchModel类,SageMaker自动在指定的版本选择的PyTorch的AWS深度学习集装箱图像framework_version。如果版本的映像不存在,则失败。这在 AWS 中没有记录,但需要注意。然后,SageMaker 使用 S3 模型文件位置和 AWS Deep Learning Container 映像 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 类。

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)

推理代码示例

请参阅流程模型输入、从 PyTorch 模型中获取预测和流程模型输出。在此示例中,预测请求在 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') 

有关的

  • 使用在 Amazon SageMaker 之外训练的模型

笔记

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

  • Thanks for this comprehensive answer. Had it not been for your answer, I would have taken something like two or three more days to figure all this out. Thank you so much @mon

以上是AWSSageMaker-如何加载经过训练的sklearn模型以用于推理?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>