草庐IT

开源深度学习模型部署工具箱MMDeploy简介及安装

fengbingchun 2024-07-06 原文

      MMDeploy是一个开源的深度学习模型部署工具箱,是OpenMMLab项目的一部分,源码在 https://github.com/open-mmlab/mmdeploy,最新发布版本为v0.8.0,License为Apache-2.0。它支持在Windows10、Linux和Mac上运行。
      MMDeploy主要特性
      (1).支持超多OpenMMLab算法库,如mmcls、mmdet、mmseg、mmocr等;
      (2).支持多种推理后端,如ONNX Runtime、TensorRT、LibTorch等;
      (3).支持可扩展的C/C++ SDK框架,如Transform图像处理、Net神经网络推理等。
      MMDeploy定义的模型部署流程:如下图所示:https://github.com/open-mmlab/mmdeploy/blob/master/docs/en/get_started.md

      (1).模型转换(Model Converter):旨在将训练模型从OpenMMLab转换为可以在目标设备上运行的后端模型。它可以把PyTorch模型转换为ONNX、TorchScript等和设备无关的IR模型。也可以将ONNX模型转换为推理后端模型。两者相结合,可实现端到端的模型转换,也就是从训练端到生产端的一键式部署。
      (2).MMDeploy模型(MMDeploy Model):是Model Converter导出的结果包,除了后端模型(backend model),它还包括模型的元信息,将用于推理SDK中。
      (3).推理SDK(Inference SDK):由C/C++开发,封装了模型的前处理、网络推理和后处理过程。对外提供多语言的模型推理接口,如C、C++、Python等。

      以下内容主要来自 https://github.com/open-mmlab/mmdeploy/blob/master/README_zh-CN.md 中的新人解说:
      模型部署:
      (1).模型部署:指把训练好的模型在特定环境中运行的过程。MMDeploy实现了OpenMMLab中目标检测、图像分割、超分辨率等多个视觉任务模型的部署,支持ONNX Runtime,TensorRT,ncnn,openppl,OpenVINO等多个推理引擎。
      (2).模型部署的常见流水线是"深度学习框架--中间表示--推理引擎"。其中比较常用的一个中间表示是ONNX。
      (3).深度学习模型实际上就是一个计算图。模型部署时通常把模型转换成静态的计算图,即没有控制流(分支语句、循环语句)的计算图。
      (4).PyTorch框架自带对ONNX的支持,只需要构造一组随机的输入,并对模型调用torch.onnx.export即可完成PyTorch到ONNX的转换。
      (5).推理引擎ONNX Runtime对ONNX模型有原生的支持。给定一个.onnx文件,只需要简单使用ONNX Runtime的Python API就可以完成模型推理。
      (6).模型部署中常见的几类困难有:模型的动态化;新算子的实现;框架间的兼容。
      (7).PyTorch转ONNX,实际上就是把每一个操作转化成ONNX定义的某一个算子。比如对于PyTorch中的Upsample和interpolate,在转ONNX后最终都会成为ONNX的Resize算子。
      (8).通过修改继承自torch.autograd.Function的算子的symbolic方法,可以改变该算子映射到ONNX算子的行为。

      PyTorch到ONNX的转换函数:torch.onnx.export
      PyTorch模型到ONNX模型转换示例:https://blog.csdn.net/fengbingchun/article/details/126072998
      TorchScript是PyTorch模型(torch.nn.Module的子类)的中间表示,是一种从PyTorch代码创建可序列化和可优化模型的方法,可以在C++等高性能环境(high-performance environment)中运行。任何TorchScript程序都可以从Python进程中保存并加载到没有Python依赖项的进程中。
      torch.onnx.export中需要的模型实际上是一个torch.jit.ScriptModule。而要把普通PyTorch模型转一个这样的TorchScript模型,有跟踪(trace)和脚本化(script)两种导出计算图的方法。如果给torch.onnx.export传入了一个普通PyTorch模型(torch.nn.Module),那么这个模型会默认使用跟踪的方法导出。
      跟踪法只能通过实际运行一遍模型的方法导出模型的静态图,即无法识别出模型中的控制流(如循环);脚本化则能通过解析模型来正确记录所有的控制流。
      函数torch.onnx.export的声明如下:v1.11.0

