还不会使用torchserve部署yoloV5模型?(不使用Docker)

Posted 啊~小 l i

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了还不会使用torchserve部署yoloV5模型?(不使用Docker)相关的知识,希望对你有一定的参考价值。

没有使用Docker容器

  1. 环境简介
    1. 操作系统centos8
    2. conda管理的python3.8(此处建议使用python3.8);
    3. JDK11(openJDK,Oracle JDK)
    4. 其他相关的python库(torch,cv2,numpy等等)
  2. 环境配置
    1. Java环境配置
      JDK下载Oracle JDK11下载官网
    2. 配置环境变量 (这里使用的源码安装)
      sudo vim /etv/bashrc然后将下面的环境变量添加到末尾
export JAVA_HOME=(您的 JDK 路径)
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib
export PATH=$JAVA_HOME/bin:$PATH
  1. python环境配置
    1. conda的安装(使用清华源手动下载,下载速度会更快)清华源Anaconda链接
      下载后进入 下载Anaconda的文件夹使用命令sudo bash (Conda的文件)
      PS:统一用户选项后,可以自由选择安装路径。最后选择自动配置环境变量
    2. conda的安装测试
      conda安装后激活环境变量source ~/.bashrc
      使用命令测试Conda环境conda env list
    3. conda的使用
      1. 环境的创建 conda create -n (环境名) python=需要的python版本
      2. conda的切换 conda activate 环境名
      3. conda环境的复制conda create -n (创建的环境名字) --clone (copy的环境名字)
    4. 依赖的安装
      切换到自己的想要使用的conda环境后使用pip/conda命令安装依赖
      1. 打包需要的库是torch-model-archiver
      2. 部署需要的库是torchserve
  2. 模型打包
    模型打包是一个很麻烦的步骤,我也参考过很多网上的资料,很多资料都是不可以使用的。这里提供一种比较好的思路来部署模型。
    1. 模型部署前的准备
      • YoloV5相关配置文件(dataloader.py;model.py等需要的基础配置文件)
    2. 手写处理流程(难点)
      模型部署后接收到的图片为字节流,我们需要对传输的数据进行处理,然后使用Hander.py文件对流程进行处理。
from ts.torch_handler.base_handler import BaseHandler
import torch
class MyHandler(BaseHandler):
    def __init__(self):
        # 初始化实例,看具体情况重写
        # self.model = None 
        # self.mapping = None
        # self.device = None
        # self.initialized = False
        # self.context = None
        # self.manifest = None
        # self.map_location = None
        # self.explain = False
        # self.target = 0
        ......
    def initialize(self,context):
        # 初始化模型及其它相关参数,看具体情况重写
        ......
    def preprocess(self, data):
        # 前处理,关键步骤,一般情况下都需要重写
        ......
    def inference(self, model_input):
        # 推理,看具体情况重写
        ......
    def postprocess(self, inference_output):
        # 后处理,关键步骤,一般情况下都需要重写
        ......
    def handle(self, data, context):
        # 服务流程,看具体情况重写
        ......

这里给大家我自己手写的一个参考(可以使用)

import torch
from PIL import Image
from hubconf import create_model
import logging
import os
import time
import io
import base64
from pathlib import Path

logger = logging.getLogger(__name__)


