精华内容
下载资源
问答
  • 将最近的工作做个记录,方便日后学习回顾: 1.针对项目需求开发满足任务的模型,拿到任务就要去选相应的算法,由于是工程应用型,必须找填...4.主要涉及环境配置、模型训练、模型编译、模型部署、产品测试。 5.包含te.

    将最近的工作做个记录,方便日后学习回顾:
    1.针对项目需求开发满足任务的模型,拿到任务就要去选相应的算法,由于是工程应用型,必须找填坑多的算法,这样遇到问题可参考的资料多。
    2.做好以后,还要将开发的算法进行封装集成,要交付的是一个相对成熟的产品,所以涉及到算法和模型的部署,而不是每个应用场景都需要像开发环境一样去构建开发环境。
    3.在本次模型的部署中遇到了各种各样的问题,有些细小问题无法全面记录,本次只按开发流程记录必要步骤。
    4.主要涉及环境配置、模型训练、模型编译、模型部署、产品测试。
    5.包含tensorRT模型加速、Triton模型推理、ubuntu18.04、GPU1080\2080\3080\3090上的不同处理、cuda、NVIDIA驱动、linux操作系统(不同设备上部署各环境要严格遵守官网建议、否则极易失败……)

    1.yolo模型训练

    网上有各种版本的训练教程,自己找一个完成训练即可。我这里所采用的是yolov5,具体训练可参看《yolov5训练自己的数据集(一文搞定训练)》

    2.tensorRT模型编译

    由于我们训练的网络模型参数较多,模型较大,且需要部署到其他机器,会导致模型加载及推理的速度降低。为了提高模型的速度,我们利用tensorRT对训练好的模型进行优化。tensorRT是C++库,故需要对现有模型进行转换。github上有各种模型的tensorRT项目:tensorRT.
    在build之前,要按照自己的训练参数对应的进行修改,如yolov5.cpp中的cuda版本,class_map……,yololayer.h中的输入图像的长宽等所有和训练有关的参数。此外,还要在编译之前就要完全按照你之后所用到的对应版本triton的配套环境进行配置(前后不匹配的话,就会和我一样遇到好多问题)这里可以回头再进行tensorRT模型的编译(重复失败几次就熟悉了……)。
    build过程其实很容易,就看环境那些的不报错就行。主要操作看官网的readme。即:

    在yolov5中将训练好的pt模型利用gen_wts.py转换成.wts文件并复制到tensorRT项目下
    然后:
    mkdir build
    cd build
    cmake …
    make
    sudo ./yolov5 -s

    通过上面步骤就会在build文件夹下生成yolov.enginelibmyplugins.so。这两个文件后面有用!

    这里是我自己的环境配置(ubuntu18.04):

    GPU1080\2080上面:
    triton20.8\9
    tensorRT7.1.3
    NVIDIA driver 450.51
    cuda11.0
    opencv3.4

    GPU3080\3090上面:
    triton20.11
    tensorRT7.2.1
    NVIDIA driver 460.84
    cuda11.1
    opencv4.0.1
    在这里插入图片描述
    #其中在该环境下编译可能会遇到上图报错,需要将yolov5.cpp文件做修改:所有的CV_FOURCC_MACRO(‘M’, ‘P’, ‘4’, ‘V’)换为cv::VideoWriter::fourcc(‘M’,‘P’,‘4’,‘V’)

    关于驱动、cuda的安装可以参看:ubuntu18.04下cuda9.0-cudnn7.6安装与多版本cuda共存及切换
    tensorRT下载链接,各版本对应的环境依赖
    opencv安装(这个适用于部署机器,若是开发进行模型编译时最好利用build得方式安装opencv,这个网上可参考的案例很多,但是在有些情况下不同版本的opencv编译的坑不同,在3080上3.4版本的我就没编译成功,最后换成了4.0.1,直接就成功了,具体操作自行查找):

    sudo add-apt-repository ppa:timsc/opencv-3.4
    sudo apt-get update
    sudo apt install libopencv-dev

    如果你安装opencv3.4.1中遇到了问题可参考:
    ubuntu18.04安装opencv3.4.3遇到问题解决方法 ubuntu18.04
    安装OpenCV3.4.1踩坑过程

    3.triton-inference-server

    Triton 推理服务器,提供针对 CPU 和 GPU 进行优化的云和边缘推理解决方案。Triton 支持 HTTP/REST 和 GRPC 协议,允许远程客户端请求对服务器管理的任何模型进行推理。对于边缘部署,Triton 可用作带有 C API 的共享库,允许将 Triton 的全部功能直接包含在应用程序中。github项目地址:https://github.com/triton-inference-server/server
    关于如何triton的介绍及使用可到官方github上仔细研读。其中强调一点就是要必须遵守官方文档中的各版本所依赖的环境,其中若是在ubuntu18.04下使用的话、使用版本20系列,20.08,20.09可在GPU1080\2080上运行,在GPU3080\3090上没成功:
    在这里插入图片描述
    在GPU3080\3090上使用20.11版本。
    关于各版本所依赖的环境可见:support-matrix
    在这里插入图片描述
    重点关注NVIDIA驱动、cuda、tensorRT三者的依赖关系。

    具体使用教程参见:Quickstart
    需要安装dockerNVIDIA Container Toolkit
    拉取所需要的triton。

    #其中 <xx.yy> 是您要拉取的 Triton 版本。
    docker pull nvcr.io/nvidia/tritonserver:<xx.yy>-py3 
    #例如  docker pull nvcr.io/nvidia/tritonserver:20.08-py3 

    创建自己的模型库,就是一个存放自己模型的文件夹,其文件存放的示例见docs/examples/model_repository 中。其中config.pbtxt文件是模型的输入输出的一些参数。

    启动服务:

    docker run --gpus=1 --rm -p8000:8000 -p8001:8001 -p8002:8002 -v/full/path/to/docs/examples/model_repository:/models nvcr.io/nvidia/tritonserver:<xx.yy>-py3 tritonserver --model-repository=/models

    也可按照指示获取客户端示例,具体看官方文档。

    4.模型部署

    将模型在别的机器上进行部署。所部署的机器不需要拥有模型的开发环境,只需配置模型的运行环境即可。

    4.1环境安装

    4.1.1 适用于gpu1080/2080

    cuda11.0-tensorRT7.1.3-opencv3.4-triton20.8 所对应的驱动大于450
    这里必须先安装cuda再装tensorRT,且安装方式要一致,我用的是deb安装

    对于该环境安装起来比较简单,直接运行脚本sh install_server_env.sh 文件具体内容如下

    #!/bin/bash
    # install cuda
    cd package/  #存放对应deb安装包的文件夹
    sudo dpkg -i cuda-repo-ubuntu1804-11-0-local_11.0.3-450.51.06-1_amd64.deb
    sudo apt-key add /var/cuda-repo-ubuntu1804-11-0-local/7fa2af80.pub
    sudo apt-get update
    sudo apt-get install cuda
    
    # install tensorrt
    sudo dpkg -i nv-tensorrt-repo-ubuntu1804-cuda11.0-trt7.1.3.4-ga-20200617_1-1_amd64.deb
    sudo apt-get update
    sudo apt-get install tensorrt
    
    # install opencv
    sudo add-apt-repository ppa:timsc/opencv-3.4
    sudo apt-get update
    sudo apt install libopencv-dev
    
    # install docker
    sudo apt-get install \
        apt-transport-https \
        ca-certificates \
        curl \
        gnupg-agent \
        software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    sudo add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
       $(lsb_release -cs) \
       stable"
    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli containerd.io
    
    sudo groupadd docker
    sudo gpasswd -a ${USER} docker
    sudo systemctl restart docker
    
    sudo cp ./daemon.json /etc/docker/daemon.json
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    # install NVIDIA Container Toolkit
    distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
       && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
       && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    sudo apt-get update
    sudo apt-get install -y nvidia-docker2
    sudo systemctl restart docker
    
    # install tritonserver
    docker pull nvcr.io/nvidia/tritonserver:20.08-py3
    
    echo "server env installed successfully!"
    

    4.1.2 适用于GPU1080\2080\3080\3090

    该环境主要是为了在30系列显卡上进行模型的部署,所需要的环境比较新,所以有很多的坑,下面是我花了好多时间测试出来的能够在30系列上部署成功的方法。由于我开发是在GPU1080上进行的,如果用我自己的环境编译出来的模型就会加载失败:
    在这里插入图片描述
    所以得在30的卡上单独编译适用于30的环境。

    测试下来triton20.11支持GPU3080\3090但其依赖cuda11.1
    相比上面一种傻瓜式安装,这种安装需要我们一步步逐步安装。
    1.升级ubuntu内核 linux kernel change to 5.9+(cuda 11.1 require)
    2.卸载原有驱动及cuda,重新安装cuda11.1+cudnn8.0.5
    3.安装tensorRT7.2.1
    4.升级NVIDIA驱动(这一步必须在安装完cuda11.1和tensorRT后进行,原因是为了满足tensorRT安装的依赖,我们的cuda必须和tensorRT采用相同的deb安装方式安装,而这种方式安装的cuda是自带驱动的)
    5.安装opencv4.0.1
    6.剩下的与上一种脚本安装基本一样

    1. 升级ubuntu内核
    参考:Ubuntu 18.04 内核升级
    按照作者教程,下载对应的deb包,下载网址https://kernel.ubuntu.com/~kernel-ppa/mainline/,升级至5.9:
    在这里插入图片描述

    sudo dpkg -i *.deb
    #重启
    reboot

    2.卸载原有驱动及cuda,重新安装cuda11.1+cudnn8.0.5

    sudo apt-get --purge remove nvidia*
    sudo apt autoremove
    sudo apt-get --purge remove "*cublas*" "cuda*"
    sudo apt-get --purge remove "*nvidia*"

    官网下载cuda11.1deb安装文件
    在这里插入图片描述

    wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
    sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
    wget https://developer.download.nvidia.com/compute/cuda/11.1.0/local_installers/cuda-repo-ubuntu1804-11-1-local_11.1.0-455.23.05-1_amd64.deb
    sudo dpkg -i cuda-repo-ubuntu1804-11-1-local_11.1.0-455.23.05-1_amd64.deb
    sudo apt-key add /var/cuda-repo-ubuntu1804-11-1-local/7fa2af80.pub
    sudo apt-get update
    sudo apt-get -y install cuda

    安装cudnn8.0.5
    这里若是cudnn与cuda版本不匹配或者不安装或者安装没有进行链接,都会在tensorRT模型编译的时候报错:
    在这里插入图片描述
    这里建议采用deb安装方式(tar解压并替换文件的方式我试了,没成功)
    参考:NVIDIA cuDNN v8 deb方法安装和卸载教程(Linux/Ubuntu)进行安装。
    官网下载下面三个文件:
    在这里插入图片描述
    在这里插入图片描述
    使用如下语句依次安装:

    sudo dpkg -i libcudnn8_8.0.5.39-1+cuda11.1_amd64.deb
    sudo dpkg -i libcudnn8-dev_8.0.5.39-1+cuda11.1_amd64.deb
    sudo dpkg -i libcudnn8-samples_8.0.5.39-1+cuda11.1_amd64.deb

    查看cudnn版本:

    dpkg -l | grep cudnn

    在这里插入图片描述
    3.安装tensorRT7.2.1

    wget https://developer.nvidia.com/compute/machine-learning/tensorrt/secure/7.2.1/local_repos/nv-tensorrt-repo-ubuntu1804-cuda11.1-trt7.2.1.6-ga-20201007_1-1_amd64.deb
    sudo dpkg -i nv-tensorrt-repo-ubuntu1804-cuda11.1-trt7.2.1.6-ga-20201007_1-1_amd64.deb
    sudo apt-get update
    sudo apt-get install tensorrt

    4.升级NVIDIA驱动

    参考网上安装驱动教程,需要禁用源,然后下载最新的nvidia驱动文件:
    在这里插入图片描述

    sudo sh NVIDIA-Linux-x86_64-460.84.run

    5.opencv4.0.1安装
    参考:Linux下安装OpenCV4(适用于Ubuntu等)
    官网下载安装包,并解压。
    在解压的文件夹里新建一个文件夹用来编译OpenCV:

    cd opencv-4.0.1
    mkdir release
    cd release
    cmake -DCMAKE_BUILD_TYPE=Release -DOPENCV_GENERATE_PKGCONFIG=ON -DCMAKE_INSTALL_PREFIX=/usr/local ..
    make -j7
    sudo make install
    cd /etc/ld.so.conf.d/
    sudo touch opencv4.conf
    sudo sh -c 'echo "/usr/local/lib" > opencv4.conf'
    sudo ldconfig

    6.其余环境安装,直接用上一节中的脚本将triton换为20.11安装即可

    运行脚本sh install_server_env.sh其具体内容如下:

    # install docker
    sudo apt-get install \
        apt-transport-https \
        ca-certificates \
        curl \
        gnupg-agent \
        software-properties-common
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    sudo add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
       $(lsb_release -cs) \
       stable"
    sudo apt-get update
    sudo apt-get install docker-ce docker-ce-cli containerd.io
    
    sudo groupadd docker
    sudo gpasswd -a ${USER} docker
    sudo systemctl restart docker
    
    sudo cp ./daemon.json /etc/docker/daemon.json
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    # install NVIDIA Container Toolkit
    distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
       && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
       && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
    sudo apt-get update
    sudo apt-get install -y nvidia-docker2
    sudo systemctl restart docker
    
    # install tritonserver
    docker pull nvcr.io/nvidia/tritonserver:20.11-py3
    
    echo "server env installed successfully!"

    至此就完成了所有环境在GPU3080上的安装,我们要用该环境编译使用于30的模型,故在这之后重新build
    tensorRT模型(见第二节),这里说下编译好的模型如何建立triton模型库。编译将生成的yolov5.engin改名为model.plan。另外还有生成的libmyplugins.so文件,按照下面tree放置:
    在这里插入图片描述
    其中config.pbtxt文件:
    在这里插入图片描述

    4.2启动triton服务

    sh run_triton_model.sh启动,文件内容如下(其中在30系列上是tritonserver:20.11。20.08启动一样,改个版本换个模型即可):

    #!/bin/bash
    docker run --gpus all \    
    	--rm --shm-size=1g \    
    	--ipc=host --ulimit memlock=-1 \    
    	--ulimit stack=67108864 -p8000:8000 -p8001:8001 -p8002:8002 \    
    	-v$(pwd)/triton_deploy/models:/models \    
    	-v$(pwd)/triton_deploy/plugins:/plugins \    
    	--env LD_PRELOAD=/plugins/libmyplugins.so nvcr.io/nvidia/tritonserver:20.11-py3 tritonserver \    
    	--model-repository=/models \    
    	--grpc-infer-allocation-pool-size=16 --log-verbose 1

    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

    4.3启动封装好的客户端界面

    在这里插入图片描述

    在这里插入图片描述
    部署后的检测帧率在每秒50帧左右:在这里插入图片描述

    5总结

    本来在1080\2080直接就部署成功的,但是在部署3080设备时遇到了很多不兼容的问题,经过不断的尝试终于一步步走了下去。真的是每进行一步都有各种大大小小的问题。在解决问题中有的直接就可以找到处理方法,但是有的网上搜不到,只能自己尝试解决,这个过程相当痛苦,前前后后搞了将近一周,熬夜加班,有时候也想放弃。但是回头来看,总结几点吧,官方文档一定要仔细看,多参考别人躺过的坑,还有就是心态不能乱!

    展开全文
  • pytorch模型转TensorRT模型部署

    千次阅读 2020-12-03 14:26:03
    pytorch训练的模型用Tensor模型部署 我们在部署AI模型时可以有多种选择,使用的是cpu还是gpu,部署框架直接使用pytorch,也可以选择tensorRT,会加速模型推理。这里主要讲的是pytorch模型怎么用tensorRT来部署,...

    pytorch训练的模型用Tensor模型部署

     

    我们在部署AI模型时可以有多种选择,使用的是cpu还是gpu,部署框架直接使用pytorch,也可以选择tensorRT,会加速模型推理。这里主要讲的是pytorch模型怎么用tensorRT来部署,先来总结一下我们常用的部署方案。

    常用部署方案:

    cpu: pytorch->onnx->onnxruntime

    gpu: pytorch->onnx->onnx2trt->tensorRT

    arm: pytorch->onnx->ncnn/mace/mnn等

     

    1.pytorch到onnx模型转换

    转换的方法可以直接看到我的另外一篇博客(https://blog.csdn.net/u012505617/article/details/108770840),这里也顺便贴一下转换的代码:

    import torch
     
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
     
    def model_converter():
        model = torch.load('resnet50.pth').to(device)  # 这里保存的是完整模型
        model.eval()
     
        dummy_input = torch.randn(1, 3, 96, 96, device=device)
        input_names = ['data']
        output_names = ['fc']
        torch.onnx.export(model, dummy_input, 'resnet50.onnx', 
                          export_params=True, 
                          verbose=True, 
                          input_names=input_names, 
                          output_names=output_names)

     

    2.onnx模型转TensorRT模型

    这里直接使用我们安装的TensorRT-7.0.0.11自带的工具进行转换,进入TensorRT-7.0.0.11/bin 目录,执行:

    ./trtexec --onnx=resnet50.onnx --saveEngine=resnet50.trt

     

    3.TensorRT模型推理

    import tensorrt as trt
    import pycuda.driver as cuda
    import pycuda.autoinit
    
    import numpy as np
    import time
    import cv2
    
    TRT_LOGGER = trt.Logger()
    
    def get_img_np_nchw(image):
        image_cv = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image_cv = cv2.resize(image_cv, (112, 112))
        mean = np.array([0.485, 0.456, 0.406])
        std = np.array([0.229, 0.224, 0.225])
        img_np = np.array(image_cv, dtype=float) / 255.
        img_np = (img_np - mean) / std
        img_np = img_np.transpose((2, 0, 1))
        img_np_nchw = np.expand_dims(img_np, axis=0)
        return img_np_nchw
    
    class HostDeviceMem(object):
        def __init__(self, host_mem, device_mem):
            super(HostDeviceMem, self).__init__()
            self.host = host_mem
            self.device = device_mem
    
        def __str__(self):
            return "Host:\n" + str(self.host) + "\nDevice:\n" + str(self.device)
    
        def __repr__(self):
            return self.__str__()
            
    
    def allocate_buffers(engine):
        inputs = []
        outputs = []
        bindings = []
        stream = cuda.Stream()  # pycuda 操作缓冲区
        for binding in engine:
            size = trt.volume(engine.get_binding_shape(binding)) * engine.max_batch_size
            dtype = trt.nptype(engine.get_binding_dtype(binding))
    
            host_mem = cuda.pagelocked_empty(size, dtype)
            device_mem = cuda.mem_alloc(host_mem.nbytes)  # 分配内存
            bindings.append(int(device_mem))
    
            if engine.binding_is_input(binding):
                inputs.append(HostDeviceMem(host_mem, device_mem))
            else:
                outputs.append(HostDeviceMem(host_mem, device_mem))
        return inputs, outputs, bindings, stream
    
    def get_engine(engine_file_path=""):
        print("Reading engine from file {}".format(engine_file_path))
        with open(engine_file_path, "rb") as f, trt.Runtime(TRT_LOGGER) as runtime:
            return runtime.deserialize_cuda_engine(f.read())
    
    
    def do_inference(context, bindings, inputs, outputs, stream, batch_size=1):
        [cuda.memcpy_htod_async(inp.device, inp.host, stream) for inp in inputs] # 将输入放入device
        context.execute_async(batch_size=batch_size, bindings=bindings, stream_handle=stream.handle) # 执行模型推理
        [cuda.memcpy_dtoh_async(out.host, out.device, stream) for out in outputs] # 将预测结果从缓冲区取出
        stream.synchronize()    # 线程同步
        return [out.host for out in outputs]
    
    def postprocess_the_outputs(h_outputs, shape_of_output):
        h_outputs = h_outputs.reshape(*shape_of_output)
        return h_outputs
    
    def landmark_detection(image_path):
        trt_engine_path = './models/landmark_detect_106.trt'
    
        engine = get_engine(trt_engine_path)
        context = engine.create_execution_context()
        inputs, outputs, bindings, stream = allocate_buffers(engine)
    
        image = cv2.imread(image_path)
        image = cv2.resize(image, (112, 112))
        img_np_nchw = get_img_np_nchw(image)
        img_np_nchw = img_np_nchw.astype(dtype=np.float32)
    
        inputs[0].host = img_np_nchw.reshape(-1)
        t1 = time.time()
        trt_outputs = do_inference(context, bindings=bindings, inputs=inputs, outputs=outputs, stream=stream)
        t2 = time.time()
        print('used time: ', t2-t1)
    
        shape_of_output = (1, 212)
        landmarks = postprocess_the_outputs(trt_outputs[1], shape_of_output)
        landmarks = landmarks.reshape(landmarks.shape[0], -1, 2)
    
        height, width = image.shape[:2]
        pred_landmark = landmarks[0] * [height, width]
    
        for (x, y) in pred_landmark.astype(np.int32):
            cv2.circle(image, (x, y), 1, (0, 255, 255), -1)
    
        cv2.imshow('landmarks', image)
        cv2.waitKey(0)
    
        return pred_landmark
    
    if __name__ == '__main__':
        image_path = './images/3766_20190805_12_10.png'
        landmarks = landmark_detection(image_path)
    
    

     

    4.效果对比

    pytorch:0.00593s

    tensorRT:0.00109s

    可见在速度上TensorRT比pytorch有5倍多的提升。

     

    参考:

    https://blog.csdn.net/qq_37546267/article/details/106767640

     

     

     

     

     

     

     

     

    展开全文
  • Pytorch模型部署 - Libtorch(crnn模型部署)

    千次阅读 热门讨论 2020-03-21 15:42:32
    Pytorch模型部署 - Libtorch 简介 libtorch是facebook提供的一套C++推理接口库,便于工业级别部署和性能优化。 安装: libtoch+opencv联合编译,这里采用libtorch-1.4(cpu)+opencv4.1. 可能出现的问题 ibtoch,...

    Pytorch模型部署 - Libtorch

    简介

    libtorch是facebook提供的一套C++推理接口库,便于工业级别部署和性能优化。

    配置

    • cmake 3.0
    • libtorch-1.14(cpu)
    • opencv-4.1.1

    安装:

    libtoch+opencv联合编译,这里采用libtorch-1.4(cpu)+opencv4.1.

    • 可能出现的问题

      • ibtoch,opencv联合编译项目时,报错Undefined reference to cv::imread(std::string const&, int).
      • 解决方案:
        • 在相同编译环境下,重新编译libtorch和opencv源码.(未测试…)
        • 在opencv的CMakeList.txt中加上add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)重新编译opencv.(测试通过)
    • libtorch安装:解压下载包就可以,在代码编译时指定库的路径即可。

    • opencv安装: 下载源码 https://opencv.org/releases/

      unzip opencv-4.1.1.zip
      cd opencv-4.1.1
      # vim CMakeList.txt 如果出现上面问题,在这里添加上述命令,重新编译安装
      mkdir build && cd build
      cmake -D CMAKE_BUILD_TYPE=RELEASE -D OPENCV_GENERATE_PKGCONFIG=ON -D CMAKE_INSTALL_PREFIX=/usr/local ..
      make -j4
      sudo make intall
      

      ls /usr/local/lib查看安装好的opencv库.

    案例:libtorch部署crnn-英文识别模型.

    crnn: 文本识别模型,常用于OCR.

    Step1: 模型转换

    将pytorch训练好的crnn模型转换为libtorch能够读取的模型.

    #covertion.py
    import torch
    import torchvison
    
    model = CRNN(32, 1, len(keys.alphabetEnglish) + 1, 256, 1).cpu()
    
    state_dict = torch.load(
        model_path, map_location=lambda storage, loc: storage)
    new_state_dict = OrderedDict()
    for k, v in state_dict.items():
        name = k.replace('module.', '')  # remove `module.`
        new_state_dict[name] = v
    # # # load params
    model.load_state_dict(new_state_dict)
    
    # convert pth-model to pt-model
    example = torch.rand(1, 1, 32, 512)
    traced_script_module = torch.jit.trace(model, example)
    traced_script_module.save("src/crnn.pt")
    

    代码过长,github附完整代码。github: crnn_libtorch

    Step2: 模型部署

    利用libtoch+opencv实现对文字条的识别.

    //crnnDeploy.h
    #include <torch/torch.h>
    #include <torch/script.h>
    #include <opencv2/highgui.hpp>
    #include <opencv2/imgproc.hpp>
    
    #include <iostream>
    #include <cassert>
    #include <vector>
    
    #ifndef CRNN_H
    #define CRNN_H
    
    class Crnn{
        public:
            Crnn(std::string& modelFile, std::string& keyFile);
            torch::Tensor loadImg(std::string& imgFile, bool isbath=false);
            void infer(torch::Tensor& input);
        private:
            torch::jit::script::Module m_module;
            std::vector<std::string> m_keys;
            std::vector<std::string> readKeys(const std::string& keyFile);
            torch::jit::script::Module loadModule(const std::string& modelFile);
    };
    
    #endif//CRNN_H
    
    /*
    @author
    date: 2020-03-17
    Introduce:
        Deploy crnn model with libtorch.
    */
    
    #include "CrnnDeploy.h"
    #include <thread>
    #include <sys/time.h>
    
    //construtor
    Crnn::Crnn(std::string& modelFile, std::string& keyFile){
        this->m_module = this->loadModule(modelFile);
        this->m_keys = this->readKeys(keyFile);
    }
    
    
    torch::Tensor Crnn::loadImg(std::string& imgFile, bool isbath){
    	cv::Mat input = cv::imread(imgFile, 0);
    	if(!input.data){
    		printf("Error: not image data, imgFile input wrong!!");
    	}
    	int resize_h = int(input.cols * 32 / input.rows);
    	cv::resize(input, input, cv::Size(resize_h, 32));
        torch::Tensor imgTensor;
        if(isbath){
            imgTensor = torch::from_blob(input.data, {32, resize_h, 1}, torch::kByte);
    	    imgTensor = imgTensor.permute({2,0,1});
        }else
        {
            imgTensor = torch::from_blob(input.data, {1,32, resize_h, 1}, torch::kByte);
            imgTensor = imgTensor.permute({0,3,1,2});
        }
    	imgTensor = imgTensor.toType(torch::kFloat);
    	imgTensor = imgTensor.div(255);
    	imgTensor = imgTensor.sub(0.5);
    	imgTensor = imgTensor.div(0.5);
        return imgTensor;
    }
    
    void Crnn::infer(torch::Tensor& input){
        torch::Tensor output = this->m_module.forward({input}).toTensor();
        std::vector<int> predChars;
        int numImgs = output.sizes()[1];
        if(numImgs == 1){
            for(uint i=0; i<output.sizes()[0]; i++){
                auto maxRes = output[i].max(1, true);
                int maxIdx = std::get<1>(maxRes).item<float>();
                predChars.push_back(maxIdx);
            }
            // 字符转录处理
            std::string realChars="";
            for(uint i=0; i<predChars.size(); i++){
                if(predChars[i] != 0){
                    if(!(i>0 && predChars[i-1]==predChars[i])){
                        realChars += this->m_keys[predChars[i]];
                    }
                }
            }
            std::cout << realChars << std::endl;
        }else
        {
            std::vector<std::string> realCharLists;
            std::vector<std::vector<int>> predictCharLists;
    
            for (int i=0; i<output.sizes()[1]; i++){
                std::vector<int> temp;
                for(int j=0; j<output.sizes()[0]; j++){
                    auto max_result = (output[j][i]).max(0, true);
                    int max_index = std::get<1>(max_result).item<float>();//predict value
                    temp.push_back(max_index);
                }
                predictCharLists.push_back(temp);
            }
    
            for(auto vec : predictCharLists){
                std::string text = "";
                for(uint i=0; i<vec.size(); i++){
                    if(vec[i] != 0){
                        if(!(i>0 && vec[i-1]==vec[i])){
                            text += this->m_keys[vec[i]];
                        }
                    }
                }
                realCharLists.push_back(text);
            }
            for(auto t : realCharLists){
                std::cout << t << std::endl;
            }
        }
    
    }
    
    std::vector<std::string> Crnn::readKeys(const std::string& keyFile){
        std::ifstream in(keyFile);
    	std::ostringstream tmp;
    	tmp << in.rdbuf();
    	std::string keys = tmp.str();
    
        std::vector<std::string> words;
        words.push_back(" ");//函数过滤掉了第一个空格,这里加上
        int len = keys.length();
        int i = 0;
        
        while (i < len) {
          assert ((keys[i] & 0xF8) <= 0xF0);
          int next = 1;
          if ((keys[i] & 0x80) == 0x00) {
          } else if ((keys[i] & 0xE0) == 0xC0) {
            next = 2;
          } else if ((keys[i] & 0xF0) == 0xE0) {
            next = 3;
          } else if ((keys[i] & 0xF8) == 0xF0) {
            next = 4;
          }
          words.push_back(keys.substr(i, next));
          i += next;
        } 
        return words;
    }
    
    torch::jit::script::Module Crnn::loadModule(const std::string& modelFile){
        torch::jit::script::Module module;
        try{
             module = torch::jit::load(modelFile);
        }catch(const c10::Error& e){
            std::cerr << "error loadding the model !!!\n";
        }
        return module;
    }
    
    
    long getCurrentTime(void){
        struct timeval tv;
        gettimeofday(&tv, NULL);
        return tv.tv_sec * 1000 + tv.tv_usec/1000;
    }
    
    int main(int argc, const char* argv[]){
    
        if(argc<4){
            printf("Error use CrnnDeploy: loss input param !!! \n");
            return -1;
        }
        std::string modelFile = argv[1];
        std::string keyFile = argv[2];
        std::string imgFile = argv[3];
    
        long t1 = getCurrentTime();
        Crnn* crnn = new Crnn(modelFile,keyFile);
        torch::Tensor input = crnn->loadImg(imgFile);
        crnn->infer(input);
        delete crnn;
        long t2 = getCurrentTime();
    
        printf("ocr time : %ld ms \n", (t2-t1));
        return 0;
    }
    

    完整代码和测试模型:
    github: crnn_libtorch

    获取代码: git clone https://github.com/chenyangMl/crnn_libtorch.git

    参考

    • opencv installtion: https://docs.opencv.org/master/d7/d9f/tutorial_linux_install.html
    • libtorch : https://pytorch.org/tutorials/advanced/cpp_frontend.html
    展开全文
  • 模型部署方法

    2019-11-18 10:39:29
    Flask 和 Google App Engine 部署模型服务使用方法 将机器学习模型部署为REST API(github)
    展开全文
  • 深度学习模型部署与剪枝优化实例课程旨在帮助同学们快速掌握模型部署与优化方法。主要包括两大核心模块:1.基于深度学习框架PyTorch与Tensorflow2版本演示模型部署方法,使用docker工具简化环境配置与迁移问题;2....
  • 本文为系列博客tensorflow模型部署系列的一部分,用于实现通用模型的部署。本文主要实现用C++接口调用tensorflow模型进行推理。相关源码见链接 引言 本文为系列博客tensorflow模型部署系列的一部分,用于C++语言...
  • 本文为系列博客tensorflow模型部署系列的一部分,用于实现通用模型的TensorFlow Serving部署。本文主要实现用TensorFlow Serving部署tensorflow模型推理服务器。实现了tensorflow模型在服务器端计算方案,并提供相关...
  • 深度学习模型部署技术方案

    千次阅读 2020-07-12 17:13:55
    深度学习模型部署技术方案训练好的深度学习模型如何进行部署的相关技术方案1 什么是模型部署?2 数据科学项目整个开发流程3 使用flask 将 Keras深度学习模型部署为Web应用程序 训练好的深度学习模型如何进行部署的...
  • 本文为系列博客tensorflow模型部署系列的一部分,用于为模型部署提供最开始的输入————标准化的模型文件。 引言 本文为系列博客tensorflow模型部署系列的一部分,用于为模型部署提供最开始的输入————标准化...
  • 本文为系列博客tensorflow模型部署系列的一部分,用于javascript实现通用模型的部署。本文主要实现用javascript接口调用tensorflow模型进行推理。实现了tensorflow在浏览器前端计算方案,将计算任务分配在终端,可以...
  • 本文为系列博客tensorflow模型部署系列的一部分,用于实现通用模型的部署。本文主要实现用JAVA接口调用tensorflow模型进行推理。相关源码见链接 引言 本文为系列博客tensorflow模型部署系列的一部分,用于JAVA语言...
  • 本文为系列博客tensorflow模型部署系列的一部分,用于实现通用模型的部署。通用主要体现在通过tensorboard图从已保存的模型中还原并查看模型详细结构,以及自定义模型的输入输出tensor 引言 本文为系列博客...
  • 本文为系列博客tensorflow模型部署系列的一部分,用于实现通用模型的独立简单服务器部署。本文主要实现用flask搭建tensorflow模型推理服务器。实现了tensorflow模型在服务器端计算方案,并提供相关示例源代码。相关...
  • TF模型部署的特点

    2020-04-30 11:24:32
    TF模型部署的特点 可扩展性、稳定性、可靠性(能经历大规模多应用部署的考验)好 可扩展性、稳定性、可靠性(能经历大规模多应用部署的考验)好 TF serving高性能,开源的机器学习服务系统,专为部署设计的 TF ...
  • tensorflow模型部署系列————立贴

    千次阅读 2019-05-20 17:47:05
    模型部署的第一步就是要有模型,所以我首先把模型导出方法做一下梳理,部署主要有两种:单机版和服务器版。单机版可以在单机上进行模型推理,主要应用在离线的智能终端、边缘计算产品上;单机版我先从最简单的p...
  • Tensorflow Serving 模型部署和服务

    万次阅读 2017-03-31 19:27:23
    本文转载自:https://zhuanlan.zhihu.com/p/233614132016年,机器学习在 Alpha Go 与李世石的世纪之战后变得更加炙手可热。Google也在今年推出了 ...它可以将训练好的机器学习模型部署到线上,使用 gRPC 作为接
  • 我们为医疗行业的模型部署做出了贡献,在过去的几个月中,我们已经帮助多家公司将经过训练的模型转移到不同类型的IoT设备上。 特别是在IoT设备情况下,要求通常很严格:计算周期数和可用内存通常都受到限制。 在...
  • 部署所知
  • 综合网上一些经验,对模型部署发布知识进行整理; 详见github: https://github.com/Stonesusu/model_service 其中接口测试,一共采用两种方式: 1、Postman; 2、python代码开发; ...
  • 本文为系列博客tensorflow模型部署系列的一部分,用于实现通用模型的部署。本文主要实现用tflite接口调用tensorflow模型进行推理。相关源码见链接 引言 本文为系列博客tensorflow模型部署系列的一部分,用于tflite...
  • 将keras模型部署到服务器上

    千次阅读 2019-09-21 19:30:54
    关于TensorFlow模型的部署可以看我的另一篇博客将TensorFlow模型部署到服务器上 下面是keras转TensorFlow的参考代码 # -*- coding: utf-8 -*- from keras.layers.core import Activation, Dense, F...
  • tensorflow_serving通过model_config_file进行模型部署以及更新部署TF Serving模型部署docker方式第一种方式第二种方式,通过model_config_file进行部署(推荐) TF Serving TF Serving架构具体包括:servables、...
  • Paddle Lite——将自己的模型部署在树莓派端

    千次阅读 多人点赞 2020-06-12 15:38:40
    文章目录准备模型文件在Paddle-Detection项目中转换模型跑通Paddle-Lite demo部署自己的模型部署模型.nb文件运行模型 准备模型文件 此处仅演示用Paddle Detection模型直接转换为paddle-Lite支持的.nb模型文件,其他...
  • 本篇文章分享一下如何使用容器进行模型部署并使用部署好的模型。 tfserving镜像下载 使用docker下载tfserving镜像,关于docker的使用可参考,tfserving包含的版本可在此查看。 docker pull tensorflow/serving:2.1.0...
  • 机器学习模型部署及在线预测

    千次阅读 2019-01-03 11:43:40
    到目前为止,我们训练的传统机器学习模型都只能进行本地预测(本地调用test方法),那么怎么样把我们的模型部署到线上,然后做在线实时预测呢? 我们的模型实际上就是一个y = f(x)函数,x是特征数据,y是预测结果。...
  • 深度学习模型部署及在线预测

    千次阅读 2019-11-09 11:20:33
    模型导出 我们在前面的内容中讲到过,可以使用tf.train.Saver....只有导出整个模型(除了模型变量、还包括模型计算图和图的元数据),才能做模型部署和在线预测,这时就必须使用SavedModel(也可以导出Session Bund...
  • (二)TensorFlow Serving系列之导出自己的训练模型 (三)TensorFlow Serving系列之客户端gRPC调用 (四)TensorFlow Serving系列之gRPC基本知识 (五)TensorFlow Serving系列之源码安装服务 (六)TensorFlow ...
  • AI实战:AI模型部署系列之docker

    千次阅读 2019-07-15 20:16:08
    AI模型部署系列之多docker
  • 深度学习Tensorflow生产环境部署(下·模型部署篇) 前一篇讲过环境的部署篇,这一次就讲讲从代码角度如何导出pb模型,如何进行服务调用。 1 hello world篇 部署完docker后,如果是cpu环境,可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 332,521
精华内容 133,008
关键字:

模型部署