def export(model, args, f, export_params=True, verbose=False, training=None,
           input_names=None, output_names=None, operator_export_type=None,
           opset_version=None, do_constant_folding=True, dynamic_axes=None,
           keep_initializers_as_inputs=None, custom_opsets=None,
           export_modules_as_functions=False)

      参数介绍:
      (1).前三个必选参数为模型、模型输入、导出的onnx文件名。
      (2).exprot_params:模型中是否存储模型权重。一般中间表示包含两大类信息:模型结构和模型权重,这两类信息可以在同一个文件里存储,也可以分文件存储。ONNX是用同一个文件表示记录模型的结构和权重。部署时一般都默认这个参数为 True。如果onnx文件是用来在不同框架间传递模型(比如PyTorch到Tensorflow)而不是用于部署,则可以令这个参数为False。
      (3).input_names, output_names:设置输入和输出张量的名称。如果不设置的话,会自动分配一些简单的名字(如数字)。ONNX模型的每个输入和输出张量都有一个名字。很多推理引擎在运行ONNX文件时,都需要以"名称--张量值"的数据对来输入数据,并根据输出张量的名称来获取输出数据。在进行跟张量有关的设置(比如添加动态维度)时,也需要知道张量的名字。在实际的部署流水线中,我们都需要设置输入和输出张量的名称,并保证ONNX和推理引擎中使用同一套名称。
      (4).opset_version:转换时参考哪个ONNX算子集版本,在PyTorch 1.11.0版本中,默认值为9。
      (5).dynamic_axes:指定输入输出张量的哪些维度是动态的。为了追求效率,ONNX默认所有参与运算的张量都是静态的(张量的形状不发生改变)。但在实际应用中,我们又希望模型的输入张量是动态的,尤其是本来就没有形状限制的全卷积模型。因此,我们需要显式地指明输入输出张量的哪几个维度的大小是可变的。

      ONNX介绍https://blog.csdn.net/fengbingchun/article/details/125947000
      ONNX在底层是用Protobuf定义的。Protobuf,全称Protocol Buffer,是Google提出的一套表示和序列化数据的机制。一个ONNX模型可以用ModelProto类表示。ModelProto包含了版本、创建者等日志信息,还包含了存储计算图结构的graph。GraphProto类则由输入张量信息、输出张量信息、节点信息组成。张量信息ValueInfoProto类包括张量名、基本数据类型、形状。节点信息NodeProto类包含了算子名、算子输入张量名、算子输出张量名。
      ONNX中的onnx.utils.extract_model()可以从原模型中取出部分节点,和新定义的输入、输出边构成一个新的子模型。利用子模型提取功能,我们可以输出原ONNX模型的中间结果,实现对ONNX模型的调试。

      安装:使用conda安装一个mmdeploy的虚拟环境,ONNX Runtime仅支持CPU,TensorRT仅支持CUDA
      (1).创建mmdeploy虚拟环境:

conda create --name mmdeploy python=3.8
conda activate mmdeploy

      (2).安装PyTorch:这里PyTorch使用1.11.0版本,CUDA使用10.2版本,此CUDA版本对PyTorch各版本都支持

conda install pytorch==1.11.0 torchvision==0.12.0 torchaudio==0.11.0 cudatoolkit=10.2 -c pytorch

      (3).安装MMCV:mmcv-full 1.5.0版本

pip install mmcv-full==1.5.0 -f https://download.openmmlab.com/mmcv/dist/cu102/torch1.11.0/index.html

      (4).安装MMDeploy:从https://github.com/open-mmlab/mmdeploy/releases下载mmdeploy-0.8.0-linux-x86_64-onnxruntime1.8.1.tar.gz,解压缩后进入到mmdeploy-0.8.0-linux-x86_64-onnxruntime1.8.1目录下,执行:

pip install dist/mmdeploy-0.8.0-py3-none-linux_x86_64.whl
pip install sdk/python/mmdeploy_python-0.8.0-cp38-none-linux_x86_64.whl

      (5).安装ONNX Runtime推理引擎:安装1.8.1版本

pip install onnxruntime==1.8.1

      (6).若用到OpenMMLab中的其它工具箱还需要进行安装,如安装MMDetection 2.25.1

