Paddle模型部署

2023-05-23  本文已影响0人  Mr_Michael

一、简介

飞桨(PaddlePaddle)以百度深度学习技术研究和业务应用为基础,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体的深度学习平台。

飞桨产品全景

1.训练模型库

PaddleHub旨在为开发者提供丰富的、高质量的、直接可用的预训练模型。飞桨的产业级模型库包含PaddleClas、PaddleDetection、PaddleSeg、PaddleOCR、PaddleGAN、PaddleVideo、PaddleNLP等方面。

模型库下载

1)PaddleDetection

PaddleDetection是一个基于PaddlePaddle的目标检测端到端开发套件,在提供丰富的模型组件和测试基准的同时,注重端到端的产业落地应用,帮助开发者实现数据准备、模型选型、模型训练、模型部署的全流程打通,快速进行落地应用。

不仅复现了常见的目标检测模型,还对模型的进行了图像增强、骨干网络优化、DropBlock,IoU Loss IoUAware等一系列深度优化。同时内置集成模型压缩能力,提供了一键式剪裁,蒸馏,量化的脚本,大大提高模型精度和速度,并减小模型体积。

优势:

2)PaddleClas

PaddleClas是飞桨为工业界和学术界所准备的一个图像识别和图像分类任务的工具集。支持多种前沿图像分类、识别相关算法,发布产业级特色骨干网络PP-HGNetPP-LCNetv2PP-LCNetSSLD半监督知识蒸馏方案等模型。

模型简介 应用场景
PULC 超轻量图像分类方案 固定图像类别分类方案
PP-ShituV2 轻量图像识别系统 针对场景数据类别频繁变动、类别数据多
PP-LCNet 轻量骨干网络 针对Intel CPU设备及MKLDNN加速库定制
PP-LCNetV2 轻量骨干网络 针对Intel CPU设备,适配OpenVINO
PP-HGNet 高精度骨干网络 GPU设备上相同推理时间精度更高

3)PaddleOCR

PaddleOCR旨在打造一套丰富、领先、且实用的OCR工具库。最新开源的超轻量PP-OCRv3模型大小仅为16.2M。同时支持中英文识别;支持倾斜、竖排等多种方向文字识别;支持GPU、CPU预测;

模型简介 模型名称 推荐场景
中英文超轻量PP-OCRv3模型(16.2M) ch_PP-OCRv3_xx 移动端&服务器端
英文超轻量PP-OCRv3模型(13.4M) en_PP-OCRv3_xx 移动端&服务器端

2.推理部署

1)服务器部署

方案 硬件 API 语言 模型支持 适用场景
Paddle Inference 服务器(CPU、GPU) C++、Python、C、Go等 支持飞桨所有模型 适合直接应用,既可通过Python API对性能要求不太高的场景快速支持;也提供C++高性能接口,可与线上系统联编;并通过基础的C API可扩展支持更多语言的生产环境。
Paddle Serving 服务器(CPU、GPU) C++、Python、Go等 适用于将推理计算作为一个远程调用服务的场景,客户端发出请求,服务端返回推理结果。可支持多机部署。

Paddle Inference特点

Paddle Inference推理部署流程

  1. 导出模型文件。
    • 对于动态图模型,可以通过paddle.jit.save 接口来导出用于部署的标准化模型文件。
    • 对于静态图模型,可以使用paddle.static.save_inference_model保存模型。
  2. 配置推理选项。Config是飞桨提供的配置管理器API。在使用Paddle Inference进行推理部署过程中,需要使用Config详细地配置推理引擎参数,包括但不限于在何种设备(CPU/GPU)上部署、加载模型路径、开启/关闭计算图分析优化、使用MKLDNN/TensorRT进行部署的加速等。参数的具体设置需要根据实际需求来定。
  3. 创建PredictorPredictor是飞桨提供的推理引擎API。根据设定好的推理配置Config创建推理引擎Predictor,也就是推理引擎的一个实例。创建期间会进行模型加载、分析和优化等工作。
  4. 准备输入数据。准备好待输入推理引擎的数据,首先获得模型中每个输入的名称以及指向该数据块(CPU或GPU上)的指针,再根据名称将对应的数据块拷贝进Tensor。飞桨采用Tensor作为输入/输出数据结构,可以减少额外的拷贝,提升推理性能。
  5. 调用Predictor.Run()执行推理。
  6. 获取推理输出。与输入数据类似,根据输出名称将输出的数据(矩阵向量)由Tensor拷贝至(CPU或GPU上)以进行后续的处理。

Paddle Serving特点

2)端侧部署

方案 硬件 API 语言 适用场景
Paddle Lite 移动终端、嵌入式终端广泛硬件 C++、Python、Java等 适用于移动端/嵌入式芯片等端侧硬件中的高性能、轻量化部署。

Paddle Lite是飞桨自研的新一代端侧推理推理框架,支持PaddlePaddle/TensorFlow/Caffe/ONNX模型的推理部署,目前已经支持ARM CPU, Mali GPU, Adreno GPU, Huawei NPU等多种硬件,正在逐步增加X86 CPU, Nvidia GPU 等多款硬件。

Paddle Lite推理流程

Paddle Lite支持的模型

