1. 背景
学习深度学习时接触到PaddleX这个可视化工具,发现对于初学者非常简单易懂,一条龙创建数据集和训练,但是,对于深度学习部署的最后一公里:在目标平台上部署推理系统,却没有过多介绍,于是,自我摸索结合查询文档,完成使用PaddleX AI studio生成FastDeploy部署包在QT桌面程序上实现推理部署
2. 效果图
3. 实现步骤
1. 基本环境和概念介绍
PaddlePaddle,也称为飞桨,是一个深度学习平台,提供了完整的深度学习工具链,包括开发环境、模型库、训练框架、部署工具等。它支持动态图和静态图两种编程范式,并提供了丰富的API和工具,使得开发者可以更加便捷地进行深度学习应用开发和部署。
PaddleX是PaddlePaddle的扩展库,提供了更加丰富和灵活的深度学习工具和模块,方便开发者进行模型训练、预测、推理等任务。PaddleX提供了更加灵活的模型设计、更加高效的训练性能、更加便捷的部署工具,以及更加全面的硬件支持,使得开发者可以更加高效地进行深度学习应用开发和部署。
Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。
Qt的主要优势在于其跨平台特性,即一次编程,到处编译。这意味着开发者只需编写一次代码,就可以在多个平台上运行,无需进行大量的重复工作。此外,Qt还提供了大量的内置组件和工具,例如窗口、按钮、文本框等,这些组件和工具可以轻松地用于构建用户界面。
本文是在Windows上开发QT应用,关于QT的安装不再赘述,没有安装的自行搜索教程,注意,QT在Windows上的安装可能不是那么的”傻瓜式“,特别要注意编译器环境的设置,初次安装不要轻易放弃
2. Paddle AI studio介绍
官网
是Paddle的在线平台,和本地版本的优势是可以通过算力卡(每日签到可以获得)大幅提高训练速度(如果你没有本地显卡的话)
Paddle AI studio需要百度账号登录,可能还需要文心一言的账号,自行注册即可
3. 在Paddle AI studio中训练模型和生成部署包
1. 点击立即开发->开发模型
2. 选择模型,可以手动选择或搜索
3. 点击模型开发
4. 启动环境
5. 数据校验
如果没有自己准备的数据集的话,直接使用实例数据集,如何制作自定义数据集不在本文章讨论范畴
6. 模型训练和评估
依次点击开始即可
7. 导出离线部署包
依次点击 模型部署->导出离线部署包->按下图选择->获取离线部署包
8. 下载离线部署包
根据前一步设置的部署包路径,去开发者模式中选中文件,右键点击下载
9. 处理离线部署包
解压后的文件夹结构如下
FastDeploy-Windows-x86_64_CPU_Model_Name
├── README.md # 使用文档,介绍部署包整体情况
├── model # 导出的静态图预测模型文件
│ ├── inference.pdmodel # 模型结构文件
│ ├── inference.pdiparams # 模型参数文件
│ ├── inference.yml # 模型配置文件
│ ├── inference.pdiparams.info
├── example # 部署示例
├── fastdeploy-win-x64-0.0.0 # FastDeploy SDK
│ ├── libs # FastDeploy库文件
│ ├── include # FastDeploy头文件
│ ├── third_libs # FastDeploy第三方依赖
│ ├── fastdeploy_init.bat
│ ├── FastDeploy.cmake
│ ├── FastDeployConfig.cmake
│ ├── FastDeployCSharp.cmake
│ ├── LICENSE
│ ├── openmp.cmake
│ ├── summary.cmake
│ ├── ThirdPartyNotices.txt
│ ├── utils.cmake
1. 环境准备
在Windows上执行部署前,需要将FastDeploy依赖的库拷贝至可执行程序所在目录,或者配置环境变量。fastdeploy_init.bat脚本用于将所有依赖库拷贝至可执行程序所在目录
cd PATH-TO-YOUR\fastdeploy-win-x64-0.0.0
fastdeploy_init.bat install %cd% ..\example\build\Release
这里“..\example\build\Release"替换为你的项目的Release的生成目录
执行后会得到所有的依赖文件
10. 编写推理程序
用VS或者QtDesigner新建一个桌面Widget程序,放置一个菜单项用来打开目标图片文件夹,一个QListWidget用来显示文件夹内的所有文件,一个QLabel用来显示原图,两个QTextEdit用来显示信息,分别连接它们的信号和槽函数,由于QT不是本文档的重点,所以QT程序的设计不再赘述
重点在于Paddle推理库的引入
1. 将必须的文件拷贝到项目目录
1.1 将头文件和lib文件拷贝到项目目录
将刚才下载解压的fastDeploy包里面的如下文件夹拷贝到你的程序目录,位置随意,只要自己找得到就行
1.2 将依赖的库文件拷贝到程序执行目录
如上节描述,使用如下的命令拷贝依赖库文件到你的项目生成的Release目录(注意,只能放到Release目录,而不是Debug目录)
cd PATH-TO-YOUR\fastdeploy-win-x64-0.0.0
fastdeploy_init.bat install %cd% ..\example\build\Release
1.3 附加头文件设置
如下图设置附加头文件设置,把图片中的路径换成你自己的实际路径
1.4 附加链接库设置
如下图设置附加链接库,将图片中的路径换成你自己的路径即可
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\lib\fastdeploy.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\onnxruntime\lib\onnxruntime.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\paddle_inference\paddle\lib\paddle_inference.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\paddle_inference\third_party\install\mkldnn\lib\mkldnn.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\paddle_inference\third_party\install\mklml\lib\libiomp5md.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\openvino\runtime\lib\openvino.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\openvino\runtime\3rdparty\tbb\lib\tbb.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\openvino\runtime\3rdparty\tbb\lib\tbbmalloc.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\opencv\build\x64\vc15\lib\opencv_world3416.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\fast_tokenizer\lib\core_tokenizers.lib
H:\VS Projects\VS2019\MyFlowerClassify\MyFlowerClassify\third_libs\install\paddle2onnx\lib\paddle2onnx.lib
2. 推理相关代码
#pragma once
#include "fastdeploy/vision.h"
// 使用fastdeploy命名空间,这样就可以直接使用该命名空间中的类和函数而不需要加上命名空间前缀。
using namespace fastdeploy;
class Infer
{
public:
// 这是一个公共成员函数,它接受模型目录和图像文件路径作为参数,然后进行推理。返回一个vision::ClassifyResult对象。
vision::ClassifyResult InitAndInfer(const std::string& model_dir, const std::string& image_file)
{
// 声明一个RuntimeOption对象。
::RuntimeOption option;
// 设置运行时使用CPU。
option.UseCpu();
// 设置运行时使用Paddle后端。
option.UsePaddleBackend();
// 设置Paddle推理选项,启用日志信息输出。这对于调试是有用的。
option.paddle_infer_option.enable_log_info = true;
// 根据给定的模型目录构造模型文件、参数文件和配置文件的路径。这是硬编码的路径组成,可能需要根据实际情况进行调整。
auto model_file = model_dir + "\\" + "inference.pdmodel";
auto params_file = model_dir + "\\" + "inference.pdiparams";
auto config_file = model_dir + "\\" + "inference.yml";
// 使用模型文件、参数文件和配置文件初始化一个Paddle分类模型。结果保存在auto model中。
auto model = fastdeploy::vision::classification::PaddleClasModel(
model_file, params_file, config_file, option);
// 检查模型是否成功初始化。如果未成功初始化,则抛出一个异常。
if (!model.Initialized())
{
throw "Failed to initialize";
}
// 使用OpenCV读取输入的图像文件,结果保存在auto image中。注意,这行代码需要OpenCV库。因为上面的代码注释掉了包含OpenCV的头文件,这里会出错。
auto image = cv::imread(image_file);
// 设置模型的TopK取值为1,表示返回预测结果的前1个最可能的类别。这适用于单标签分类问题。
model.GetPostprocessor().SetTopk(1);
// 声明一个静态的ClassifyResult对象,用于保存推理结果。注意,这里使用静态对象可能是为了在多次调用Predict函数时重用这个对象。
static fastdeploy::vision::ClassifyResult res;
// 对图像进行预测,并将结果保存到res中。如果预测失败,则抛出一个异常。
if (!model.Predict(image, &res))
throw "Failed to predict";
// 返回推理结果。
return res;
}
};
3. 使用相关代码
vision::ClassifyResult res = infer.InitAndInfer(
"H:\\VS Projects\\VS2019\\MyFlowerClassify\\x64\\Debug\\model",
this->strFilePath.toStdString()
);//获取推理结果结构体
ui.lineResult->setText(
"It is a " + GetValueFromId(res.label_ids[0])
+ QString::asprintf(" %.2f", res.scores[0]));
//这里GetValueFromId的作用是通过推理得出的class_index获取对应的class_name
//比如 labels = ["a", "b", "c"] class_name = labels[0]