diff --git a/doc/fluid/advanced_usage/deploy/index_anakin.rst b/doc/fluid/advanced_usage/deploy/index_anakin.rst index e65dd941ea6e39e00014f2610b579f095e3ba774..e227f41aa6f02a86f1f3ff60885823b45e4a1f56 100644 --- a/doc/fluid/advanced_usage/deploy/index_anakin.rst +++ b/doc/fluid/advanced_usage/deploy/index_anakin.rst @@ -1,4 +1,4 @@ -服务器端部署 - Anakin +Anakin ####################### diff --git a/doc/fluid/advanced_usage/index.rst b/doc/fluid/advanced_usage/index.rst index 89166573eebca045e948046c69f3b7a3e0031d58..9ec55bc158cb333df2f01dc2118317d0f1ab9f59 100644 --- a/doc/fluid/advanced_usage/index.rst +++ b/doc/fluid/advanced_usage/index.rst @@ -10,8 +10,8 @@ .. toctree:: :maxdepth: 2 - deploy/index_anakin.rst deploy/index_mobile.rst + deploy/index_anakin.rst development/contribute_to_paddle.md development/write_docs.rst development/new_op.md diff --git a/doc/fluid/user_guides/howto/inference/index.rst b/doc/fluid/user_guides/howto/inference/index.rst index 45e1a2883773b92ed47ef8d51417bbdcd060b4ec..5b85747b52639b5edb0f45711b6388e320da7955 100644 --- a/doc/fluid/user_guides/howto/inference/index.rst +++ b/doc/fluid/user_guides/howto/inference/index.rst @@ -1,5 +1,5 @@ ############ -模型预测部署 +预测部署 ############ PaddlePaddle Fluid 提供了 C++ API 来支持模型的部署上线 @@ -8,4 +8,4 @@ PaddlePaddle Fluid 提供了 C++ API 来支持模型的部署上线 :maxdepth: 2 build_and_install_lib_cn.rst - native_infer.rst + native_infer.md diff --git a/doc/fluid/user_guides/howto/inference/native_infer.md b/doc/fluid/user_guides/howto/inference/native_infer.md new file mode 100644 index 0000000000000000000000000000000000000000..e6e5409d59baff7e46b45c7a7b2e194df9f8a55f --- /dev/null +++ b/doc/fluid/user_guides/howto/inference/native_infer.md @@ -0,0 +1,139 @@ +# Paddle 预测 API + +为了更简单方便的预测部署,Fluid 提供了一套高层 API 用来隐藏底层不同的优化实现。 + +预测库包含: + +- 头文件 `paddle_inference_api.h` 定义了所有的接口 +- 库文件`libpaddle_fluid.so` 或 `libpaddle_fluid.a` + +下面是详细介绍 + +## PaddleTensor + +PaddleTensor 定义了预测最基本的输入输出的数据格式,常用字段: + +- `name` 用于指定输入数据对应的 模型中variable 的名字 +- `shape` 表示一个 Tensor 的 shape +- `data` 数据以连续内存的方式存储在`PaddleBuf` 中,`PaddleBuf` 可以接收外面的数据或者独立`malloc`内存,详细可以参考头文件中相关定义。 +- `dtype` 表示 Tensor 的数据类型 + +## 利用Config 创建不同引擎 + +高层 API 底层有多种优化实现,我们称之为 engine;不同 engine 的切换通过传递不同的 Config 实现重载 + +- `NativeConfig` 原生 engine,由 paddle 原生的 forward operator + 组成,可以天然支持所有paddle 训练出的模型, + +- `MixedRTConfig` TensorRT mixed engine 用于 GPU + 加速,用子图的方式支持了 [TensorRT] ,支持所有paddle + 模型,并自动切割部分计算子图到 TensorRT 上加速(WIP) + + +## 预测部署过程 + +总体上分为以下步骤 + +1. 用合适的配置创建 `PaddlePredictor` +2. 创建输入用的 `PaddleTensor`,传入到 `PaddlePredictor` 中 +3. 获取输出的 `PaddleTensor` ,将结果取出 + +下面完整演示一个简单的模型,部分细节代码隐去 + +```c++ +#include "paddle_inference_api.h" + +// 创建一个 config,并修改相关设置 +paddle::NativeConfig config; +config.model_dir = "xxx"; +config.use_gpu = false; +// 创建一个原生的 PaddlePredictor +auto predictor = + paddle::CreatePaddlePredictor(config); +// 创建输入 tensor +int64_t data[4] = {1, 2, 3, 4}; +paddle::PaddleTensor tensor; +tensor.shape = std::vector({4, 1}); +tensor.data = paddle::PaddleBuf(data, sizeof(data)); +tensor.dtype = paddle::PaddleDType::INT64; +// 创建输出 tensor,输出 tensor 的内存可以复用 +std::vector outputs; +// 执行预测 +CHECK(predictor->Run(slots, &outputs)); +// 获取 outputs ... +``` + +编译时,联编 `libpaddle_fluid.a/.so` 便可。 + + + +## 高阶使用 + +### 输入输出的内存管理 +`PaddleTensor` 的 `data` 字段是一个 `PaddleBuf`,用于管理一段内存用于数据的拷贝。 + +`PaddleBuf` 在内存管理方面有两种模式: + +1. 自动分配和管理内存 + +```c++ +int some_size = 1024; +PaddleTensor tensor; +tensor.data.Resize(some_size); +// 也可以写成 tensor.data = PaddleBuf(some_size); +``` + +2. 外部内存传入 + +```c++ +int some_size = 1024; +// 用户外部分配内存并保证 PaddleTensor 使用过程中,内存一直可用 +void* memory = new char[some_size]; + +tensor.data.Reset(memory, some_size); +// 也可以写成 tensor.data = PaddleBuf(memory, some_size); +// ... + +// 用户最后需要自行删除内存以避免内存泄漏 +delete[] memory; +``` + +两种模式中,第一种比较方便;第二种则可以严格控制内存的管理,便于与 `tcmalloc` 等库的集成。 + +### 基于 contrib::AnalysisConfig 提升性能 (预发布) +*AnalyisConfig 目前正在预发布阶段,用 `namespace contrib` 进行了保护,后续可能会有调整* + +类似 `NativeConfig` , `AnalysisConfig` 可以创建一个经过一系列优化的高性能预测引擎。 其中包含了计算图的分析和优化,以及对一些重要 Op 的融合改写等,**对使用了 While, LSTM, GRU 等模型性能有大幅提升** 。 + +`AnalysisConfig` 的使用方法也和 `NativeConfig` 类似,但 *目前仅支持 CPU,正在增加对GPU 的支持* + +```c++ +AnalysisConfig config; +config.model_dir = xxx; +config.use_gpu = false; // 目前还不支持 GPU 的优化 +config.specify_input_name = true; // 需要指定输入的 name +``` + +这里需要注意的是,输入的 PaddleTensor 需要指定,比如之前的例子需要修改为 + +```c++ +auto predictor = + paddle::CreatePaddlePredictor(config); // 注意这里需要 AnalysisConfig +// 创建输入 tensor +int64_t data[4] = {1, 2, 3, 4}; +paddle::PaddleTensor tensor; +tensor.shape = std::vector({4, 1}); +tensor.data = paddle::PaddleBuf(data, sizeof(data)); +tensor.dtype = paddle::PaddleDType::INT64; +tensor.name = "input0"; // 注意这里的 name 需要设定 +``` + +### 性能建议 +1. 在 CPU型号允许的情况下,尽量使用带 AVX 和 MKL 的版本 +2. 复用输入和输出的 `PaddleTensor` 以避免频繁分配内存拉低性能 +3. CPU预测,可以尝试把 `NativeConfig` 改成成 `AnalysisConfig` 来进行优化 + +## 详细代码参考 + +- [inference demos](./demo_ci) +- [复杂单线程/多线程例子](https://github.com/PaddlePaddle/Paddle/blob/develop/paddle/fluid/inference/api/test_api_impl.cc) diff --git a/doc/fluid/user_guides/howto/inference/native_infer.rst b/doc/fluid/user_guides/howto/inference/native_infer.rst deleted file mode 100644 index 6d6f3035c0b5c985cd39d45df9f1bcce50dcefa0..0000000000000000000000000000000000000000 --- a/doc/fluid/user_guides/howto/inference/native_infer.rst +++ /dev/null @@ -1,106 +0,0 @@ -Paddle 预测 API -=============== - -为了更简单方便的预测部署,Fluid 提供了一套高层 API -用来隐藏底层不同的优化实现。 - -`预测库相关代码 `_ -包括 - -- 头文件 ``paddle_inference_api.h`` 定义了所有的接口 -- 库文件\ ``libpaddle_fluid.so`` 或 ``libpaddle_fluid.a`` - - -编译和依赖可以参考 :ref:`install_or_build_cpp_inference_lib` 。 - -下面是一些 API 概念的介绍 - -PaddleTensor ------------- - -PaddleTensor 定义了预测最基本的输入输出的数据格式,其定义是 - -.. code:: cpp - - struct PaddleTensor { - std::string name; // variable name. - std::vector shape; - PaddleBuf data; // blob of data. - PaddleDType dtype; - }; - -- ``name`` 用于指定输入数据对应的 模型中variable 的名字 - (暂时没有用,但会在后续支持任意 target 时启用) -- ``shape`` 表示一个 Tensor 的 shape -- ``data`` 数据以连续内存的方式存储在\ ``PaddleBuf`` - 中,\ ``PaddleBuf`` - 可以接收外面的数据或者独立\ ``malloc``\ 内存,详细可以参考头文件中相关定义。 -- ``dtype`` 表示 Tensor 的数据类型 - -engine ------- - -高层 API 底层有多种优化实现,我们称之为 engine,目前有三种 engine - -- 原生 engine,由 paddle 原生的 forward operator - 组成,可以天然支持所有paddle 训练出的模型, -- Anakin engine,封装了 - `Anakin `__ - ,在某些模型上性能不错,但只能接受自带模型格式,无法支持所有 paddle - 模型, -- TensorRT mixed engine,用子图的方式支持了 - `TensorRT `__ ,支持所有paddle - 模型,并自动切割部分计算子图到 TensorRT 上加速(WIP) - -其实现为 - -.. code:: cpp - - enum class PaddleEngineKind { - kNative = 0, // Use the native Fluid facility. - kAnakin, // Use Anakin for inference. - kAutoMixedTensorRT // Automatically mixing TensorRT with the Fluid ops. - }; - -预测部署过程 ------------- - -总体上分为以下步骤 - -1. 用合适的配置创建 ``PaddlePredictor`` -2. 创建输入用的 ``PaddleTensor``\ ,传入到 ``PaddlePredictor`` 中 -3. 获取输出的 ``PaddleTensor`` ,将结果取出 - -下面完整演示一个简单的模型,部分细节代码隐去 - -.. code:: cpp - - #include "paddle_inference_api.h" - - // 创建一个 config,并修改相关设置 - paddle::NativeConfig config; - config.model_dir = "xxx"; - config.use_gpu = false; - // 创建一个原生的 PaddlePredictor - auto predictor = - paddle::CreatePaddlePredictor(config); - // 创建输入 tensor - int64_t data[4] = {1, 2, 3, 4}; - paddle::PaddleTensor tensor{.name = "", - .shape = std::vector({4, 1}), - .data = PaddleBuf(data, sizeof(data)), - .dtype = PaddleDType::INT64}; - // 创建输出 tensor,输出 tensor 的内存可以复用 - std::vector outputs; - // 执行预测 - CHECK(predictor->Run(slots, &outputs)); - // 获取 outputs ... - -编译时,联编 ``libpaddle_fluid.a/.so`` 便可。 - -详细代码参考 ------------- - -- `inference - demos `__ -- `复杂单线程/多线程例子 `__