想要模型部署玩得好,这些我们要知道!

2022-04-09 16:55:18 浏览数 (1)

时光如逝,岁月如梭,不知不觉,MMDeploy 陪大家走过一个季度了(此处应有熟悉的 BGM)。在过去的 3 个月中,MMDeploy 攒了些“瓷器活儿”,也从社区收集到不少问题,听到了一些声音。是时候可以和大家说一说,唠一唠了,咋唠呢?我们就按下面的内容一一展开吧~

初心

对于还不清楚 MMDeploy 是什么的新朋友们,可以阅读千行百业智能化落地,MMDeploy 助你一“部”到位,了解 MMDeploy 概貌(此处省略一千字)。

正如我们在部署教程中说的那样,工业界比较成熟的模型部署模式是:

而 MMDeploy 是上述模式的实现方法之一。

在技术选型时,我们的动机是:站在巨人的肩膀上,避免重复造轮子。比如 TensorRT、ppl.nn、ncnn 等等。

在设计阶段,我们定义了 MMDeploy 两个核心功能:模型转换、C/C 推理(即 SDK)。它们之间的关系如下图所示:

在实现方法上,大量使用了工厂模式和 Adapter 模式,做好模块封装,消除推理引擎、设备差异。

我们的出发点是:让用户有得选,避免一揽子操作。比如,用户可以仅选择转成 ONNX 中间格式;也可以选择导出想要的推理引擎文件,如 TensorRT engine;亦可以集成 MMDeploy SDK,从而完全避免写模型前处理、网络推理和后处理过程。

我们觉得,如此,用户便可结合自己的实际需求,有选择地使用 MMDeploy 的功能组件,最小化“侵入”已有项目或者产品,不一定非得切换部署框架。一些典型的、具体的用法我们会在下文中阐述。

进展

过去这 3 个月我们可没闲着哦。一方面,在扩充功能。另一方面,在写模型部署教程。我们的美好愿望是,通过前者“授予鱼”,通过后者“授人以渔”。我们一起来看看近期的进展吧~

设备

· 支持 NVIDIA Jetson 系列

某种程度上,算是集齐了 NVIDIA 全家桶。感兴趣的同学,可以移步安装说明手册。

平台

· 支持了 Windows 平台

这个工作花了一人月有余,远超预期。各种踩坑趟雷。啥都不说了,经验总结都在文档中了。这里,要特别感谢热心的社区同学对文档的 review 工作。

· 支持了 Android 平台,并开发了 Demo

主分支提供了 Android 下的构建教程。Android Demo 会在 4 月份,以另一个代码库的形式和大家见面。这里有份尝鲜版视频,供大家食用。

FFI

· SDK 封装了 Python 接口

玩转 python 的同学可以试用下,3、4行代码可以搞定模型推理哟。在下一章节会给出具体的例子。

算法库

· 支持了 MMPose、MMDetection3D

目前,MMDetection3D 模型部署暂只能通过 Model Converter 接口体验。如果需要集成 MMDeploy SDK 到你的项目,得再等一等。因为,这些模型的前后处理模块还没集成到 SDK,错过了 Q1 的末班车。

“新” IR

· 支持了 TorchScript

如果,你要问 TorchScript 是什么?看这里TorchScript 系列解读(一):初识 TorchScript。TorchScript 和 ONNX 啥关系?教程在路上。该怎么用呢?请关注代码库里的文档。记得戳戳 star 哟。

教程 & 技术文档

· 发布了 2 篇入门级教程

· 开始更新 TorchScript 解读系列

诚邀大家关注我们的微信公众号、知乎账号,第一时间获得相关推送。我们更欢迎大家参与进来,一起讨论编写教程,把部署这件事情讲清楚、讲透彻。

用法

MMDeploy 高度模块化。可以被当作一个整体,进行端到端的模型部署。也可以只使用其中的部分模块,灵活地服务自己的项目或者产品。比如:

1)使用 Model Converter 进行模型转换、推理。

适用场景:快速搭建模型部署 demo,验证部署结果的正确性。如下面的例子所示,输入匹配的部署配置、算法配置、checkpoint、图像、工作目录等,即可通过一条命令将 torch 模型转换为推理引擎要求的模型格式。目前,MMDeploy 支持了 6 种推理引擎:TensorRT、ONNXRuntime、PPL.NN、ncnn、OpenVINO 和 libtorch。