类别 类别细分 模型 支持平台
CV 分类 MobileNetV1 ARM,X86,NPU,RKNPU,APU
CV 分类 MobileNetV2 ARM,X86,NPU
CV 分类 ResNet18 ARM,NPU
CV 分类 ResNet50 ARM,X86,NPU,XPU
CV 分类 MnasNet ARM,NPU
CV 分类 EfficientNet* ARM
CV 分类 SqueezeNet ARM,NPU
CV 分类 ShufflenetV2* ARM
CV 分类 ShuffleNet ARM
CV 分类 InceptionV4 ARM,X86,NPU
CV 分类 VGG16 ARM
CV 分类 VGG19 XPU
CV 分类 GoogleNet ARM,X86,XPU
CV 检测 MobileNet-SSD ARM,NPU*
CV 检测 YOLOv3-MobileNetV3 ARM,NPU*
CV 检测 Faster RCNN ARM
CV 检测 Mask RCNN* ARM
CV 分割 Deeplabv3 ARM
CV 分割 UNet ARM
CV 人脸 FaceDetection ARM
CV 人脸 FaceBoxes* ARM
CV 人脸 BlazeFace* ARM
CV 人脸 MTCNN ARM
CV OCR OCR-Attention ARM
CV GAN CycleGAN* NPU
NLP 机器翻译 Transformer* ARM,NPU*
NLP 机器翻译 BERT XPU
NLP 语义表示 ERNIE XPU

二、安装PaddlePaddle

飞桨支持的GPU架构型号

快速安装

1.通过pip安装

# 根据CUDA版本选择安装

# cuda 11.2
python -m pip install paddlepaddle-gpu==2.4.2.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html
# CPU
python -m pip install paddlepaddle==2.4.2 -i https://pypi.tuna.tsinghua.edu.cn/simple

2.通过docker安装

docker hub paddlepaddle/paddle

# 拉取预安装 PaddlePaddle 的镜像
$ sudo docker pull registry.baidubce.com/paddlepaddle/paddle:2.4.2-gpu-cuda11.7-cudnn8.4-trt8.4
# $ sudo docker pull registry.baidubce.com/paddlepaddle/paddle:2.4.2-gpu-cuda11.2-cudnn8.2-trt8.0

# 进入Docker容器
$ nvidia-docker run --name paddle -it -v $PWD:/paddle registry.baidubce.com/paddlepaddle/paddle:2.4.2-gpu-cuda11.7-cudnn8.4-trt8.4 /bin/bash

# 测试paddle
$ paddle --version
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
grep: warning: GREP_OPTIONS is deprecated; please use an alias or script
PaddlePaddle 2.4.2.post117, compiled with
    with_avx: ON
    with_gpu: ON
    with_mkl: ON
    with_mkldnn: ON
    with_python: ON

# 容器中安装paddle2onnx
$ pip install paddle2onnx -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
$ paddle2onnx --version
[INFO]  paddle2onnx-1.0.6 with python>=3.6, paddlepaddle>=2.0.0

# 容器中安装paddleslim
$ pip install paddleslim  -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
$ pip list |grep paddleslim
paddleslim          2.4.1

三、模型部署SDK FastDeploy

随着人工智能的发展,新的算法模型层出不穷,各种AI硬件芯片也不断涌现。在实际算法落地中,也需要处理不同场景(服务器部署、服务化部署、嵌入式部署、手机端部署等),不同操作系统(Linux、Windows、Android、iOS等),不同编程语言(Python、C++等)。

为了解决AI部署落地难题,百度发布了新一代面向产业实践的推理部署工具FastDeploy,它是一款全场景、易用灵活、极致高效的AI推理部署工具,支持云端、移动端和边缘端部署。

特点

推理后端及能力

1.编译安装

https://github.com/PaddlePaddle/FastDeploy/tree/develop/docs/cn/build_and_install

1)python 预编译库安装

fastdeploy whl包

# 环境要求
CUDA >= 11.2
cuDNN >= 8.0
python >= 3.6

# gpu版本
pip install numpy opencv-python fastdeploy-gpu-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html
# cpu版本
pip install numpy opencv-python fastdeploy-python -f https://www.paddlepaddle.org.cn/whl/fastdeploy.html

2)python sdk编译安装

# 环境要求
gcc/g++ >= 5.4(推荐8.2)
cmake >= 3.18.0
python >= 3.6
cuda >= 11.2
cudnn >= 8.2

git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy/python
export ENABLE_ORT_BACKEND=ON
export ENABLE_PADDLE_BACKEND=ON
export ENABLE_OPENVINO_BACKEND=ON
export ENABLE_VISION=ON
export ENABLE_TEXT=ON
export ENABLE_TRT_BACKEND=ON
export WITH_GPU=ON
export TRT_DIRECTORY=/Paddle/TensorRT-8.4.1.5
export CUDA_DIRECTORY=/usr/local/cuda
# OPENCV_DIRECTORY可选,不指定会在编译过程下载FastDeploy预编译的OpenCV库
export OPENCV_DIRECTORY=/usr/lib/x86_64-linux-gnu/cmake/opencv4 \

python setup.py build
python setup.py bdist_wheel

3)c++ 预编译库安装