pip install mmdet==2.25.1

      在linux上通过源码编译mmdeploy要求
      (1).安装cmake:版本>=3.14.0;
      (2).安装gcc 7+:mmdeploy sdk中使用了C++17特性,因此需要安装gcc 7+以上的版本;
      (3).安装依赖包:conda、pytorch(>=1.8.0)、mmcv-full;
      (4).安装mmdeploy sdk依赖:opencv(>=3.0)、pplcv(可选,仅cuda下需要);
      (5).安装推理引擎:onnxruntime(>=1.8.1)、tensorrt(要保证和你机器的cpu架构及cuda版本是匹配的)、cudnn(要保证和你机器的cpu架构、cuda版本及tensorrt版本是匹配的)、ppl.nn、openvino、ncnn、libtorch、cann。

     使用MMDeploy中的工具tools/deploy.py,将OpenMMLab的PyTorch模型转换成推理后端ONNX Runtime支持的ONNX格式

     (1).MMDetection中的模型使用 https://blog.csdn.net/fengbingchun/article/details/126199218 中测试用的faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth;

     (2).将执行命令写在mmdeploy_mmdetection_to_onnx_build.sh中,如下:

#! /bin/bash

python ../../src/mmdeploy/tools/deploy.py \
    ../../src/mmdeploy/configs/mmdet/detection/detection_onnxruntime_dynamic.py \
    ../../src/mmdetection/configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py \
    http://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
    ../../data/image/1.jpg \
    --work-dir ../../data/model \
    --device cpu \
    --show

     (3).直接执行会报error:onnxruntime.capi.onnxruntime_pybind11_state.Fail: [ONNXRuntimeError] : 1 : FAIL : Failed to load library ~/Disk/anaconda3/envs/mmdeploy/lib/python3.8/site-packages/mmdeploy/lib/libmmdeploy_onnxruntime_ops.so with error: libonnxruntime.so.1.8.1: cannot open shared object file: No such file or directory,找不到libonnxruntime.so.1.8.1,虽然配置环境时执行了pip install onnxruntime==1.8.1,但在相关目录下搜索确实没有此库,解决方法:从https://github.com/microsoft/onnxruntime/releases 中下载onnxruntime-linux-x64-1.8.1.tgz,解压缩;并将压缩后的目录onnxruntime-linux-x64-1.8.1拷贝到mmdeploy环境下的~/Disk/anaconda3/envs/mmdeploy/目录下,然后在执行:

export LD_LIBRARY_PATH=~/Disk/anaconda3/envs/mmdeploy/onnxruntime-linux-x64-1.8.1/lib:${LD_LIBRARY_PATH}
./mmdeploy_mmdetection_to_onnx_build.sh

     (4).执行完上述命令后,会显示一样的两幅检测结果图,一个是pytorch的,一个是onnxruntime的,如下图所示:原始图像来自于网络

      并在../../data/model目录下产生onnx文件end2end.onnx。终端部分输出结果如下图所示:

      GitHub: https://github.com/fengbingchun/PyTorch_Test

有关开源深度学习模型部署工具箱MMDeploy简介及安装的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby - 完全离线安装RVM - 2

    我打算为ruby​​脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn

  5. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  6. ruby-on-rails - rails 目前在重启后没有安装 - 2

    我有一个奇怪的问题:我在rvm上安装了ruby​​onrails。一切正常,我可以创建项目。但是在我输入“railsnew”时重新启动后,我有“程序'rails'当前未安装。”。SystemUbuntu12.04ruby-v"1.9.3p194"gemlistactionmailer(3.2.5)actionpack(3.2.5)activemodel(3.2.5)activerecord(3.2.5)activeresource(3.2.5)activesupport(3.2.5)arel(3.0.2)builder(3.0.0)bundler(1.1.4)coffee-rails(

  7. ruby - 如何为 emacs 安装 ruby​​-mode - 2

    我刚刚为fedora安装了emacs。我想用emacs编写ruby。为ruby​​提供代码提示、代码完成类型功能所需的工具、扩展是什么? 最佳答案 ruby-mode已经包含在Emacs23之后的版本中。不过,它也可以通过ELPA获得。您可能感兴趣的其他一些事情是集成RVM、feature-mode(Cucumber)、rspec-mode、ruby-electric、inf-ruby、rinari(用于Rails)等。这是我当前用于Ruby开发的Emacs配置:https://github.com/citizen428/emacs

  8. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  9. ruby-on-rails - 无法在centos上安装therubyracer(V8和GCC出错) - 2

    我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e

  10. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

随机推荐