Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
models
提交
78825715
M
models
项目概览
PaddlePaddle
/
models
大约 1 年 前同步成功
通知
222
Star
6828
Fork
2962
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
602
列表
看板
标记
里程碑
合并请求
255
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
models
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
602
Issue
602
列表
看板
标记
里程碑
合并请求
255
合并请求
255
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
78825715
编写于
4月 19, 2022
作者:
A
andyjpaddle
提交者:
GitHub
4月 19, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add tipc for cpp infer (#5499)
上级
67d113e0
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
719 addition
and
6 deletion
+719
-6
tutorials/mobilenetv3_prod/Step6/test_tipc/README.md
tutorials/mobilenetv3_prod/Step6/test_tipc/README.md
+1
-1
tutorials/mobilenetv3_prod/Step6/test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
...p6/test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
+14
-0
tutorials/mobilenetv3_prod/Step6/test_tipc/docs/test_inference_cpp.md
...bilenetv3_prod/Step6/test_tipc/docs/test_inference_cpp.md
+245
-0
tutorials/mobilenetv3_prod/Step6/test_tipc/test_inference_cpp.sh
...ls/mobilenetv3_prod/Step6/test_tipc/test_inference_cpp.sh
+74
-0
tutorials/tipc/README.md
tutorials/tipc/README.md
+1
-1
tutorials/tipc/infer_cpp/README.md
tutorials/tipc/infer_cpp/README.md
+9
-0
tutorials/tipc/infer_cpp/test_infer_cpp.md
tutorials/tipc/infer_cpp/test_infer_cpp.md
+375
-4
未找到文件。
tutorials/mobilenetv3_prod/Step6/test_tipc/README.md
浏览文件 @
78825715
...
...
@@ -60,7 +60,7 @@ test_tipc
-
更多部署方式测试(coming soon):
-
[
Linux GPU/CPU PYTHON 服务化部署测试
](
docs/test_serving_infer_python.md
)
-
[Linux GPU/CPU C++ 服务化部署测试]
-
[Linux GPU/CPU C++ 推理测试]
-
[
Linux GPU/CPU C++ 推理测试
]
(
docs/test_inference_cpp.md
)
-
[Paddle.js 部署测试]
-
[
Paddle2ONNX 测试
](
docs/test_paddle2onnx.md
)
-
[
Lite ARM CPU 部署测试
](
docs/test_lite_infer_cpp_arm_cpu.md
)
...
...
tutorials/mobilenetv3_prod/Step6/test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
0 → 100755
浏览文件 @
78825715
# model load config
use_gpu 0
gpu_id 0
gpu_mem 4000
cpu_math_library_num_threads 10
use_mkldnn 1
use_tensorrt 0
use_fp16 0
# cls config
cls_model_path ./deploy/inference_cpp/mobilenet_v3_small_infer/inference.pdmodel
cls_params_path ./deploy/inference_cpp/mobilenet_v3_small_infer/inference.pdiparams
resize_short_size 256
crop_size 224
tutorials/mobilenetv3_prod/Step6/test_tipc/docs/test_inference_cpp.md
0 → 100644
浏览文件 @
78825715
# Linux GPU/CPU C++ 推理功能测试
Linux GPU/CPU C++ 推理功能测试的主程序为
`test_inference_cpp.sh`
,可以测试基于C++预测引擎的推理功能。
## 1. 测试结论汇总
-
推理相关:
| 算法名称 | 模型名称 | device_CPU | device_GPU | tensorrt | mkldnn |
| :----: | :----: | :----: | :----: | :----: | :----: |
| MobileNetV3 | mobilenet_v3_small | 支持 | 支持 | 支持 | 支持 |
## 2. 测试流程
### 2.1 准备数据和推理模型
#### 2.1.1 准备数据
从验证集或者测试集中抽出至少一张图像,用于后续的推理过程验证。
#### 2.1.2 准备推理模型
*
如果已经训练好了模型,可以参考
[
模型导出
](
../../tools/export_model.py
)
,导出
`inference model`
,用于模型预测。得到预测模型后,假设模型文件放在
`inference`
目录下,则目录结构如下。
```
mobilenet_v3_small_infer/
|--inference.pdmodel
|--inference.pdiparams
|--inference.pdiparams.info
```
**注意**
:上述文件中,
`inference.pdmodel`
文件存储了模型结构信息,
`inference.pdiparams`
文件存储了模型参数信息。注意两个文件的路径需要与
[
配置文件
](
../configs/mobilenet_v3_small/inference_cpp.txt
)
中的
`cls_model_path`
和
`cls_params_path`
参数对应一致。
### 2.2 准备环境
#### 2.2.1 运行准备
配置合适的编译和执行环境,其中包括编译器,cuda等一些基础库,建议安装docker环境,
[
参考链接
](
https://www.paddlepaddle.org.cn/install/quick?docurl=/documentation/docs/zh/install/docker/linux-docker.html
)
。
#### 2.2.2 编译opencv库
*
首先需要从opencv官网上下载Linux环境下的源码,以3.4.7版本为例,下载及解压缩命令如下:
```
cd deploy/inference_cpp
wget https://github.com/opencv/opencv/archive/3.4.7.tar.gz
tar -xvf 3.4.7.tar.gz
```
*
编译opencv,首先设置opencv源码路径(
`root_path`
)以及安装路径(
`install_path`
),
`root_path`
为下载的opencv源码路径,
`install_path`
为opencv的安装路径。在本例中,源码路径即为当前目录下的
`opencv-3.4.7/`
。
```
shell
cd
./opencv-3.4.7
export
root_path
=
$PWD
export
install_path
=
${
root_path
}
/opencv3
```
*
然后在opencv源码路径下,按照下面的命令进行编译。
```
shell
rm
-rf
build
mkdir
build
cd
build
cmake ..
\
-DCMAKE_INSTALL_PREFIX
=
${
install_path
}
\
-DCMAKE_BUILD_TYPE
=
Release
\
-DBUILD_SHARED_LIBS
=
OFF
\
-DWITH_IPP
=
OFF
\
-DBUILD_IPP_IW
=
OFF
\
-DWITH_LAPACK
=
OFF
\
-DWITH_EIGEN
=
OFF
\
-DCMAKE_INSTALL_LIBDIR
=
lib64
\
-DWITH_ZLIB
=
ON
\
-DBUILD_ZLIB
=
ON
\
-DWITH_JPEG
=
ON
\
-DBUILD_JPEG
=
ON
\
-DWITH_PNG
=
ON
\
-DBUILD_PNG
=
ON
\
-DWITH_TIFF
=
ON
\
-DBUILD_TIFF
=
ON
make
-j
make
install
```
*
`make install`
完成之后,会在该文件夹下生成opencv头文件和库文件,用于后面的代码编译。
以opencv3.4.7版本为例,最终在安装路径下的文件结构如下所示。
**注意**
:不同的opencv版本,下述的文件结构可能不同。
```
opencv3/
|-- bin :可执行文件
|-- include :头文件
|-- lib64 :库文件
|-- share :部分第三方库
```
#### 2.2.3 下载或者编译Paddle预测库
*
有2种方式获取Paddle预测库,下面进行详细介绍。
##### 预测库源码编译
*
如果希望获取最新预测库特性,可以从Paddle github上克隆最新代码,源码编译预测库。
*
可以参考
[
Paddle预测库官网
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16
)
的说明,从github上获取Paddle代码,然后进行编译,生成最新的预测库。使用git获取代码方法如下。
```
shell
git clone https://github.com/PaddlePaddle/Paddle.git
```
*
进入Paddle目录后,使用如下命令编译。
```
shell
rm
-rf
build
mkdir
build
cd
build
cmake ..
\
-DWITH_CONTRIB
=
OFF
\
-DWITH_MKL
=
ON
\
-DWITH_MKLDNN
=
ON
\
-DWITH_TESTING
=
OFF
\
-DCMAKE_BUILD_TYPE
=
Release
\
-DWITH_INFERENCE_API_TEST
=
OFF
\
-DON_INFER
=
ON
\
-DWITH_PYTHON
=
ON
make
-j
make inference_lib_dist
```
更多编译参数选项可以参考Paddle C++预测库官网:
[
https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/05_inference_deployment/inference/build_and_install_lib_cn.html#id16
)
。
*
编译完成之后,可以在
`build/paddle_inference_install_dir/`
文件下看到生成了以下文件及文件夹。
```
build/paddle_inference_install_dir/
|-- CMakeCache.txt
|-- paddle
|-- third_party
|-- version.txt
```
其中
`paddle`
就是之后进行C++预测时所需的Paddle库,
`version.txt`
中包含当前预测库的版本信息。
##### 直接下载安装
*
[
Paddle预测库官网
](
https://paddleinference.paddlepaddle.org.cn/user_guides/download_lib.html
)
上提供了不同cuda版本的Linux预测库,可以在官网查看并选择合适的预测库版本。
以
`manylinux_cuda11.1_cudnn8.1_avx_mkl_trt7_gcc8.2`
版本为例,使用下述命令下载并解压:
```
shell
wget https://paddle-inference-lib.bj.bcebos.com/2.2.2/cxx_c/Linux/GPU/x86-64_gcc8.2_avx_mkl_cuda11.1_cudnn8.1.1_trt7.2.3.4/paddle_inference.tgz
tar
-xvf
paddle_inference.tgz
```
最终会在当前的文件夹中生成
`paddle_inference/`
的子文件夹,文件内容和上述的paddle_inference_install_dir一样。
#### 2.2.4 编译C++预测Demo
*
编译命令如下,其中Paddle C++预测库、opencv等其他依赖库的地址需要换成自己机器上的实际地址。
```
shell
sh tools/build.sh
```
具体地,
`tools/build.sh`
中内容如下。
```
shell
OPENCV_DIR
=
your_opencv_dir
LIB_DIR
=
your_paddle_inference_dir
CUDA_LIB_DIR
=
your_cuda_lib_dir
CUDNN_LIB_DIR
=
your_cudnn_lib_dir
TENSORRT_DIR
=
your_tensorrt_lib_dir
BUILD_DIR
=
build
rm
-rf
${
BUILD_DIR
}
mkdir
${
BUILD_DIR
}
cd
${
BUILD_DIR
}
cmake ..
\
-DPADDLE_LIB
=
${
LIB_DIR
}
\
-DWITH_MKL
=
ON
\
-DDEMO_NAME
=
clas_system
\
-DWITH_GPU
=
OFF
\
-DWITH_STATIC_LIB
=
OFF
\
-DWITH_TENSORRT
=
OFF
\
-DTENSORRT_DIR
=
${
TENSORRT_DIR
}
\
-DOPENCV_DIR
=
${
OPENCV_DIR
}
\
-DCUDNN_LIB
=
${
CUDNN_LIB_DIR
}
\
-DCUDA_LIB
=
${
CUDA_LIB_DIR
}
\
make
-j
```
上述命令中,
*
`OPENCV_DIR`
为opencv编译安装的地址(本例中为
`opencv-3.4.7/opencv3`
文件夹的路径);
*
`LIB_DIR`
为下载的Paddle预测库(
`paddle_inference`
文件夹),或编译生成的Paddle预测库(
`build/paddle_inference_install_dir`
文件夹)的路径;
*
`CUDA_LIB_DIR`
为cuda库文件地址,在docker中一般为
`/usr/local/cuda/lib64`
;
*
`CUDNN_LIB_DIR`
为cudnn库文件地址,在docker中一般为
`/usr/lib64`
。
*
`TENSORRT_DIR`
是tensorrt库文件地址,在dokcer中一般为
`/usr/local/TensorRT-7.2.3.4/`
,TensorRT需要结合GPU使用。
在执行上述命令,编译完成之后,会在当前路径下生成
`build`
文件夹,其中生成一个名为
`clas_system`
的可执行文件。
### 2.3 功能测试
测试方法如下所示,希望测试不同的模型文件,只需更换为自己的参数配置文件,即可完成对应模型的测试。
```
bash
bash test_tipc/test_inference_cpp.sh
${
your_params_file
}
```
以
`mobilenet_v3_small`
的
`Linux GPU/CPU C++推理测试`
为例,命令如下所示。
```
bash
bash test_tipc/test_inference_cpp.sh test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
```
输出结果如下,表示命令运行成功。
```
bash
Run successfully with
command
- ./deploy/inference_cpp/build/clas_system test_tipc/configs/mobilenet_v3_small/inference_cpp.txt ./images/demo.jpg
>
./log/infer_cpp/infer_cpp_use_cpu_use_mkldnn.log 2>&1
!
```
最终log中会打印出结果,如下所示
```
img_file_list length: 1
result:
class id: 8
score: 0.9014719725
Current image path: ./images/demo.jpg
Current time cost: 0.1409450000 s, average time cost in all: 0.1409450000 s.
```
详细log位于
`./log/infer_cpp/infer_cpp_use_cpu_use_mkldnn.log`
中。
如果运行失败,也会在终端中输出运行失败的日志信息以及对应的运行命令。可以基于该命令,分析运行失败的原因。
tutorials/mobilenetv3_prod/Step6/test_tipc/test_inference_cpp.sh
0 → 100644
浏览文件 @
78825715
#!/bin/bash
source
test_tipc/common_func.sh
function
func_parser_key_cpp
(){
strs
=
$1
IFS
=
" "
array
=(
${
strs
}
)
tmp
=
${
array
[0]
}
echo
${
tmp
}
}
function
func_parser_value_cpp
(){
strs
=
$1
IFS
=
" "
array
=(
${
strs
}
)
tmp
=
${
array
[1]
}
echo
${
tmp
}
}
FILENAME
=
$1
dataline
=
$(
cat
${
FILENAME
}
)
lines
=(
${
dataline
}
)
# parser params
dataline
=
$(
awk
'NR==1, NR==14{print}'
$FILENAME
)
IFS
=
$'
\n
'
lines
=(
${
dataline
}
)
# parser load config
use_gpu_key
=
$(
func_parser_key_cpp
"
${
lines
[1]
}
"
)
use_gpu_value
=
$(
func_parser_value_cpp
"
${
lines
[1]
}
"
)
use_mkldnn_key
=
$(
func_parser_key_cpp
"
${
lines
[5]
}
"
)
use_mkldnn_value
=
$(
func_parser_value_cpp
"
${
lines
[5]
}
"
)
use_tensorrt_key
=
$(
func_parser_key_cpp
"
${
lines
[6]
}
"
)
use_tensorrt_value
=
$(
func_parser_value_cpp
"
${
lines
[6]
}
"
)
use_fp16_key
=
$(
func_parser_key_cpp
"
${
lines
[7]
}
"
)
use_fp16_value
=
$(
func_parser_value_cpp
"
${
lines
[7]
}
"
)
LOG_PATH
=
"./log/infer_cpp"
mkdir
-p
${
LOG_PATH
}
status_log
=
"
${
LOG_PATH
}
/results_infer_cpp.log"
function
func_infer_cpp
(){
# inference cpp
if
test
$use_gpu_value
-gt
0
;
then
if
test
$use_tensorrt_value
-gt
0
;
then
if
test
$use_fp16_value
-gt
0
;
then
_save_log_path
=
"
${
LOG_PATH
}
/infer_cpp_
${
use_gpu_key
}
_
${
use_tensorrt_key
}
_
${
use_fp16_key
}
.log"
else
_save_log_path
=
"
${
LOG_PATH
}
/infer_cpp_
${
use_gpu_key
}
_
${
use_tensorrt_key
}
.log"
fi
else
_save_log_path
=
"
${
LOG_PATH
}
/infer_cpp_
${
use_gpu_key
}
.log"
fi
else
if
test
$use_mkldnn_value
-gt
0
;
then
_save_log_path
=
"
${
LOG_PATH
}
/infer_cpp_use_cpu_
${
use_mkldnn_key
}
.log"
else
_save_log_path
=
"
${
LOG_PATH
}
/infer_cpp_use_cpu.log"
fi
fi
# run infer cpp
inference_cpp_cmd
=
"./deploy/inference_cpp/build/clas_system"
inference_cpp_img
=
"./images/demo.jpg"
infer_cpp_full_cmd
=
"
${
inference_cpp_cmd
}
${
FILENAME
}
${
inference_cpp_img
}
>
${
_save_log_path
}
2>&1 "
eval
$infer_cpp_full_cmd
last_status
=
${
PIPESTATUS
[0]
}
status_check
$last_status
"
${
infer_cpp_full_cmd
}
"
"
${
status_log
}
"
}
echo
"################### run test cpp inference ###################"
func_infer_cpp
tutorials/tipc/README.md
浏览文件 @
78825715
...
...
@@ -19,7 +19,7 @@
-
更多部署方式开发文档
-
[
Linux GPU/CPU PYTHON 服务化部署开发文档
](
./serving_python/README.md
)
-
Linux GPU/CPU C++ 服务化部署开发文档 (coming soon)
-
Linux GPU/CPU C++ 推理开发文档 (coming soon
)
-
[
Linux GPU/CPU C++ 推理开发文档
](
./infer_cpp/README.md
)
-
Paddle.js 部署开发文档 (coming soon)
-
[
Paddle2ONNX 开发文档
](
./paddle2onnx/README.md
)
-
[
Lite ARM CPU 部署开发文档
](
./lite_infer_cpp_arm_cpu/README.md
)
...
...
tutorials/tipc/infer_cpp/README.md
浏览文件 @
78825715
...
...
@@ -38,3 +38,12 @@ Paddle Inference 是飞桨的原生推理库, 作用于服务器端和云端
参考
[
C++推理文档开发文档
](
./infer_cpp.md
)
得到可执行的代码。
## 3. C++推理功能测试开发与规范
### 3.1 开发流程
具体参考
[
C++推理功能测试开发文档
](
./test_infer_cpp.md
)
### 3.2 核验点
具体参考
[
C++推理功能测试开发文档
](
./test_infer_cpp.md
)
tutorials/tipc/infer_cpp/test_infer_cpp.md
浏览文件 @
78825715
...
...
@@ -2,7 +2,378 @@
# 目录
-
[
1. 简介
](
#1---
)
-
[
2. 基本C++推理功能测试开发
](
#2---
)
-
[
3. 高级C++推理功能测试开发
](
#3---
)
-
[
4. FAQ
](
#4---
)
-
[
1. 简介
](
#1
)
-
[
2. 命令与配置文件解析
](
#2
)
-
[
2.1 命令解析
](
#2.1
)
-
[
2.2 配置文件和运行命令映射解析
](
#2.2
)
-
[
3. 基本C++推理功能测试开发
](
#3
)
-
[
3.1 准备系统环境
](
#3.1
)
-
[
3.2 准备输入数据和推理模型
](
#3.2
)
-
[
3.3 准备推理所需代码
](
#3.3
)
-
[
3.4 编译得到可执行代码
](
#3.4
)
-
[
3.5 运行得到结果
](
#3.5
)
-
[
3.6 填写配置文件
](
#3.6
)
-
[
3.7 验证配置正确性
](
#3.7
)
-
[
3.8 撰写说明文档
](
#3.8
)
-
[
4. FAQ
](
#4
)
<a
name=
"1"
></a>
## 1. 简介
Paddle Inference 是飞桨的原生推理库, 作用于服务器端和云端,提供高性能的推理能力。相比于直接基于预训练模型进行预测,Paddle Inference可使用MKLDNN、CUDNN、TensorRT进行预测加速,从而实现更优的推理性能。
更多关于Paddle Inference推理引擎的介绍,可以参考
[
Paddle Inference官网教程
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/05_inference_deployment/inference/inference_cn.html
)
。
本文档主要介绍飞桨模型在 Linux GPU/CPU 下基于C++预测引擎的推理过程开发。
<a
name=
"2"
></a>
## 2. 命令与配置文件解析
<a
name=
"2.1"
></a>
### 2.1 命令解析
基于paddle inference的C++预测命令如下:
```
run_scripts configs_path img_path
```
*
`run_scripts`
:最终编译好的可执行命令。
*
`configs_path`
:设置模型路径、是否使用GPU、是否开启mkldnn、是否开启TensorRT等。
*
`img_path`
:待预测的图像路径。
<a
name=
"2.2"
></a>
### 2.2 配置文件解析
完整的
`inference_cpp.txt`
配置文件共有14行,包含两个方面的内容。
*
运行环境参数配置:第1~8行
*
模型参数配置:第10~14行
具体内容见
[
inference_cpp.txt
](
../../mobilenetv3_prod/Step6/test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
)
配置文件中主要有以下2种类型的字段。
*
一行内容以空格为分隔符:该行可以被解析为
`key value`
的格式,需要根据实际的含义修改该行内容,下面进行详细说明。
*
一行内容为
`# xxxxx`
:该行内容为注释信息,无需修改。
<details>
<summary><b>
配置参数(点击以展开详细内容或者折叠)
</b></summary>
| 行号 | 参考内容 | 含义 | key是否需要修改 | value是否需要修改 | 修改内容 |
|----|-------------------------------------|---------------|-----------|-------------|----------------------------------|
| 2 | use_gpu | 是否使用GPU | 否 | 是 | value根据是否使用GPU进行修改 |
| 3 | gpu_id | 使用的GPU卡号 | 否 | 是 | value修改为自己的GPU ID |
| 4 | gpu_mem | 显存 | 否 | 是 | value修改为自己的GPU 显存 |
| 5 | cpu_math_library_num_thread | 底层科学计算库所用线程的数量 | 否 | 是 | value修改为合适的线程数 |
| 6 | use_mkldnn | 是否使用MKLDNN加速 | 否 | 是 | value根据是否使用MKLDNN进行修改 |
| 7 | use_tensorrt | 是否使用tensorRT进行加速 | 否 | 是 | value根据是否使用tensorRT进行修改 |
| 8 | use_fp16 | 是否使用半精度浮点数进行计算,该选项仅在use_tensorrt为true时有效 | 否 | 是 | value根据在开启tensorRT时是否使用半精度进行修改|
| 11 | cls_model_path | 预测模型结构文件路径 | 否 | 是 | value修改为预测模型结构文件路径 |
| 12 | cls_params_path | 预测模型参数文件路径 | 否 | 是 | vvalue修改为预测模型参数文件路径 |
| 13 | resize_short_size | 预处理时图像缩放大小 | 否 | 是 | value修改为预处理时图像缩放大小
| 14 | crop_size | 预处理时图像裁剪后的大小 | 否 | 是 | value修改为预处理时图像裁剪后的大小
</details>
<a
name=
"3"
></a>
## 3. 基本C++推理功能测试开发
基于Paddle Inference的推理过程可以分为5个步骤,如下图所示。
<div
align=
"center"
>
<img
src=
"../images/infer_cpp.png"
width=
"600"
>
</div>
其中设置了2个核验点,分别为
*
准备输入数据和推理模型
*
编译得到可执行代码
<a
name=
"3.1"
></a>
### 3.1 准备系统环境
该部分可参考
[
文档
](
../../mobilenetv3_prod/Step6/test_tipc/docs/test_inference_cpp.md
)
中的2.2.1,2.2.1,2.2.3章节准备环境。
<a
name=
"3.2"
></a>
### 3.2 准备输入数据和推理模型
该部分可参考
[
文档
](
../../mobilenetv3_prod/Step6/test_tipc/docs/test_inference_cpp.md
)
中的2.1章节准备数据和推理模型。
<a
name=
"3.3"
></a>
### 3.3 准备推理所需代码
基于预测引擎的推理过程包含4个步骤:初始化预测引擎、预处理、推理、后处理。
#### 3.3.1 初始化预测引擎
**【基本内容】**
该部分主要根据配置文件对预测引擎进行初始化,包括设置模型结构和参数文件路径、是否使用GPU、是否开启MKLDNN、是否开启TensorRT等。
**【实战】**
以mobilenet_v3_small模型为例,推理引擎初始化函数实现如下,其中模型结构和参数文件路径、是否使用GPU、是否开启MKLDNN等内容都是可以配置的。
主要实现在
[
cls.cpp
](
../../mobilenetv3_prod/Step6/deploy/inference_cpp/src/cls.cpp
)
```
c++
void
Classifier
::
LoadModel
(
const
std
::
string
&
model_path
,
const
std
::
string
&
params_path
)
{
paddle_infer
::
Config
config
;
config
.
SetModel
(
model_path
,
params_path
);
if
(
this
->
use_gpu_
)
{
config
.
EnableUseGpu
(
this
->
gpu_mem_
,
this
->
gpu_id_
);
if
(
this
->
use_tensorrt_
)
{
config
.
EnableTensorRtEngine
(
1
<<
20
,
1
,
3
,
this
->
use_fp16_
?
paddle_infer
::
Config
::
Precision
::
kHalf
:
paddle_infer
::
Config
::
Precision
::
kFloat32
,
false
,
false
);
}
}
else
{
config
.
DisableGpu
();
if
(
this
->
use_mkldnn_
)
{
config
.
EnableMKLDNN
();
// cache 10 different shapes for mkldnn to avoid memory leak
config
.
SetMkldnnCacheCapacity
(
10
);
}
config
.
SetCpuMathLibraryNumThreads
(
this
->
cpu_math_library_num_threads_
);
}
config
.
SwitchUseFeedFetchOps
(
false
);
// true for multiple input
config
.
SwitchSpecifyInputNames
(
true
);
config
.
SwitchIrOptim
(
true
);
config
.
EnableMemoryOptim
();
config
.
DisableGlogInfo
();
this
->
predictor_
=
CreatePredictor
(
config
);
}
```
#### 3.3.2 预处理
**【基本内容】**
该部分主要用来读取指定图像,对其进行数据变换,转化为符合模型推理所需要的输入格式,
**【实战】**
以mobilenet_v3_small模型为例,使用的数据预处理如下:
*
resize
*
crop
*
normalize
*
RGB -> CHW
主要实现在
[
preprocess_op.cpp
](
../../mobilenetv3_prod/Step6/deploy/inference_cpp/src/preprocess_op.cpp
)
中。
```
c++
//Resize
class
ResizeImg
{
public:
virtual
void
Run
(
const
cv
::
Mat
&
img
,
cv
::
Mat
&
resize_img
,
int
max_size_len
);
};
//Crop
class
CenterCropImg
{
public:
virtual
void
Run
(
cv
::
Mat
&
im
,
const
int
crop_size
=
224
);
};
//Norm
class
Normalize
{
public:
virtual
void
Run
(
cv
::
Mat
*
im
,
const
std
::
vector
<
float
>
&
mean
,
const
std
::
vector
<
float
>
&
scale
,
const
bool
is_scale
=
true
);
};
// RGB -> CHW
class
Permute
{
public:
virtual
void
Run
(
const
cv
::
Mat
*
im
,
float
*
data
);
};
```
#### 3.3.3 推理
**【基本内容】**
前向推理是主要步骤,会将预处理好的输入图像输出到预测引擎中,得到输出结果。
**【实战】**
以mobilenet_v3_small模型为例,前向推理主要实现在
[
cls.cpp
](
../../mobilenetv3_prod/Step6/deploy/inference_cpp/src/cls.cpp
)
。
```
C++
auto input_names = this->predictor_->GetInputNames();
auto input_t = this->predictor_->GetInputHandle(input_names[0]);
input_t->Reshape({1, 3, resize_img.rows, resize_img.cols});
auto start = std::chrono::system_clock::now();
input_t->CopyFromCpu(input.data());
this->predictor_->Run();
std::vector<float> out_data;
auto output_names = this->predictor_->GetOutputNames();
auto output_t = this->predictor_->GetOutputHandle(output_names[0]);
std::vector<int> output_shape = output_t->shape();
int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
std::multiplies<int>());
out_data.resize(out_num);
output_t->CopyToCpu(out_data.data());
```
#### 3.3.4 后处理
**【基本内容】**
模型最后的输出可能是数组,一般并不是我们最后想要获取的结果,因此需要对模型的输出做后处理。
**【实战】**
以mobilenet_v3_small模型为例,模型输出的是一个一维的数组,代表输入图片分类到每个类目的概率,为了得到有实际含义的输出,需要获取该数组中最大值的位置和大小,mobilenet_v3_small的后处理代码如下所示。
```
c++
int
maxPosition
=
max_element
(
out_data
.
begin
(),
out_data
.
end
())
-
out_data
.
begin
();
int
score
=
out_data
[
maxPosition
];
```
<a
name=
"3.4"
></a>
### 3.4 编译得到可执行代码
**【基本内容】**
在准备好相应的代码后需要开始准备编译,这里可以利用cmake来实现。
**【实战】**
以mobilenet_v3_small模型为例,代码示例如:
[
CMakeLists.txt
](
../../mobilenetv3_prod/Step6/deploy/inference_cpp/CMakeLists.txt
)
```
bash
set
(
DEPS
${
DEPS
}
${
OpenCV_LIBS
}
)
AUX_SOURCE_DIRECTORY
(
./src SRCS
)
add_executable
(
${
DEMO_NAME
}
${
SRCS
}
)
target_link_libraries
(
${
DEMO_NAME
}
${
DEPS
}
)
```
执行脚本:
```
bash
OPENCV_DIR
=
../opencv-3.4.7/opencv3/
LIB_DIR
=
../paddle_inference/
CUDA_LIB_DIR
=
/usr/local/cuda/lib64
CUDNN_LIB_DIR
=
/usr/lib64
TENSORRT_DIR
=
/usr/local/TensorRT-7.2.3.4
BUILD_DIR
=
build
rm
-rf
${
BUILD_DIR
}
mkdir
${
BUILD_DIR
}
cd
${
BUILD_DIR
}
cmake ..
\
-DPADDLE_LIB
=
${
LIB_DIR
}
\
-DWITH_MKL
=
ON
\
-DWITH_GPU
=
OFF
\
-DWITH_STATIC_LIB
=
OFF
\
-DUSE_TENSORRT
=
OFF
\
-DOPENCV_DIR
=
${
OPENCV_DIR
}
\
-DCUDNN_LIB
=
${
CUDNN_LIB_DIR
}
\
-DCUDA_LIB
=
${
CUDA_LIB_DIR
}
\
make
-j
```
上述命令中,Paddle C++预测库、opencv等其他依赖库的地址需要换成自己机器上的实际地址。
*
`OPENCV_DIR`
为opencv编译安装的地址(本例中为
`opencv-3.4.7/opencv3`
文件夹的路径);
*
`LIB_DIR`
为下载的Paddle预测库(
`paddle_inference`
文件夹),或编译生成的Paddle预测库(
`build/paddle_inference_install_dir`
文件夹)的路径;
*
`CUDA_LIB_DIR`
为cuda库文件地址,在docker中一般为
`/usr/local/cuda/lib64`
;
*
`CUDNN_LIB_DIR`
为cudnn库文件地址,在docker中一般为
`/usr/lib64`
。
*
`TENSORRT_DIR`
是tensorrt库文件地址,在dokcer中一般为
`/usr/local/TensorRT-7.2.3.4/`
,TensorRT需要结合GPU使用。
在执行上述命令,编译完成之后,会在当前路径下生成
`build`
文件夹,其中生成一个名为
`clas_system`
的可执行文件。
<a
name=
"3.5"
></a>
### 3.5 运行得到结果
相关脚本位置
[
run.sh
](
../../mobilenetv3_prod/Step6/deploy/inference_cpp/tools/run.sh
)
```
bash
./build/clas_system ./tools/config.txt ../../images/demo.jpg
```
<a
name=
"3.6"
></a>
### 3.6 填写配置文件
**【基本内容】**
在repo的
`test_tipc/`
目录中新建
`configs/model_name`
,将文件
[
inference_cpp.txt
](
../../mobilenetv3_prod/Step6/test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
)
拷贝到该目录中,其中
`model_name`
需要修改为您自己的模型名称。
**【实战】**
配置文件的含义解析可以参考
[
2.2节配置文件解析
](
#2.2
)
部分。
mobilenet_v3_small的测试开发配置文件可以参考:
[
inference_cpp.txt
](
../../mobilenetv3_prod/Step6/test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
)
。
<a
name=
"3.7"
></a>
### 3.7 验证配置正确性
**【基本内容】**
基于修改完的配置,运行
```
bash
bash test_tipc/test_inference_cpp.sh
${
your_params_file
}
```
**【注意事项】**
如果运行失败,会输出具体的报错命令,可以根据输出的报错命令排查下配置文件的问题并修改,示例报错如下所示。
```
Run failed with command - ./deploy/inference_cpp/build/clas_system test_tipc/configs/mobilenet_v3_small/inference_cpp.txt ./images/demo.jpg > ./log/infer_cpp/infer_cpp_use_cpu_use_mkldnn.log 2>&1 !
```
**【实战】**
以mobilenet_v3_small的
`Linux GPU/CPU C++推理功能测试`
为例,命令如下所示。
```
bash
bash test_tipc/test_inference_cpp.sh test_tipc/configs/mobilenet_v3_small/inference_cpp.txt
```
输出结果如下,表示命令运行成功。
```
bash
Run successfully with
command
- ./deploy/inference_cpp/build/clas_system test_tipc/configs/mobilenet_v3_small/inference_cpp.txt ./images/demo.jpg
>
./log/infer_cpp/infer_cpp_use_cpu_use_mkldnn.log 2>&1
!
```
也可以在
`./log/infer_cpp/infer_cpp_use_cpu_use_mkldnn.log`
中查看详细的输出结果。
**【核验】**
基于修改后的配置文件,测试通过,全部命令成功
<a
name=
"3.8"
></a>
### 3.8 撰写说明文档
**【基本内容】**
撰写TIPC功能总览和测试流程说明文档,分别为
1.
TIPC功能总览文档:test_tipc/README.md
2.
Linux GPU/CPU C++推理功能测试说明文档:test_tipc/docs/test_inference_cpp.md
2个文档模板分别位于下述位置,可以直接拷贝到自己的repo中,根据自己的模型进行修改。
1.
[
README.md
](
../../mobilenetv3_prod/Step6/test_tipc/README.md
)
2.
[
test_inference_cpp
](
../../mobilenetv3_prod/Step6/test_tipc/docs/test_inference_cpp.md
)
**【实战】**
mobilenet_v3_small中
`test_tipc`
文档如下所示。
1.
TIPC功能总览文档:
[
README.md
](
../../mobilenetv3_prod/Step6/test_tipc/README.md
)
2.
Paddle2ONNX 测试说明文档:
[
test_inference_cpp.md
](
../../mobilenetv3_prod/Step6/test_tipc/docs/test_inference_cpp.md
)
**【核验】**
repo中最终目录结构如下所示。
```
test_tipc
|--configs # 配置目录
| |--model_name # 您的模型名称
| |--inference_cpp.txt # inference_cpp测试配置文件
|--docs # 文档目录
| |--test_inference_cpp.md # inference_cpp测试说明文档
|----README.md # TIPC说明文档
|----test_inference_cpp.sh # TIPC inference_cpp解析脚本,无需改动
|----common_func.sh # TIPC基础训练推理测试常用函数,无需改动
```
基于
`test_inference_cpp.md`
文档,跑通
`inference_cpp功能测试`
流程。
<a
name=
"4"
></a>
## 4. FAQ
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录