@@ -20,17 +20,20 @@ PaddleTensor 定义了预测最基本的输入输出的数据格式,常用字
2020
2121## 利用Config 创建不同引擎
2222
23- 高层 API 底层有多种优化实现,我们称之为 engine;不同 engine 的切换通过传递不同的 Config 实现重载
23+ 高层 API 底层有多种优化实现,我们称之为 engine;不同 engine 的切换通过传递不同的 Config 实现重载。
2424
25- - ` NativeConfig ` 原生 engine,由 paddle 原生的 forward operator
26- 组成,可以天然支持所有paddle 训练出的模型,
25+ ` Config ` 有两种,` NativeConfig ` 较简单和稳定,` AnalysisConfig ` 功能更新,性能更好
2726
28- - ` AnalysisConfig ` TensorRT mixed engine 用于 GPU
27+ - ` NativeConfig ` 原生 engine,由 paddle 原生的 forward operator
28+ 组成,可以天然支持所有paddle 训练出的模型,
29+ - ` AnalysisConfig `
30+ - 支持计算图的分析和优化
31+ - 支持最新的各类 op fuse,性能一般比 ` NativeConfig ` 要好
32+ - 支持 TensorRT mixed engine 用于 GPU
2933 加速,用子图的方式支持了 [ TensorRT] ,支持所有paddle
30- 模型,并自动切割部分计算子图到 TensorRT 上加速(WIP),具体的使用方式可以参考[ 这里] ( http://paddlepaddle.org/documentation/docs/zh/1.1/user_guides/howto/inference/paddle_tensorrt_infer.html ) 。
31-
34+ 模型,并自动切割部分计算子图到 TensorRT 上加速,具体的使用方式可以参考[ 这里] ( http://paddlepaddle.org/documentation/docs/zh/1.1/user_guides/howto/inference/paddle_tensorrt_infer.html )
3235
33- ## 预测部署过程
36+ ## 基于 NativeConfig 的预测部署过程
3437
3538总体上分为以下步骤
3639
@@ -70,68 +73,144 @@ CHECK(predictor->Run(slots, &outputs));
7073## 高阶使用
7174
7275### 输入输出的内存管理
76+
7377`PaddleTensor` 的 `data` 字段是一个 `PaddleBuf`,用于管理一段内存用于数据的拷贝。
7478
7579`PaddleBuf` 在内存管理方面有两种模式:
7680
77811. 自动分配和管理内存
78-
79- ```c++
80- int some_size = 1024;
81- PaddleTensor tensor;
82- tensor.data.Resize(some_size);
83- ```
82+
83+ ```c++
84+ int some_size = 1024;
85+ PaddleTensor tensor;
86+ tensor.data.Resize(some_size);
87+ ```
8488
85892 . 外部内存传入
86- ```c++
87- int some_size = 1024;
88- // 用户外部分配内存并保证 PaddleTensor 使用过程中,内存一直可用
89- void* memory = new char[some_size];
90-
91- tensor.data.Reset(memory, some_size);
92- // ...
93-
94- // 用户最后需要自行删除内存以避免内存泄漏
95-
96- delete[] memory;
97- ```
90+
91+ ``` c++
92+ int some_size = 1024 ;
93+ // 用户外部分配内存并保证 PaddleTensor 使用过程中,内存一直可用
94+ void * memory = new char [some_size];
95+
96+ tensor.data.Reset(memory, some_size);
97+ // ...
98+
99+ // 用户最后需要自行删除内存以避免内存泄漏
100+
101+ delete[] memory;
102+ ```
98103
99104两种模式中,第一种比较方便;第二种则可以严格控制内存的管理,便于与 ` tcmalloc ` 等库的集成。
100105
101- ### 基于 contrib::AnalysisConfig 提升性能
102- *AnalyisConfig 目前正在预发布阶段,用 `namespace contrib` 进行了保护,后续可能会有调整*
106+ ### 基于 AnalysisConfig 提升性能
107+
108+ ` AnalysisConfig ` 是目前我们重点优化的版本。
103109
104- 类似 `NativeConfig` , `AnalysisConfig` 可以创建一个经过一系列优化的高性能预测引擎。 其中包含了计算图的分析和优化,以及对一些重要 Op 的融合改写等,**对使用了 While, LSTM, GRU 等模型性能有大幅提升** 。
110+ 类似 ` NativeConfig ` , ` AnalysisConfig ` 可以创建一个经过一系列优化的高性能预测引擎。 其中包含了计算图的分析和优化,以及对一些重要 Op 的融合改写等,比如对使用了 While, LSTM, GRU 等模型性能有大幅提升 。
105111
106- `AnalysisConfig` 的使用方法也和 `NativeConfig` 类似,但 *目前仅支持 CPU,正在增加对GPU 的支持*
112+ ` AnalysisConfig ` 的使用方法也和 ` NativeConfig ` 类似
107113
108114``` c++
109- AnalysisConfig config;
110- config.SetModel(dirname); // 设定模型的目录
111- config.EnableUseGpu(100, 0 /*gpu id*/); // 使用GPU, CPU下使用config.DisableGpu();
112- config.SwitchSpecifyInputNames(true); // 需要指定输入的 name
113- config.SwitchIrOptim(); // 打开优化开关,运行时会执行一系列的优化
115+ AnalysisConfig config (dirname); // dirname 是模型的路径
116+ // 对于不同的模型存储格式,也可以用 AnalysisConfig config(model_file, params_file)
117+ config.EnableUseGpu(100/* 初始显存池大小(MB)* /, 0 /* gpu id* /); // 使用GPU, CPU下使用config.DisableGpu();
118+ config.SwitchIrOptim(); // 打开优化开关,运行时会执行一系列的计算图优化
114119```
115120
116121这里需要注意的是,输入的 PaddleTensor 需要指定,比如之前的例子需要修改为
117122
118123```c++
119- auto predictor =
120- paddle::CreatePaddlePredictor<paddle::contrib::AnalysisConfig>(config); // 注意这里需要 AnalysisConfig
124+ auto predictor = paddle::CreatePaddlePredictor(config); // 注意这里需要 AnalysisConfig
121125// 创建输入 tensor
122126int64_t data[4] = {1, 2, 3, 4};
123127paddle::PaddleTensor tensor;
124128tensor.shape = std::vector<int>({4, 1});
125129tensor.data.Reset(data, sizeof(data));
126130tensor.dtype = paddle::PaddleDType::INT64;
127- tensor.name = "input0"; // 注意这里的 name 需要设定
131+ ```
132+
133+ 后续的执行过程与 ` NativeConfig ` 完全一致。
134+
135+ ### 多线程预测的建议
136+
137+ #### 数据并行的服务
138+
139+ 这种场景下,每个服务线程执行同一种模型,支持 CPU 和 GPU。
140+
141+ Paddle 并没有相关的接口支持,但用户可以简单组合得出,下面演示最简单的实现,用户最好参考具体应用场景做调整
142+
143+ ``` c++
144+ auto main_predictor = paddle::CreatePaddlePredictor(config);
145+
146+ const int num_threads = 10 ; // 假设有 10 个服务线程
147+ std::vector<std::thread> threads;
148+ std::vector<decl_type(main_predictor)> predictors;
149+
150+ // 最好初始化时把所有predictor都创建好
151+ predictors.emplace_back(std::move(main_predictor));
152+ for (int i = 1 ; i < num_threads; i++) {
153+ predictors.emplace_back(main_predictor->Clone());
154+ }
155+ // 创建线程并执行
156+ for (int i = 0 ; i < num_threads; i++) {
157+ threads.emplace_back([i, &]{
158+ auto& predictor = predictors[i];
159+ // 执行
160+ CHECK (predictor->Run(...));
161+ });
162+ }
163+
164+ // 结尾
165+ for (auto & t : threads) {
166+ if (t.joinable()) t.join();
167+ }
168+
169+ // 结束
170+ ```
171+
172+ #### 模型并行的服务
173+
174+ 这种场景,使用多个线程/CPU核加速单个模型的预测,** 目前只支持 CPU下使用 MKL/MKLDNN 的情况** 。
175+
176+ 使用 ` AnalysisConfig ` 的对应接口来设置底层科学计算库使用线程的数目,具体参考 [ SetCpuMathLibraryNumThreads] ( https://github.com/PaddlePaddle/Paddle/blob/release/1.3/paddle/fluid/inference/api/paddle_analysis_config.h#L159 )
177+
178+ ``` c++
179+ config.SetCpuMathLibraryNumThreads(8 ); // 一个模型使用 8 个线程加速预测
180+
181+ // 查询状态,可以使用如下接口
182+ config.cpu_math_library_num_threads(); // return an int
128183```
129184
130185### 性能建议
186+
1311871 . 在 CPU型号允许的情况下,尽量使用带 AVX 和 MKL 的版本
1321882 . 复用输入和输出的 ` PaddleTensor ` 以避免频繁分配内存拉低性能
1331893 . CPU或GPU预测,可以尝试把 ` NativeConfig ` 改成成 ` AnalysisConfig ` 来进行优化
134190
191+ #### CPU下可以尝试使用 Intel 的 ` MKLDNN ` 加速
192+
193+ MKLDNN 对 ` CNN ` 类的模型预测有不错的加速效果,可以尝试对比与 ` MKLML ` 的性能。
194+
195+ 使用方法:
196+
197+ ``` c++
198+ // AnalysisConfig config(...);
199+ config.EnableMKLDNN();
200+ // 查看 mkldnn 是否已经打开,可以用如下代码
201+ config.mkldnn_enabled(); // return a bool
202+ ```
203+
204+ #### GPU 下可以尝试打开 ` TensorRT ` 子图加速引擎
205+
206+ 通过计算图分析,Paddle 可以自动将计算图中部分子图切割,并调用 NVidia 的 ` TensorRT ` 来进行加速。
207+
208+ 详细内容可以参考 [ TensorRT 子图引擎] ( ./paddle_tensorrt_infer.html )
209+
135210## 详细代码参考
136211
212+ ` AnalysisConfig ` 完整接口可以参考 [ 这里] ( https://github.com/PaddlePaddle/Paddle/blob/release/1.3/paddle/fluid/inference/api/paddle_analysis_config.h#L35 )
213+
137214[ inference demos] ( https://github.com/PaddlePaddle/Paddle/tree/develop/paddle/fluid/inference/api/demo_ci )
215+
216+
0 commit comments