代码语言:javascript复制
# 将 MMDet 中的 Faster-RCNN 模型,转换为 TensorRT engine 格式
## ${MMDEPLOY_DIR}: git clone mmdeploy 后,源码存放的路径
## ${MMDET_DIR}: git clone mmdetection 后,源码存放的路径
## ${CHECKPOINT_DIR}: 存放 checkpoint 的目录
## ${INPUT_IMG}: 一张图像的路径
## ${WORK_DIR}: 用来存放转换结果的目录
python ${MMDEPLOY_DIR}/tools/deploy.py 
    ${MMDEPLOY_DIR}/configs/mmdet/detection/detection_tensorrt_dynamic-320x320-1344x1344.py 
    ${MMDET_DIR}/configs/faster_rcnn/faster_rcnn_r50_fpn_1x_coco.py 
    ${CHECKPOINT_DIR}/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth 
    ${INPUT_IMG} 
    --work-dir ${WORK_DIR} 
    --device cuda:0 
    --dump-info

2)使用 Model Converter 转换模型,集成 MMDeploy 算子库到自己项目中。

适用场景:比如,自己的项目中已经集成了 TensorRT 推理引擎。那么加载 MMDeploy 算子的动态库后,即可无缝读取 MMDeploy 转出的 TensorRT 模型。这种方式,在推理引擎为 ONNXRuntime 时,同样适用。

代码语言:javascript复制
# 1. 编译 TensorRT 自定义算子的动态库
cd ${MMDEPLOY_DIR}
mkdir -p build && cd build
cmake -DCMAKE_CXX_COMPILER=g  -7 -DMMDEPLOY_TARGET_BACKENDS=trt -DTENSORRT_DIR=${TENSORRT_DIR} -DCUDNN_DIR=${CUDNN_DIR} ..
make -j$(nproc)

# 2. 在你的项目中,加载自定义算子的动态库。在此之后,就是你的地盘啦
import ctypes
ctypes.CDLL("libmmdeploy_tensorrt_ops.so")

3)使用 Model Converter 导出 SDK Model,把 SDK 集成到自己的项目中。

适用场景:对于 latency 或者 throughput 要求高的情况。以检测为例,可以集成 C/C 接口、Python 接口。其他诸如分类器、分割器、文字检测识别等等,依此类推。

- 集成 C/C 接口

代码语言:javascript复制
auto sdk_model_path = "/the/work/dir/passed/to/deploy.py";
auto image_path = "/the/path/of/an/image";
auto device_name = "cuda";
auto device_id = 0;

// 创建检测器句柄
mm_handle_t detector{};
mmdeploy_detector_create_by_path(model_path, device_name, 0, &detector);

// 读取图像
cv::Mat img = cv::imread(image_path);

// 送入检测器进行推理
mm_mat_t mat{img.data, img.rows, img.cols, 3, MM_BGR, MM_INT8};
mm_detect_t *bboxes{};
int *res_count{};
mmdeploy_detector_apply(detector, &mat, 1, &bboxes, &res_count);

// 根据实际情况,处理 bboxes
// ...

// 销毁数据和句柄
mmdeploy_detector_release_result(bboxes, res_count, 1);
mmdeploy_detector_destroy(detector);

- 集成 Python 接口

代码语言:javascript复制
import cv2
import mmdeploy_python

sdk_model_path = '/the/work/dir/specified/via/deploy.py'
image_path = '/the/path/of/an/image'
device_name = 'cuda'
device_id = 0

img = cv2.imread(image_path)
detector = mmdeploy_python.Detector(sdk_model_path, device_name, device_id)
result = detector([img])
print(result)

除了上面典型的应用,大家也可以基于 MMDeploy 开发新的模块或者组件。比如,某个新算法的模型导出、推理引擎组件、算法的后处理模块、SDK Model 其他文件格式的读取模块等等,甚至好玩有趣的 App。有想法,肯行动,开源自己牛气的项目并非遥不可及。

计划

Q2 的计划,尽在下图中。

最后,还请大家多多关注 MMDeploy,加入我们的社群一起愉快的玩耍。期待大家的 star、issue 和 PR!

0 人点赞