【mmdeploy】让openmmlab带我走深度学习最后一公里,实现模型部署及终端推理。从模型转换,量化模型开始,小小的参数,大大的变化

  • 如何将模型从pytorch形式转换成其他后端形式,准备工作

    • 安装目标后端。

    • 安装目标代码库。

  • 使用方法

    • python ./tools/deploy.py \
          ${DEPLOY_CFG_PATH} \
          ${MODEL_CFG_PATH} \
          ${MODEL_CHECKPOINT_PATH} \
          ${INPUT_IMG} \
          --test-img ${TEST_IMG} \
          --work-dir ${WORK_DIR} \
          --calib-dataset-cfg ${CALIB_DATA_CFG} \
          --device ${DEVICE} \
          --log-level INFO \
          --show \
          --dump-info
      
  • 参数描述

      • deploy_cfg : mmdeploy 针对此模型的部署配置,包含推理框架类型、是否量化、输入 shape 是否动态等。

      • model_cfg : mm 算法库的模型配置,例如 mmpretrain/configs/vision_transformer/vit-base-p32_ft-64xb64_in1k-384.py,与 mmdeploy 的路径无关。

      • checkpoint : torch 模型路径。可以 http/https 开头,详见 mmcv.FileClient 的实现。

      • img : 模型转换时,用做测试的图像或点云文件路径。

      • --test-img : 用于测试模型的图像文件路径。默认设置成None

      • --work-dir : 工作目录,用来保存日志和模型文件。

      • --calib-dataset-cfg : 此参数只有int8模式下生效,用于校准数据集配置文件。若在int8模式下未传入参数,则会自动使用模型配置文件中的’val’数据集进行校准。

      • --device : 用于模型转换的设备。 默认是cpu,对于 trt 可使用 cuda:0 这种形式。

      • --log-level : 设置日记的等级,选项包括'CRITICAL', 'FATAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'。 默认是INFO

      • --show : 是否显示检测的结果。

      • --dump-info : 是否输出 SDK 信息。

  • 如何查找pytorch模型对应的部署配置文件

    • 在 configs/ 文件夹中找到模型对应的代码库文件夹。

    • 根据模型的任务类型在 configs/codebase_folder/ 下查找对应的文件夹。

    • 在 configs/codebase_folder/task_folder/ 下找到模型的部署配置文件。

    • ## 示例
      python ./tools/deploy.py \
          configs/mmdet/detection/detection_tensorrt_dynamic-320x320-1344x1344.py \
          $PATH_TO_MMDET/configs/yolo/yolov3_d53_8xb8-ms-608-273e_coco.py \
          $PATH_TO_MMDET/checkpoints/yolo/yolov3_d53_mstrain-608_273e_coco_20210518_115020-a2c3acb8.pth \
          $PATH_TO_MMDET/demo/demo.jpg \
          --work-dir work_dir \
          --show \
          --device cuda:0
      
  • ONNX 配置描述了如何将PyTorch模型转换为ONNX模型。ONNX配置参数说明

      • type: 配置类型。 默认为 onnx

      • export_params: 如果指定,将导出模型所有参数。如果您只想导出未训练模型将此项设置为 False

      • keep_initializers_as_inputs: 如果为 True,则所有初始化器(通常对应为参数)也将作为输入导出,添加到计算图中。 如果为 False,则初始化器不会作为输入导出,不添加到计算图中,仅将非参数输入添加到计算图中。

      • opset_version: ONNX的算子集版本,默认为11

      • save_file: 输出ONNX模型文件。

      • input_names: 模型计算图中输入节点的名称。

      • output_names: 模型计算图中输出节点的名称。

      • input_shape: 模型输入张量的高度和宽度。

    • onnx_config = dict(
          type='onnx',
          export_params=True,
          keep_initializers_as_inputs=False,
          opset_version=11,
          save_file='end2end.onnx',
          input_names=['input'],
          output_names=['output'],
          input_shape=None)
      
  • 如果模型要求动态尺寸的输入和输出,您需要在ONNX配置中加入dynamic_axes配置。dynamic_axes: 描述输入和输出的维度信息。

    •     dynamic_axes={
              'input': {
                  0: 'batch',
                  2: 'height',
                  3: 'width'
              },
              'dets': {
                  0: 'batch',
                  1: 'num_dets',
              },
              'labels': {
                  0: 'batch',
                  1: 'num_dets',
              },
          }
      
  • 代码库配置参数说明:type: OpenMMLab 系列模型代码库的简称, 包括 mmpretrain, mmdet, mmseg, mmocr, mmagictask: OpenMMLab 系列模型任务类型, 具体请参考 OpenMMLab 系列模型任务列表。

    • codebase_config = dict(type='mmpretrain', task='Classification')
      
  • 推理框架配置主要用于指定模型运行在哪个推理框架,并提供模型在推理框架运行时所需的信息,具体参考 ONNX Runtime, TensorRT, ncnn, PPLNN。type: 模型推理框架, 包括 onnxruntime, ncnn, pplnn, tensorrt, openvino

    • backend_config = dict(
          type='tensorrt',
          common_config=dict(
              fp16_mode=False, max_workspace_size=1 << 30),
          model_inputs=[
              dict(
                  input_shapes=dict(
                      input=dict(
                          min_shape=[1, 3, 512, 1024],
                          opt_shape=[1, 3, 1024, 2048],
                          max_shape=[1, 3, 2048, 2048])))
          ])
      
  • 部署配置完整示例

    • codebase_config = dict(type='mmpretrain', task='Classification')
      backend_config = dict(
          type='tensorrt',
          common_config=dict(
              fp16_mode=False,
              max_workspace_size=1 << 30),
          model_inputs=[
              dict(
                  input_shapes=dict(
                      input=dict(
                          min_shape=[1, 3, 224, 224],
                          opt_shape=[4, 3, 224, 224],
                          max_shape=[64, 3, 224, 224])))])
      
      onnx_config = dict(
          type='onnx',
          dynamic_axes={
              'input': {
                  0: 'batch',
                  2: 'height',
                  3: 'width'
              },
              'output': {
                  0: 'batch'
              }
          },
          export_params=True,
          keep_initializers_as_inputs=False,
          opset_version=11,
          save_file='end2end.onnx',
          input_names=['input'],
          output_names=['output'],
          input_shape=[224, 224])
      
  • 模型转换结束后,MMDeploy 提供了 tools/test.py 做为单测工具。需要参照 安装说明 完成依赖安装 ,按照 转换说明 转出模型。

    • python tools/test.py \
      ${DEPLOY_CFG} \
      ${MODEL_CFG} \
      --model ${BACKEND_MODEL_FILES} \
      [--speed-test] \
      [--warmup ${WARM_UP}] \
      [--log-interval ${LOG_INTERVERL}] \
      [--log2file ${LOG_RESULT_TO_FILE}]
      
  • 参数详解

    • 参数 备注
      deploy_cfg 部署配置文件
      deploy_cfg codebase 中的模型配置文件
      log2file 保存日志和运行文件的路径
      speed-test 是否做速度测试
      warm-up 执行前是否 warm-up
      log-interval 日志打印间隔
  • 执行模型推理(举例)

    • python tools/test.py \
          configs/mmpretrain/classification_onnxruntime_static.py \
          {MMPRETRAIN_DIR}/configs/resnet/resnet50_b32x8_imagenet.py \
          --model model.onnx \
          --out out.pkl \
          --device cuda:0  
      ## profile 速度测试
      python tools/test.py \
          configs/mmpretrain/classification_onnxruntime_static.py \
          {MMPRETRAIN_DIR}/configs/resnet/resnet50_b32x8_imagenet.py \
          --model model.onnx \
          --speed-test \
          --device cpu
      
  • 为什么要量化,相对于 fp32 模型,定点模型有诸多优点:

      • 体积更小,8-bit 模型可降低 75% 文件大小

      • 由于模型变小,Cache 命中率提升,速度更快

      • 芯片往往有对应的定点加速指令,这些指令更快、能耗更低(常见 CPU 上 int8 大约只需要 10% 能量)

    • 安装包体积、发热都是移动端评价 APP 的关键指标;而在服务端,“加速”意味着可以维持相同 QPS、增大模型换取精度提升。

  • mmdeploy 离线量化方案,mmdeploy 基于静态图(onnx)生成推理框架所需的量化表,再用后端工具把浮点模型转为定点。目前 mmdeploy 支持 ncnn PTQ。

  • 模型怎么转定点,mmdeploy 安装完成后,加载 ppq 并安装

    • git clone https://github.com/openppl-public/ppq.git
      cd ppq
      pip install -r requirements.txt
      python3 setup.py install
      
    • 回到 mmdeploy, 使用 tools/deploy.py --quant 选项开启量化。

    • cd /path/to/mmdeploy
      export MODEL_CONFIG=/path/to/mmpretrain/configs/resnet/resnet18_8xb16_cifar10.py
      export MODEL_PATH=https://download.openmmlab.com/mmclassification/v0/resnet/resnet18_b16x8_cifar10_20210528-bd6371c8.pth
      # 找一些 imagenet 样例图
      git clone https://github.com/nihui/imagenet-sample-images --depth=1
      # 量化模型
      python3 tools/deploy.py  configs/mmpretrain/classification_ncnn-int8_static.py  ${MODEL_CONFIG}  ${MODEL_PATH}   /path/to/self-test.png   --work-dir work_dir --device cpu --quant --quant-image-dir /path/to/imagenet-sample-images
      ...
      
      • –quant:是否开启量化,默认为 False

      • –quant-image-dir:校准数据集,默认使用 MODEL_CONFIG 中的验证集

  • 把 OpenMMLab 模型转 onnx 格式。

    • python tools/torch2onnx.py \
          ${DEPLOY_CFG} \
          ${MODEL_CFG} \
          ${CHECKPOINT} \
          ${INPUT_IMG} \
          --work-dir ${WORK_DIR} \
          --device cpu \
          --log-level INFO
      
    • 参数说明

        • deploy_cfg : The path of the deploy config file in MMDeploy codebase.

        • model_cfg : The path of model config file in OpenMMLab codebase.

        • checkpoint : The path of the model checkpoint file.

        • img : The path of the image file used to convert the model.

        • --work-dir : Directory to save output ONNX models Default is ./work-dir.

        • --device : The device used for conversion. If not specified, it will be set to cpu.

        • --log-level : To set log level which in 'CRITICAL', 'FATAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', 'NOTSET'. If not specified, it will be set to INFO.

  • MMDETECTION 模型部署

    • 安装 mmdet

    • 安装 mmdeploy

  • 模型转换

    • 你可以使用 tools/deploy.py 把 mmdet 模型一键式转换为推理后端模型。

    • cd mmdeploy
      # download faster r-cnn model from mmdet model zoo
      mim download mmdet --config faster-rcnn_r50_fpn_1x_coco --dest .
      # convert mmdet model to onnxruntime model with dynamic shape
      python tools/deploy.py \
          configs/mmdet/detection/detection_onnxruntime_dynamic.py \
          faster-rcnn_r50_fpn_1x_coco.py \
          faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth \
          demo/resources/det.jpg \
          --work-dir mmdeploy_models/mmdet/ort \
          --device cpu \
          --show \
          --dump-info
      
    • {task}:mmdet 任务有2种:物体检测(detection)、实例分割(instance-seg)。例如,RetinaNetFaster R-CNNDETR等属于前者。Mask R-CNNSOLO等属于后者。请务必使用 detection/detection_*.py 转换检测模型,使用 instance-seg/instance-seg_*.py 转换实例分割模型。

    • {backend}: 推理后端名称。比如,onnxruntime、tensorrt、pplnn、ncnn、openvino、coreml 等等

    • {precision}: 推理精度。比如,fp16、int8。不填表示 fp32

    • {static | dynamic}: 动态、静态 shape

    • {shape}: 模型输入的 shape 或者 shape 范围

  • 在使用转换后的模型进行推理之前,有必要了解转换结果的结构。 它存放在 --work-dir 指定的路路径下。

    • mmdeploy_models/mmdet/ort
      ├── deploy.json
      ├── detail.json
      ├── end2end.onnx
      └── pipeline.json
      
      • end2end.onnx: 推理引擎文件。可用 ONNX Runtime 推理

      • *.json: mmdeploy SDK 推理所需的 meta 信息

    • 整个文件夹被定义为mmdeploy SDK model。换言之,mmdeploy SDK model既包括推理引擎,也包括推理 meta 信息。

  • 以上述模型转换后的 end2end.onnx 为例,可以使用如下代码进行推理:

    • from mmdeploy.apis.utils import build_task_processor
      from mmdeploy.utils import get_input_shape, load_config
      import torch
      deploy_cfg = 'configs/mmdet/detection/detection_onnxruntime_dynamic.py'
      model_cfg = './faster-rcnn_r50_fpn_1x_coco.py'
      device = 'cpu'
      backend_model = ['./mmdeploy_models/mmdet/ort/end2end.onnx']
      image = './demo/resources/det.jpg'
      # read deploy_cfg and model_cfg
      deploy_cfg, model_cfg = load_config(deploy_cfg, model_cfg)
      # build task and backend model
      task_processor = build_task_processor(model_cfg, deploy_cfg, device)
      model = task_processor.build_backend_model(backend_model)
      # process input image
      input_shape = get_input_shape(deploy_cfg)
      model_inputs, _ = task_processor.create_input(image, input_shape)
      # do model inference
      with torch.no_grad():
          result = model.test_step(model_inputs)
      # visualize results
      task_processor.visualize(
          image=image,
          model=model,
          result=result[0],
          window_name='visualize',
          output_file='output_detection.png')
      
  • MMPOSE 模型部署

    • 安装 mmpose 安装 — MMPose 1.0.0 文档

    • 安装 mmdeploy

  • 模型转换

    • 可以使用 tools/deploy.py 把 mmpose 模型一键式转换为推理后端模型。以下,我们将演示如何把 hrnet 转换为 onnx 模型。

    • cd mmdeploy
      # download hrnet model from mmpose model zoo
      mim download mmpose --config td-hm_hrnet-w32_8xb64-210e_coco-256x192 --dest .
      # convert mmdet model to onnxruntime model with static shape
      python tools/deploy.py \
          configs/mmpose/pose-detection_onnxruntime_static.py \
          td-hm_hrnet-w32_8xb64-210e_coco-256x192.py \
          hrnet_w32_coco_256x192-c78dce93_20200708.pth \
          demo/resources/human-pose.jpg \
          --work-dir mmdeploy_models/mmpose/ort \
          --device cpu \
          --show
      
    • 转换的关键之一是使用正确的配置文件。项目中已内置了各后端部署配置文件。 文件的命名模式是:

    • pose-detection_{backend}-{precision}_{static | dynamic}_{shape}.py
      
      • {backend}: 推理后端名称。比如,onnxruntime、tensorrt、pplnn、ncnn、openvino、coreml 等等

      • {precision}: 推理精度。比如,fp16、int8。不填表示 fp32

      • {static | dynamic}: 动态、静态 shape

      • {shape}: 模型输入的 shape 或者 shape 范围

  • 模型规范

    • 在使用转换后的模型进行推理之前,有必要了解转换结果的结构。 它存放在 --work-dir 指定的路路径下。上例中的mmdeploy_models/mmpose/ort,结构如下:

    • mmdeploy_models/mmpose/ort
      ├── deploy.json
      ├── detail.json
      ├── end2end.onnx
      └── pipeline.json
      
  • 模型推理

    • 以上述模型转换后的 end2end.onnx 为例,你可以使用如下代码进行推理:

    • from mmdeploy.apis.utils import build_task_processor
      from mmdeploy.utils import get_input_shape, load_config
      import torch
      deploy_cfg = 'configs/mmpose/pose-detection_onnxruntime_static.py'
      model_cfg = 'td-hm_hrnet-w32_8xb64-210e_coco-256x192.py'
      device = 'cpu'
      backend_model = ['./mmdeploy_models/mmpose/ort/end2end.onnx']
      image = './demo/resources/human-pose.jpg'
      # read deploy_cfg and model_cfg
      deploy_cfg, model_cfg = load_config(deploy_cfg, model_cfg)
      # build task and backend model
      task_processor = build_task_processor(model_cfg, deploy_cfg, device)
      model = task_processor.build_backend_model(backend_model)
      # process input image
      input_shape = get_input_shape(deploy_cfg)
      model_inputs, _ = task_processor.create_input(image, input_shape)
      # do model inference
      with torch.no_grad():
          result = model.test_step(model_inputs)
      # visualize results
      task_processor.visualize(
          image=image,
          model=model,
          result=result[0],
          window_name='visualize',
          output_file='output_pose.png')
      

你可能感兴趣的:(树莓派,深度学习,python,mmdeploy,计算机视觉)