# g++ 8.2, CUDA 11.2, cuDNN 8.2编译产出
$ wget https://bj.bcebos.com/fastdeploy/release/cpp/fastdeploy-linux-x64-gpu-1.0.6.tgz
$ tar -zxvf fastdeploy-linux-x64-gpu-1.0.6.tgz

$ tree -L 3 fastdeploy-linux-x64-gpu-1.0.6
├── FastDeploy.cmake
├── FastDeployConfig.cmake
├── FastDeployCSharp.cmake
├── fastdeploy_init.sh
├── include # 头文件
│   ├── fastdeploy
│   │   ├── benchmark
│   │   ├── core
│   │   ├── encryption
│   │   │   ├── include
│   │   │   │   ├── decrypt.h
│   │   │   │   ├── encrypt.h
│   │   │   │   └── model_code.h
│   │   │   ├── src
│   │   │   └── util
│   │   ├── encryption.h
│   │   ├── fastdeploy_model.h
│   │   ├── function
│   │   │   ├── cast.h
│   │   │   ├── concat.h
│   │   │   ├── cuda_cast.h
│   │   │   ├── cumprod.h
│   │   │   ├── eigen.h
│   │   │   ├── ....
│   │   │   └── transpose.h
│   │   ├── pipeline
│   │   ├── pipeline.h
│   │   ├── pybind
│   │   ├── runtime
│   │   │   ├── backends
│   │   │   │   ├── backend.h
│   │   │   │   ├── common
│   │   │   │   ├── lite
│   │   │   │   ├── openvino
│   │   │   │   ├── ort
│   │   │   │   ├── paddle
│   │   │   │   ├── poros
│   │   │   │   ├── rknpu2
│   │   │   │   ├── sophgo
│   │   │   │   └── tensorrt
│   │   │   ├── enum_variables.h
│   │   │   ├── runtime.h
│   │   │   └── runtime_option.h
│   │   ├── runtime.h
│   │   ├── text
│   │   ├── text.h
│   │   ├── utils
│   │   ├── vision
│   │   │   ├── classification
│   │   │   ├── common
│   │   │   ├── detection
│   │   │   ├── facealign
│   │   │   ├── facedet
│   │   │   ├── faceid
│   │   │   ├── generation
│   │   │   ├── headpose
│   │   │   ├── keypointdet
│   │   │   ├── matting
│   │   │   ├── ocr
│   │   │   ├── segmentation
│   │   │   ├── sr
│   │   │   ├── tracking
│   │   │   ├── utils
│   │   │   └── visualize
│   │   └── vision.h
│   ├── fastdeploy_capi
│   │   ├── core
│   │   ├── internal
│   │   ├── runtime
│   │   ├── vision
│   │   └── vision.h
│   └── onnx
│       ├── backend
│       ├── bin
│       ├── checker.h
│       ├── common
│       ├── defs
│       ├── examples
│       ├── frontend
│       ├── ......
│       ├── test
│       ├── tools
│       └── version_converter
├── lib # fastdeploy动态库【已编译】
│   ├── libfastdeploy.so -> libfastdeploy.so.1.0.6
│   ├── libfastdeploy.so.1.0.6
│   └── libonnxifi.so
├── lib64
│   ├── cmake
│   │   └── ONNX
│   ├── libonnx.a
│   ├── libonnxifi_dummy.so
│   ├── libonnxifi_loader.a
│   └── libonnx_proto.a
├── LICENSE
├── openmp.cmake
├── summary.cmake
├── third_libs  # 第三方库依赖【已编译】
│   └── install
│       ├── fast_tokenizer
│       │   ├── commit.log
│       │   ├── FastTokenizer.cmake
│       │   ├── include
│       │   ├── lib
│       │   └── third_party
│       ├── onnxruntime     # 推理后端
│       │   ├── include
│       │   └── lib
│       ├── opencv
│       │   ├── bin
│       │   ├── include
│       │   ├── lib64
│       │   └── share
│       ├── openvino        # 推理后端
│       │   └── runtime
│       │       ├── 3rdparty
│       │       ├── cmake
│       │       ├── include
│       │       └── lib
│       ├── paddle_inference    # 用于paddle模型的服务器端推理
│       │   ├── CMakeCache.txt
│       │   ├── paddle
│       │   │   ├── extension.h
│       │   │   ├── include
│       │   │   │   ├── crypto
│       │   │   │   ├── paddle_api.h
│       │   │   │   ├── paddle_inference_api.h
│       │   │   │   ├── ......
│       │   │   └── lib
│       │   │       └── libpaddle_inference.so
│       │   ├── third_party # paddle_inference依赖的第三方库【已编译】
│       │   │   ├── externalError
│       │   │   │   └── data
│       │   │   ├── install
│       │   │   │   ├── cryptopp
│       │   │   │   ├── gflags
│       │   │   │   ├── glog
│       │   │   │   ├── mkldnn
│       │   │   │   ├── mklml
│       │   │   │   ├── protobuf
│       │   │   │   ├── utf8proc
│       │   │   │   └── xxhash
│       │   │   └── threadpool
│       │   │       └── ThreadPool.h
│       │   └── version.txt
│       └── tensorrt        # 推理后端
│           └── lib
├── ThirdPartyNotices.txt
├── utils
│   └── gflags.cmake
├── utils.cmake
└── VERSION_NUMBER

4)c++ sdk编译安装