class YoloHandler(object):
    
    def __init__(self):
       self.model = None
       self.device = None
       self.initialized = False
       self.context = None
       self.manifest = None
       self.map_location = None
       self.explain = False

    def initialize(self, context):
        """Initialize function loads the model.pt file and initialized the model object.

        Args:
            context (context): It is a JSON Object containing information
            pertaining to the model artifacts parameters.

        Raises:
            RuntimeError: Raises the Runtime error when the model.py is missing

        """
        properties = context.system_properties
        self.map_location = "cuda" if torch.cuda.is_available() else "cpu"
        self.device = torch.device(
            self.map_location + ":" + str(properties.get("gpu_id"))
            if torch.cuda.is_available()
            else self.map_location
        )
        self.manifest = context.manifest
        model_dir = properties.get("model_dir")
        serialized_file = self.manifest["model"]["serializedFile"]
        yolov5_model_name = os.path.splitext(serialized_file)[0]
        model_pt_path = os.path.join(model_dir, serialized_file)

        if not os.path.isfile(model_pt_path):
            raise RuntimeError("Missing the model.pt file")

        self.model = create_model(yolov5_model_name, model_pt_path, channels=3, classes=1, autoshape=True)
        logger.info("Loading eager model")
        self.model.to(self.device)
        self.model.eval()

        logger.info('Model file %s loaded successfully', model_pt_path)
        self.initialized = True

    def preprocess(self, data):
        """The preprocess function of MNIST program converts the input data to a float tensor

        Args:
            data (List): Input data from the request is in the form of a Tensor

        Returns:
            list : The preprocess function returns the input image as a list of float tensors.
        """
        images = []

        for row in data:
            # Compat layer: normally the envelope should just return the data
            # directly, but older versions of Torchserve didn't have envelope.
            image = row.get("data") or row.get("body")
            if isinstance(image, str):
                # if the image is a string of bytesarray.
                image = base64.b64decode(image)

            # If the image is sent as bytesarray
            if isinstance(image, (bytearray, bytes)):
                image = Image.open(io.BytesIO(image))
            else:
                # if the image is a list
                image = torch.FloatTensor(image)

            images.append(image)

        return images

    def handle(self, data, context):
        """Entry point for default handler. It takes the data from the input request and returns
           the predicted outcome for the input.

        Args:
            data (list): The input data that needs to be made a prediction request on.
            context (Context): It is a JSON Object containing information pertaining to
                               the model artefacts parameters.

        Returns:
            list : Returns a list of dictionary with the predicted response.
        """

        # It can be used for pre or post processing if needed as additional request
        # information is available in context
        start_time = time.time()

        self.context = context
        metrics = self.context.metrics

        data_preprocess = self.preprocess(data)

        if not self._is_explain():
            output = self.model(data_preprocess)
            output = self.postprocess(output)

        stop_time = time.time()
        metrics.add_time('HandlerTime', round((stop_time - start_time) * 1000, 2), None, 'ms')
        return output

    def _is_explain(self):
        return False

    def postprocess(self, data):
        result = []
        preds = data.pred
        class_names = data.names
        for batch_idx, pred in enumerate(preds):
            if pred is not None:
                retval=[]
                for *box, conf, cls in pred:  # xyxy, confidence, class
                    _retval = 
                    xmin = float(box[0])
                    ymin = float(box[1])
                    xmax = float(box[2])
                    ymax = float(box[3])
                    _retval['boxes'] = [xmin, ymin, xmax, ymax]
                    _retval['score'] = float(conf)
                    _retval['class'] = class_names[int(cls)]
                    retval.append(_retval)
                result.append(retval)

        return result

**补充:**这里的代码并不能直接使用,这里打包的时候还需要将其他YOLOV5的相关代码一起打包进去,这里仅供参考。完整的部署代码(自己手写基于YOLOV5代码做出来的)见我的Gitee链接

打包命令torch-model-archiver --model-name test --version 1 --serialized-file ./last_90.pt --handler ./handler.py --extra-files ./file(这个就是要加载的py文件) -f

  1. 模型部署
    配置文件编写示例(config.properties):
inference_address=http://0.0.0.0:8080
management_address=http://127.0.0.1:8081
metrics_address=http://127.0.0.1:8082

配置好相关将模型放到文件夹使用命令启动
torchserve --start --model-store model_store --models yolo5=yolo5.mar --ts-config ./config.properties

以上是关于还不会使用torchserve部署yoloV5模型?(不使用Docker)的主要内容,如果未能解决你的问题,请参考以下文章

还不会使用torchserve部署yoloV5模型?(不使用Docker)

TorchServe部署HuggingFace文本生成模型

TorchServe部署HuggingFace文本生成模型

TorchServe部署HuggingFace文本生成模型

torchserve安装模型的部署与测试(基于docker)

Yolov5s模型在全志V853平台上的部署方法和应用