torchserver模型本地部署和docker部署-自定义handler函数以及通过dockerfile一键部署
案例部署参考:https://blog.csdn.net/qq_15821487/article/details/122684773?spm=1001.2014.3001.5502模型打包(torch-model-archiver)我们需要两个文件和一个handler.py,分别是:1,模型(.pt,.bin的torch模型参数文件)2,需要读取的一些配置或者函数文件3,handler.py我们具
参考
案例部署参考:
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路径中。
更多推荐
所有评论(0)