# 前置依赖
- gcc/g++ >= 5.4(推荐8.2)
- cmake >= 3.18.0
- cuda >= 11.2
- cudnn >= 8.2

sudo apt-get install libopencv-dev

git clone https://github.com/PaddlePaddle/FastDeploy.git
cd FastDeploy
mkdir build && cd build
cmake .. -DENABLE_ORT_BACKEND=ON \
         -DENABLE_PADDLE_BACKEND=ON \
         -DENABLE_OPENVINO_BACKEND=ON \
         -DENABLE_TRT_BACKEND=ON \
         -DWITH_GPU=ON \
         -DTRT_DIRECTORY=/Paddle/TensorRT-8.4.1.5 \
         -DCUDA_DIRECTORY=/usr/local/cuda \
         -DCMAKE_INSTALL_PREFIX=${PWD}/compiled_fastdeploy_sdk \
         -DENABLE_VISION=ON \
         -DOPENCV_DIRECTORY=/usr/lib/x86_64-linux-gnu/cmake/opencv4 \
         -DENABLE_TEXT=ON
make -j12
make install

# Run cpack to generate a .deb package 【可选】
cpack -G DEB
# Install .deb package
dpkg -i xxx.deb

5)编译选项说明

选项 说明
ENABLE_ORT_BACKEND 默认OFF, 是否编译集成ONNX Runtime后端(CPU/GPU上推荐打开)
ENABLE_PADDLE_BACKEND 默认OFF,是否编译集成Paddle Inference后端(CPU/GPU上推荐打开)
ENABLE_LITE_BACKEND 默认OFF,是否编译集成Paddle Lite后端(编译Android库时需要设置为ON)
ENABLE_RKNPU2_BACKEND 默认OFF,是否编译集成RKNPU2后端(RK3588/RK3568/RK3566上推荐打开)
ENABLE_SOPHGO_BACKEND 默认OFF,是否编译集成SOPHGO后端, 当在SOPHGO TPU上部署时,需要设置为ON
WITH_ASCEND 默认OFF,当在华为昇腾NPU上部署时, 需要设置为ON
WITH_KUNLUNXIN 默认OFF,当在昆仑芯XPU上部署时,需设置为ON
WITH_TIMVX 默认OFF,需要在RV1126/RV1109/A311D上部署时,需设置为ON
ENABLE_TRT_BACKEND 默认OFF,是否编译集成TensorRT后端(GPU上推荐打开)
ENABLE_OPENVINO_BACKEND 默认OFF,是否编译集成OpenVINO后端(CPU上推荐打开)
ENABLE_VISION 默认OFF,是否编译集成视觉模型的部署模块
ENABLE_TEXT 默认OFF,是否编译集成文本NLP模型的部署模块
WITH_GPU 默认OFF, 当需要在GPU上部署时,需设置为ON
RKNN2_TARGET_SOC ENABLE_RKNPU2_BACKEND时才需要使用这个编译选项。无默认值, 可输入值为RK3588/RK356X, 必须填入,否则 将编译失败
CUDA_DIRECTORY 默认/usr/local/cuda, 当需要在GPU上部署时,用于指定CUDA(>=11.2)的路径
TRT_DIRECTORY 当开启TensorRT后端时,必须通过此开关指定TensorRT(>=8.4)的路径
ORT_DIRECTORY 当开启ONNX Runtime后端时,用于指定用户本地的ONNX Runtime库路径;如果不指定,编译过程会自动下载ONNX Runtime库
OPENCV_DIRECTORY 当ENABLE_VISION=ON时,用于指定用户本地的OpenCV库路径;如果不指定,编译过程会自动下载OpenCV库
OPENVINO_DIRECTORY 当开启OpenVINO后端时, 用于指定用户本地的OpenVINO库路径;如果不指定,编译过程会自动下载OpenVINO库

2.Python SDK使用

1)常用Python API

Python API文档

# fastdeploy.RuntimeOption API 后端配置
    set_model_path
    
    use_ascend
    use_cpu
        set_cpu_thread_num
    use_gpu
    
    use_paddle_infer_backend
    use_openvino_backend
    use_ort_backend
    use_trt_backend                 # Use TensorRT inference
        enable_trt_fp16
        enable_paddle_to_trt    # Use Paddle-TensorRT inference
        set_trt_cache_file      # 通过加载保存的缓存,可以快速完成模型加载初始化。

# fastdeploy.Runtime API 多后端推理引擎API
    get_input_info
    get_output_info
    num_inputs
    num_outputs
    infer
    
# Vision Processor (图像预处理库) 
    fastdeploy.vision.common.processors.ResizeByShort
    fastdeploy.vision.common.processors.Resize
    fastdeploy.vision.common.processors.CenterCrop
    fastdeploy.vision.common.processors.Cast
    fastdeploy.vision.common.processors.HWC2CHW
    fastdeploy.vision.common.processors.Normalize
    fastdeploy.vision.common.processors.NormalizeAndPermute
    fastdeploy.vision.common.processors.Pad
    fastdeploy.vision.common.processors.PadToSize
    fastdeploy.vision.common.processors.StridePad

# fastdeploy vision Model API  视觉任务模型API
    fastdeploy.vision.detection.PPYOLOE
    fastdeploy.vision.detection.YOLOv5
        preprocessor
        predict
        batch_predict
        postprocessor

