参考

案例部署参考:
https://blog.csdn.net/qq_15821487/article/details/122684773?spm=1001.2014.3001.5502
https://blog.csdn.net/u011984148/article/details/108459545
handler编写参考文件在这里插入图片描述

必须要求


You can create custom handler by having class with any name, but it must have an `initialize` and a `handle` method.

并且,参数和示例一样,不能缺少,哪怕那个参数不用,另外handle的输入和输出必须是list,并且list的元素个数需要一致

示例

# custom handler file

# model_handler.py

"""
ModelHandler defines a custom model handler.
"""

from ts.torch_handler.base_handler import BaseHandler

class ModelHandler(BaseHandler):
    """
    A custom model handler implementation.
    """

    def __init__(self):
        self._context = None
        self.initialized = False
        self.explain = False
        self.target = 0

    def initialize(self, context):
        """
        Initialize model. This will be called during model loading time
        :param context: Initial context contains model server system properties.
        :return:
        """
        self._context = context
        self.initialized = True
        #  load the model, refer 'custom handler class' above for details

    def preprocess(self, data):
        """
        Transform raw input into model input data.
        :param batch: list of raw requests, should match batch size
        :return: list of preprocessed model input data
        """
        # Take the input data and make it inference ready
        preprocessed_data = data[0].get("data")
        if preprocessed_data is None:
            preprocessed_data = data[0].get("body")

        return preprocessed_data


    def inference(self, model_input):
        """
        Internal inference methods
        :param model_input: transformed model input data
        :return: list of inference output in NDArray
        """
        # Do some inference call to engine here and return output
        model_output = self.model.forward(model_input)
        return model_output

    def postprocess(self, inference_output):
        """
        Return inference result.
        :param inference_output: list of inference output
        :return: list of predict results
        """
        # Take output from network and post-process to desired format
        postprocess_output = inference_output
        return postprocess_output

    def handle(self, data, context):
        """
        Invoke by TorchServe for prediction request.
        Do pre-processing of data, prediction using model and postprocessing of prediciton output
        :param data: Input data for prediction
        :param context: Initial context contains model server system properties.
        :return: prediction output
        """
        model_input = self.preprocess(data)
        model_output = self.inference(model_input)
        return self.postprocess(model_output)

生成打包的部署文件

在–extra-files中,你需要将路径传递给你的handlers正在使用的所有文件。

pip install torch-model-archiver

模型打包(torch-model-archiver)
我们需要两个文件和一个handler.py,分别是:

1,模型(.pt,.bin的torch模型参数文件)
2,需要读取的一些配置或者函数文件
3,handler.py
我们具体讲handler.py,handler主要是让input进来后,通过一系列操作得到output(api返回的结果),所以他属于我们主要要修改的内容,而模型和外部配置也是通过handler接收的。
handler主要有以下几个方法:

initialize:初始参数定义
preprocess:数据处理
inference:正向传播
postprocess:预测呈现处理
handle:从input:data依次调用preprocess>inference>postprocess>output(可以理解为定义模型nn.Module的forward)

dockerfile文件如下:

当前镜像的目录默认就在model-server/,直接把安装文件拷贝过来即可,保证和默认的一致,以便默认的日志文件可以保存在默认位置

FROM pytorch/torchserve:0.1-cuda10.1-cudnn7-runtime


ENV LANG C.UTF-8
COPY ./requirements.txt /home/model-server/


RUN pip config set global.index-url https://mirror.baidu.com/pypi/simple \
    && pip install --upgrade setuptools \
    && pip install --upgrade pip \
    && pip install torch==1.6.0+cu101 torchvision==0.7.0+cu101 -f https://download.pytorch.org/whl/torch_stable.html \
    && pip install -r requirements.txt

安装包requirement如下:

transformers==3.0.2
tqdm==4.62.3
wandb==0.12.9
ipython

完整命令参考:extra-files直接指定一个文件夹即可,保证torchserve生成的目录和本地的实际的目录一致