2)Python 推理后端使用

Runtime Python使用示例

Deploy Paddle model with Paddle Inference(CPU/GPU)、TensorRT(GPU)、OpenVINO(CPU)、ONNX Runtime(CPU/GPU)

Deploy ONNX model with TensorRT(GPU)、OpenVINO(CPU)、ONNX Runtime(CPU/GPU)

示例1:

# Deploy Paddle model with Paddle Inference(CPU/GPU)
import fastdeploy as fd
import numpy as np

# 下载模型并解压
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.tgz"
fd.download_and_decompress(model_url)

option = fd.RuntimeOption()
option.set_model_path("mobilenetv2/inference.pdmodel",
                      "mobilenetv2/inference.pdiparams")
# **** CPU 配置 ****
option.use_cpu()
option.use_paddle_infer_backend()
option.set_cpu_thread_num(12)
# **** GPU 配置 ***
# 如需使用GPU,使用如下注释代码
# option.use_gpu(0)
# **** IPU 配置 ***
# 如需使用IPU,使用如下注释代码
# option.use_ipu()

# 初始化构造runtime
runtime = fd.Runtime(option)
# 获取模型输入名
input_name = runtime.get_input_info(0).name

# 构造随机数据进行推理
results = runtime.infer({
    input_name: np.random.rand(1, 3, 224, 224).astype("float32")
})
print(results[0].shape)

示例2:

#   Deploy ONNX model with TensorRT(GPU)
import fastdeploy as fd
from fastdeploy import ModelFormat
import numpy as np

# 下载模型并解压
model_url = "https://bj.bcebos.com/fastdeploy/models/mobilenetv2.onnx"
fd.download(model_url, path=".")

option = fd.RuntimeOption()
option.set_model_path("mobilenetv2.onnx", model_format=ModelFormat.ONNX)
# **** GPU 配置 ***
option.use_gpu(0)
option.use_trt_backend()

# 初始化构造runtime
runtime = fd.Runtime(option)
# 获取模型输入名
input_name = runtime.get_input_info(0).name

# 构造随机数据进行推理
results = runtime.infer({
    input_name: np.random.rand(1, 3, 224, 224).astype("float32")
})
print(results[0].shape)

3)使用预置视觉网络推理

FastDeploy/examples/vision

示例1:yolov5

import fastdeploy as fd
import cv2

# 配置runtime,加载模型
option = fd.RuntimeOption()
option.use_trt_backend()
option.set_trt_input_shape("images", [1, 3, 640, 640])
model = fd.vision.detection.YOLOv5(
    "yolov5-model.pdmodel",
    "yolov5-model.pdiparams",
    runtime_option=option,
    model_format=fd.ModelFormat.PADDLE)

# 预测图片检测结果
im = cv2.imread(image)
result = model.predict(im)
print(result)

# 预测结果可视化
vis_im = fd.vision.vis_detection(im, result)
cv2.imwrite("visualized_result.jpg", vis_im)

3.C++ SDK使用

1)C++ API

C++ API文档

2)C++ 推理后端使用

Runtime C++使用示例

示例1:Deploy Paddle model with Paddle Inference(CPU/GPU)

#include "fastdeploy/runtime.h"
#include <cassert>

namespace fd = fastdeploy;

int main(int argc, char* argv[]) {
  // Download from https://bj.bcebos.com/paddle2onnx/model_zoo/pplcnet.tar.gz
  std::string model_file = "pplcnet/inference.pdmodel";
  std::string params_file = "pplcnet/inference.pdiparams";

  // configure runtime
  // How to configure by RuntimeOption, refer its api doc for more information
  // https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1RuntimeOption.html
  fd::RuntimeOption runtime_option;
  runtime_option.SetModelPath(model_file, params_file);
  runtime_option.UseCpu();
 
  // If need to configure Paddle Inference backend for more option, we can configure runtime_option.paddle_infer_option
  // refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1PaddleBackendOption.html
  runtime_option.paddle_infer_option.enable_mkldnn = true;

  fd::Runtime runtime;
  assert(runtime.Init(runtime_option));

  // Get model's inputs information
  // API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1Runtime.html
  std::vector<fd::TensorInfo> inputs_info = runtime.GetInputInfos();

  // Create dummy data fill with 0.5
  std::vector<float> dummy_data(1 * 3 * 224 * 224, 0.5);

  // Create inputs/outputs tensors
  std::vector<fd::FDTensor> inputs(inputs_info.size());
  std::vector<fd::FDTensor> outputs;

  // Initialize input tensors
  // API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1FDTensor.html
  inputs[0].SetData({1, 3, 224, 224}, fd::FDDataType::FP32, dummy_data.data());
  inputs[0].name = inputs_info[0].name;

  // Inference
  assert(runtime.Infer(inputs, &outputs));
 
  // Print debug information of outputs 
  outputs[0].PrintInfo();

  // Get data pointer and print it's elements
  const float* data_ptr = reinterpret_cast<const float*>(outputs[0].GetData());
  for (size_t i = 0; i < 10 && i < outputs[0].Numel(); ++i) {
    std::cout << data_ptr[i] << " ";
  }
  std::cout << std::endl;
  return 0;
}

示例2:

#include "fastdeploy/runtime.h"
#include <cassert>

namespace fd = fastdeploy;

int main(int argc, char* argv[]) {
  // Download from https://bj.bcebos.com/paddle2onnx/model_zoo/pplcnet.onnx
  std::string model_file = "pplcnet.onnx";

  // configure runtime
  // How to configure by RuntimeOption, refer its api doc for more information
  // https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1RuntimeOption.html
  fd::RuntimeOption runtime_option;
  runtime_option.SetModelPath(model_file, "", fd::ModelFormat::ONNX);
  runtime_option.UseTrtBackend();
  
  // Use NVIDIA GPU to inference
  // If need to configure TensorRT backend for more option, we can configure runtime_option.trt_option
  // refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1TrtBackendOption.html
  runtime_option.UseGpu(0);
  // Use float16 inference to improve performance
  runtime_option.trt_option.enable_fp16 = true;
  // Cache trt engine to reduce time cost in model initialize
  runtime_option.trt_option.serialize_file = "./model.trt";

  fd::Runtime runtime;
  assert(runtime.Init(runtime_option));

  // Get model's inputs information
  // API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1Runtime.html
  std::vector<fd::TensorInfo> inputs_info = runtime.GetInputInfos();

  // Create dummy data fill with 0.5
  std::vector<float> dummy_data(1 * 3 * 224 * 224, 0.5);

  // Create inputs/outputs tensors
  std::vector<fd::FDTensor> inputs(inputs_info.size());
  std::vector<fd::FDTensor> outputs;

  // Initialize input tensors
  // API doc refer https://baidu-paddle.github.io/fastdeploy-api/cpp/html/structfastdeploy_1_1FDTensor.html
  inputs[0].SetData({1, 3, 224, 224}, fd::FDDataType::FP32, dummy_data.data());
  inputs[0].name = inputs_info[0].name;

  // Inference
  assert(runtime.Infer(inputs, &outputs));
 
  // Print debug information of outputs 
  outputs[0].PrintInfo();

  // Get data pointer and print it's elements
  const float* data_ptr = reinterpret_cast<const float*>(outputs[0].GetData());
  for (size_t i = 0; i < 10 && i < outputs[0].Numel(); ++i) {
    std::cout << data_ptr[i] << " ";
  }
  std::cout << std::endl;
  return 0;
}

3)使用预置视觉网络推理

FastDeploy/examples/vision

示例1:yolov5 使用onnx模型

#include "fastdeploy/vision.h"

// onnxruntime cpu
void CpuInfer(const std::string& model_file, const std::string& image_file) {
  auto model = fastdeploy::vision::detection::YOLOv5(model_file);
  if (!model.Initialized()) {
    std::cerr << "Failed to initialize." << std::endl;
    return;
  }

  auto im = cv::imread(image_file);

  fastdeploy::vision::DetectionResult res;
  if (!model.Predict(&im, &res)) {
    std::cerr << "Failed to predict." << std::endl;
    return;
  }
  std::cout << res.Str() << std::endl;

  auto vis_im = fastdeploy::vision::VisDetection(im, res);
  cv::imwrite("vis_result.jpg", vis_im);
  std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
}

// onnxruntime gpu
void GpuInfer(const std::string& model_file, const std::string& image_file) {
  auto option = fastdeploy::RuntimeOption();
  option.UseGpu();
  auto model = fastdeploy::vision::detection::YOLOv5(model_file, "", option);
  if (!model.Initialized()) {
    std::cerr << "Failed to initialize." << std::endl;
    return;
  }

  auto im = cv::imread(image_file);

  fastdeploy::vision::DetectionResult res;
  if (!model.Predict(&im, &res)) {
    std::cerr << "Failed to predict." << std::endl;
    return;
  }
  std::cout << res.Str() << std::endl;

  auto vis_im = fastdeploy::vision::VisDetection(im, res);
  cv::imwrite("vis_result.jpg", vis_im);
  std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
}

void TrtInfer(const std::string& model_file, const std::string& image_file) {
  auto option = fastdeploy::RuntimeOption();
  option.UseGpu();
  option.UseTrtBackend();
  option.SetTrtInputShape("images", {1, 3, 640, 640});
  auto model = fastdeploy::vision::detection::YOLOv5(model_file, "", option);
  if (!model.Initialized()) {
    std::cerr << "Failed to initialize." << std::endl;
    return;
  }

  auto im = cv::imread(image_file);

  fastdeploy::vision::DetectionResult res;
  if (!model.Predict(&im, &res)) {
    std::cerr << "Failed to predict." << std::endl;
    return;
  }
  std::cout << res.Str() << std::endl;

  auto vis_im = fastdeploy::vision::VisDetection(im, res);
  cv::imwrite("vis_result.jpg", vis_im);
  std::cout << "Visualized result saved in ./vis_result.jpg" << std::endl;
}

int main(int argc, char* argv[]) {
  if (std::atoi(argv[3]) == 0) {
    CpuInfer(argv[1], argv[2]);
  } else if (std::atoi(argv[3]) == 1) {
    GpuInfer(argv[1], argv[2]);
  } else if (std::atoi(argv[3]) == 2) {
    TrtInfer(argv[1], argv[2]);
  }
  return 0;
}