实际目录介绍
在这里插入图片描述
特别注意入口文件handeler.py在torch-model-archiver生成打包部署文件,以及生成容器的时候会被单独拉出来在最外层文件夹,本地文件为了和docker 容器里面的目录保持一致,在本地把入口文件单独拿出来,放在最外面的一层路径
在这里插入图片描述

0 切换到支持python3和torch-model-archiver指令的虚拟环境
cd /xx/TPlinker-joint-extraction/ && source ./venv/bin/activate && cd /xx/deploy_torchserve
1 创建可模型部署的打包文件夹
mkdir ./deploy/model-store
2 生成可模型部署的mar文件 
torch-model-archiver --model-name epidemic_hsy --version 1.0  --export-path ./deploy/model-store --handler ./deploy/handler_epidemic_ner.py --extra-files "./deploy" -f

这个可以直接删除以下的配置,因为deploy已经有训练好的模型了
--serialized-file ./deploy/tplinker_plus1/default_log_dir/model_best/model_state_dict_best.pt
3 根据dockerfile制作自带cuda python的torchserve镜像
(镜像下载列表[https://hub.docker.com/r/pytorch/torchserve/tags?page=1&ordering=last_updated](https://hub.docker.com/r/pytorch/torchserve/tags?page=1&ordering=last_updated))
cd /xx/deploy_torchserve/deploy
docker build -t pytorch/torchserve:0.1-cuda10.1-cudnn7-runtime_new .
或者:
docker pull pytorch/torchserve:0.1-cuda10.1-cudnn7-runtime
4 创建容器,注意指定开启gpu模型,以及本地mar地址映射到docker容器默认地址
docker run --rm -it --gpus all -p 8080:8080 -p 8081:8081 --name epidemic_hsy -v /xx/deploy_torchserve/deploy/model-store:/home/model-server/model-store pytorch/torchserve:0.1-cuda10.1-cudnn7-runtime_new
# docker 可选参数 --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 \
# 切换到后台运行
5 不退出docker切换到后台运行
ctrl + p + q
6 进入容器
docker exec -it epidemic_hsy /bin/bash
可以拷贝文件进行相关验证
docker cp /xx/deploy_torchserve a1141a634637:/deploy_torchserve/
7 验证环境
验证cuda是否可用以及版本号,发现和本地的版本不一致,会导致不可用,重新下拉镜像
import torch
print(torch.__version__)
print(torch.version.cuda)
print(torch.backends.cudnn.version())
torch.cuda.is_available()
#cuda是否可用;
torch.cuda.device_count()
#返回gpu数量;
torch.cuda.get_device_name(0)
#返回gpu名字,设备索引默认从0开始;
torch.cuda.current_device()
#返回当前设备索引
torchserve --stop
torchserve --start --ncs --model-store /home/model-server/model-store --models epidemic_hsy.mar
8 查看已经注册的模型
curl "http://localhost:8081/models"
9 注册模型
curl -v -X POST "http://localhost:8081/models?initial_workers=1&synchronous=false&url=epidemic_hsy.mar"
10 查看注册模型详情
curl "http://localhost:8081/models/epidemic_hsy"
11 健康检查

curl http://localhost:8080/ping
```json
{
  "health": "healthy!"
}
12 实际访问测试
curl -X POST http://localhost:8080/predictions/epidemic_hsy -d "data=2021年1月4日,07:30从家中出发,交通工具无"

 curl -X POST http://localhost:8080/predictions/epidemic_hsy -T ./test.txt

它暴露了一个handle函数,我们从该函数调用自定义handler中的方法。你可以使用默认名称来使用默认handler(例如,–handler image_classifier)。
在–extra-files中,你需要将路径传递给你的handlers正在使用的所有文件。在本例中,我们必须向.json文件中添加路径。使用所有人类可读标签名称,并在MyHandler.py 中定义每个类别。
如果你传递一个index_to_name.json文件,它将自动加载到handler ,并通过self.mapping访问。
–export-path就是 .mar存放的地方,我还添加了-f来覆盖原有的文件。
如果一切顺利的话,你可以看到resnet34.mar存放在./model-store路径中。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