4.FastDeploy 工具包

一键安装

# 通过pip安装fastdeploy-tools. 此工具包目前支持模型一键自动化压缩和模型转换的功能.
pip install fastdeploy-tools==0.0.1

1)模型压缩工具PaddleSlim

https://github.com/PaddlePaddle/PaddleSlim

PaddleSlim是一个专注于深度学习模型压缩的工具库,提供低比特量化、知识蒸馏、稀疏化和模型结构搜索等模型压缩策略,帮助开发者快速实现模型的小型化。

python -m pip install paddlepaddle-gpu==2.4.1.post112 -f https://www.paddlepaddle.org.cn/whl/linux/mkl/avx/stable.html

pip install paddleslim

自动化压缩

相比于传统手工压缩,自动化压缩的“自动”主要体现在4个方面:解耦训练代码、离线量化超参搜索、策略自动组合、硬件感知 (硬件延时预估)。

# 导入依赖包
import paddle
from PIL import Image
from paddle.vision.datasets import DatasetFolder
from paddle.vision.transforms import transforms
from paddleslim.auto_compression import AutoCompression
paddle.enable_static()
# 定义DataSet
class ImageNetDataset(DatasetFolder):
    def __init__(self, path, image_size=224):
        super(ImageNetDataset, self).__init__(path)
        normalize = transforms.Normalize(
            mean=[123.675, 116.28, 103.53], std=[58.395, 57.120, 57.375])
        self.transform = transforms.Compose([
            transforms.Resize(256),
            transforms.CenterCrop(image_size), transforms.Transpose(),
            normalize
        ])

    def __getitem__(self, idx):
        img_path, _ = self.samples[idx]
        return self.transform(Image.open(img_path).convert('RGB'))

    def __len__(self):
        return len(self.samples)

# 定义DataLoader
train_dataset = ImageNetDataset("./ILSVRC2012_data_demo/ILSVRC2012/train/")
image = paddle.static.data(
    name='inputs', shape=[None] + [3, 224, 224], dtype='float32')
train_loader = paddle.io.DataLoader(train_dataset, feed_list=[image], batch_size=32, return_list=False)
# 开始自动压缩
ac = AutoCompression(
    model_dir="./MobileNetV1_infer",
    model_filename="inference.pdmodel",
    params_filename="inference.pdiparams",
    save_dir="MobileNetV1_quant",
    config={"QuantPost": {}, "HyperParameterOptimization": {'ptq_algo': ['avg'], 'max_quant_count': 3}},
    ### config={"QuantAware": {}, "Distillation": {}}, ### 如果您的系统为Windows系统, 请使用当前这一行配置
    train_dataloader=train_loader,
    eval_dataloader=train_loader)
ac.compress()

量化过程划分:

量化方式:

2)模型转换工具X2Paddle

https://github.com/PaddlePaddle/X2Paddle

X2Paddle用于将其它深度学习框架的模型迁移至飞桨框架。目前支持推理模型的框架转换PyTorch训练代码迁移

# 环境依赖
python >= 3.5
paddlepaddle >= 2.2.2
tensorflow == 1.14 (如需转换TensorFlow模型)
onnx >= 1.6.0 (如需转换ONNX模型)
torch >= 1.5.0 (如需转换PyTorch模型)
paddlelite >= 2.9.0 (如需一键转换成Paddle-Lite支持格式,推荐最新版本)

# 安装
pip install x2paddle

PyTorch模型转换

from x2paddle.convert import pytorch2paddle
pytorch2paddle(module=torch_module,
               save_dir="./pd_model",
               jit_type="trace",
               input_examples=[torch_input])
# module (torch.nn.Module): PyTorch的Module。
# save_dir (str): 转换后模型的保存路径。
# jit_type (str): 转换方式。默认为"trace"。
# input_examples (list[torch.tensor]): torch.nn.Module的输入示例,list的长度必须与输入的长度一致。默认为None。

ONNX模型转换

x2paddle --framework=onnx \
        --model=onnx_model.onnx \
        --save_dir=pd_model

3)模型转换工具Paddle2ONNX

https://github.com/PaddlePaddle/Paddle2ONNX

Paddle2ONNX 支持将 PaddlePaddle 模型格式转化到 ONNX 模型格式。

# 安装
pip install paddle2onnx

# 命令行使用
paddle2onnx --model_dir saved_inference_model \
            --model_filename model.pdmodel \
            --params_filename model.pdiparams \
            --save_file model.onnx \
            --enable_dev_version True \
            --opset_version 11 \
            --enable_onnx_checker True

参数选项

参数 参数说明
--model_dir 配置包含 Paddle 模型的目录路径
--model_filename [可选] 配置位于 --model_dir 下存储网络结构的文件名
--params_filename [可选] 配置位于 --model_dir 下存储模型参数的文件名称
--save_file 指定转换后的模型保存目录路径
--opset_version [可选] 配置转换为 ONNX 的 OpSet 版本,目前支持 7~16 等多个版本,默认为 9
--enable_dev_version [可选] 是否使用新版本 Paddle2ONNX(推荐使用),默认为 True
--enable_onnx_checker [可选] 配置是否检查导出为 ONNX 模型的正确性, 建议打开此开关, 默认为 False
--enable_auto_update_opset [可选] 是否开启 opset version 自动升级功能,当低版本 opset 无法转换时,自动选择更高版本的 opset进行转换, 默认为 True
--deploy_backend [可选] 量化模型部署的推理引擎,支持 onnxruntime、tensorrt 或 others,当选择 others 时,所有的量化信息存储于 max_range.txt 文件中,默认为 onnxruntime
--save_calibration_file [可选] TensorRT 8.X版本部署量化模型需要读取的 cache 文件的保存路径,默认为 calibration.cache
--version [可选] 查看 paddle2onnx 版本
--external_filename [可选] 当导出的 ONNX 模型大于 2G 时,需要设置 external data 的存储路径,推荐设置为:external_data
--export_fp16_model [可选] 是否将导出的 ONNX 的模型转换为 FP16 格式,并用 ONNXRuntime-GPU 加速推理,默认为 False
--custom_ops [可选] 将 Paddle OP 导出为 ONNX 的 Custom OP,例如:--custom_ops '{"paddle_op":"onnx_op"},默认为 {}

Paddle 训练模型导出为 ONNX

import paddle

# export to ONNX
save_path = 'onnx.save/lenet' # 需要保存的路径
# 调用 paddle.static.InputSpec API 指定输入的 shape,如果输入中某一维为动态的,可以将该维指定为 None
x_spec = paddle.static.InputSpec([None, 1, 28, 28], 'float32', 'x') 
# 调用 paddle.onnx.export 接口,在指定的路径下生成 ONNX 模型。
paddle.onnx.export(model, save_path, input_spec=[x_spec], opset_version=11)

验证 ONNX 模型

# 导入 ONNX 库
import onnx
# 载入 ONNX 模型
onnx_model = onnx.load("model.onnx")
# 使用 ONNX 库检查 ONNX 模型是否合理
check = onnx.checker.check_model(onnx_model)
# 打印检查结果
print('check: ', check)


# 随机生成输入,用于验证 Paddle 和 ONNX 的推理结果是否一致
x = np.random.random((1, 3, 224, 224)).astype('float32')

# predict by ONNXRuntime
ort_sess = onnxruntime.InferenceSession("model.onnx")
ort_inputs = {ort_sess.get_inputs()[0].name: x}
ort_outs = ort_sess.run(None, ort_inputs)

四、精品模型部署

1.PP-YOLOE+

PP-YOLOE是基于PP-YOLOv2的卓越的单阶段Anchor-free模型,超越了多种流行的YOLO模型。PP-YOLOE+是PP-YOLOE的升级版本,从大规模的obj365目标检测预训练模型入手,在大幅提升收敛速度的同时,提升了模型在COCO数据集上的速度。同时,PP-YOLOE+大幅提升了包括数据预处理在内的端到端的预测速度。

1)环境及模型准备

git clone https://github.com/PaddlePaddle/PaddleDetection.git
cd PaddleDetection
# 安装PaddleDetection
pip install -r requirements.txt
python setup.py install

# 下载预训练模型
mkdir -p models/PP-YOLOE+_s && cd models/PP-YOLOE+_s
wget https://paddledet.bj.bcebos.com/models/ppyoloe_plus_crn_s_80e_coco.pdparams 
wget https://github.com/PaddlePaddle/PaddleDetection/blob/release/2.6/configs/ppyoloe/ppyoloe_plus_crn_s_80e_coco.yml
cd -

2)paddle源模型推理

# 推理单张图片
$ CUDA_VISIBLE_DEVICES=0 python tools/infer.py \
        -c configs/ppyoloe/ppyoloe_plus_crn_s_80e_coco.yml \
        -o weights=models/PP-YOLOE+_s/ppyoloe_plus_crn_s_80e_coco.pdparams \
        --infer_img=demo/000000014439_640x640.jpg

Detection bbox results save in output/000000014439_640x640.jpg

3)paddle模型转onnx

由于tensorrt转换时不支持nms相关算子,建议设置exclude_post_process为True,然后自行实现后处理(参考yolov8)。

# 模型微调,不包含nms,其会在tensorrt转换时因缺少TopK算子而报错
$ python tools/export_model.py -c configs/ppyoloe/ppyoloe_plus_crn_s_80e_coco.yml \
        -o weights=models/PP-YOLOE+_s/ppyoloe_plus_crn_s_80e_coco.pdparams \
        exclude_post_process=True trt=True

# 默认输出到output_inference
$ ls output_inference/ppyoloe_plus_crn_s_80e_coco/
infer_cfg.yml  model.pdiparams  model.pdiparams.info  model.pdmodel

# 转化成ONNX格式
$ paddle2onnx --model_dir output_inference/ppyoloe_plus_crn_s_80e_coco \
        --model_filename model.pdmodel \
        --params_filename model.pdiparams \
        --opset_version 11 \
        --enable_onnx_checker True \
        --save_file ppyoloe_plus_crn_s_80e_coco.onnx

4)onnx转tensorrt

trtexec="/usr/src/tensorrt/bin/trtexec"
$trtexec --onnx=./ppyoloe_plus_crn_s_80e_coco.onnx --saveEngine=./ppyoloe_s_bs1.engine  --fp16  --buildOnly --workspace=4096 
上一篇下一篇

猜你喜欢

热点阅读