From 66e38da149517df678edb79e68d2cf953b4ed4ec Mon Sep 17 00:00:00 2001
From: nhzlx
Date: Wed, 13 May 2020 07:39:54 +0000
Subject: [PATCH] add trt doc
---
README.md | 2 +-
docs/index.rst | 10 +-
docs/introduction/quick_start.md | 10 +-
docs/introduction/summary.md | 2 +-
docs/optimize/paddle_trt.md | 251 ++++++++++++++++++++++++++++++-
docs/tools/visual.md | 62 ++++++++
docs/tools/x2paddle.md | 69 +++++++++
docs/user_guides/cxx_api.md | 32 ++--
docs/user_guides/tutorial.md | 42 +++++-
9 files changed, 453 insertions(+), 27 deletions(-)
create mode 100644 docs/tools/visual.md
create mode 100644 docs/tools/x2paddle.md
diff --git a/README.md b/README.md
index 186f35e3816a2..0418b09616540 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ Paddle Inference为飞桨核心框架推理引擎。Paddle Inference功能特性
**在这个repo中我们会假设您已经对Paddle Inference有了一定的了解。**
-**如果您刚刚接触Paddle Inference不久,建议您[访问这里](http://10.162.69.147:8082/test/infer_py_sample/docs/_build/html/)对Paddle Inference做一个初步的认识。**
+**如果您刚刚接触Paddle Inference不久,建议您[访问这里](https://paddle-inference.readthedocs.io/en/latest/index.html)对Paddle Inference做一个初步的认识。**
## 测试样例
diff --git a/docs/index.rst b/docs/index.rst
index 4dd78dac5452c..8247e7fc0587d 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -23,7 +23,6 @@ Welcome to Paddle-Inference's documentation!
user_guides/inference_python_api
user_guides/source_compile
user_guides/cxx_api
- user_guides/x2paddle
.. toctree::
:maxdepth: 1
@@ -31,6 +30,15 @@ Welcome to Paddle-Inference's documentation!
:name: sec-optimize
optimize/paddle_trt
+
+.. toctree::
+ :maxdepth: 1
+ :caption: 工具
+ :name: sec-tools
+
+ tools/visual
+ tools/x2paddle
+
.. toctree::
:maxdepth: 1
diff --git a/docs/introduction/quick_start.md b/docs/introduction/quick_start.md
index e488421e84752..2792cda710c29 100644
--- a/docs/introduction/quick_start.md
+++ b/docs/introduction/quick_start.md
@@ -165,7 +165,11 @@ print (output_data)
相关链接
-Python API 使用介绍
-C++ API使用介绍
-Paddle Inference使用样例
+[Python API 使用介绍](../user_guides/inference_python_api)
+
+[C++ API使用介绍](../user_guides/cxx_api)
+
+[Python 使用样例](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/python)
+
+[C++ 使用样例](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c%2B%2B)
diff --git a/docs/introduction/summary.md b/docs/introduction/summary.md
index 4067c52f46310..5935151a26e01 100644
--- a/docs/introduction/summary.md
+++ b/docs/introduction/summary.md
@@ -37,4 +37,4 @@ Paddle Inference为飞桨核心框架推理引擎。Paddle Inference功能特性
下一步
-- 如果您刚接触Paddle Inference, 请访问Quick start。
+- 如果您刚接触Paddle Inference, 请访问[Quick start](./quick_start)。
diff --git a/docs/optimize/paddle_trt.md b/docs/optimize/paddle_trt.md
index 0dfefb71deb3f..d5ca697dbadbb 100644
--- a/docs/optimize/paddle_trt.md
+++ b/docs/optimize/paddle_trt.md
@@ -1 +1,250 @@
-# 使用Paddle TRT 进行预测
+# 使用Paddle-TensorRT库预测
+
+NVIDIA TensorRT 是一个高性能的深度学习预测库,可为深度学习推理应用程序提供低延迟和高吞吐量。PaddlePaddle 采用子图的形式对TensorRT进行了集成,即我们可以使用该模块来提升Paddle模型的预测性能。在这篇文章中,我们会介绍如何使用Paddle-TRT子图加速预测。
+
+## 概述
+
+当模型加载后,神经网络可以表示为由变量和运算节点组成的计算图。如果我们打开TRT子图模式,在图分析阶段,Paddle会对模型图进行分析同时发现图中可以使用TensorRT优化的子图,并使用TensorRT节点替换它们。在模型的推断期间,如果遇到TensorRT节点,Paddle会调用TensorRT库对该节点进行优化,其他的节点调用Paddle的原生实现。TensorRT除了有常见的OP融合以及显存/内存优化外,还针对性的对OP进行了优化加速实现,降低预测延迟,提升推理吞吐。
+
+目前Paddle-TRT支持静态shape模式以及/动态shape模式。在静态shape模式下支持图像分类,分割,检测模型,同时也支持Fp16, Int8的预测加速。在动态shape模式下,除了对动态shape的图像模型(FCN, Faster rcnn)支持外,同时也对NLP的Bert/Ernie模型也进行了支持。
+
+**Paddle-TRT的现有能力:**
+
+**1)静态shape:**
+
+支持模型:
+
+|分类模型|检测模型|分割模型|
+|---|---|---|
+|Mobilenetv1|yolov3|ICNET|
+|Resnet50|SSD|UNet|
+|Vgg16|Mask-rcnn|FCN|
+|Resnext|Faster-rcnn||
+|AlexNet|Cascade-rcnn||
+|Se-ResNext|Retinanet||
+|GoogLeNet|Mobilenet-SSD||
+|DPN|||
+
+
+ FP16
+ Calib INT8
+ 优化信息序列化
+ 加载PaddleSlim Int8模型
+
+
+**2)动态shape:**
+
+支持模型:
+
+|图像|NLP|
+|:--:|:--:|
+|FCN|Bert|
+|Faster RCNN|Ernie|
+
+ FP16
+ Calib INT8
+ 优化信息序列化
+ 加载PaddleSlim Int8模型
+
+
+**Note:**
+
+1. 从源码编译时,TensorRT预测库目前仅支持使用GPU编译,且需要设置编译选项TENSORRT_ROOT为TensorRT所在的路径。
+2. Windows支持需要TensorRT 版本5.0以上。
+3. 使用Paddle-TRT的动态shape输入功能要求TRT的版本在6.0以上。
+
+
+## 一:环境准备
+
+使用Paddle-TRT功能,我们需要准备带TRT的Paddle运行环境,我们提供了以下几种方式:
+
+1)linux下通过pip安装
+
+```
+# 该whl包依赖cuda10.1, cudnnv7.6, tensorrt6.0 的lib, 需自行下载安装并设置lib路径到LD_LIBRARY_PATH中
+wget https://paddle-inference-dist.bj.bcebos.com/libs/paddlepaddle_gpu-1.8.0-cp27-cp27mu-linux_x86_64.whl
+pip install -U paddlepaddle_gpu-1.8.0-cp27-cp27mu-linux_x86_64.whl
+```
+
+如果您想在Nvidia Jetson平台上使用,请点击此[链接](https://paddle-inference-dist.cdn.bcebos.com/temp_data/paddlepaddle_gpu-0.0.0-cp36-cp36m-linux_aarch64.whl) 下载whl包,然后通过pip 安装。
+
+2)使用docker镜像
+
+```
+# 拉取镜像,该镜像预装Paddle 1.8 Python环境,并包含c++的预编译库,lib存放在主目录~/ 下。
+docker pull hub.baidubce.com/paddlepaddle/paddle:1.8.0-gpu-cuda10.0-cudnn7-trt6
+
+export CUDA_SO="$(\ls /usr/lib64/libcuda* | xargs -I{} echo '-v {}:{}') $(\ls /usr/lib64/libnvidia* | xargs -I{} echo '-v {}:{}')"
+export DEVICES=$(\ls /dev/nvidia* | xargs -I{} echo '--device {}:{}')
+export NVIDIA_SMI="-v /usr/bin/nvidia-smi:/usr/bin/nvidia-smi"
+
+docker run $CUDA_SO $DEVICES $NVIDIA_SMI --name trt_open --privileged --security-opt seccomp=unconfined --net=host -v $PWD:/paddle -it hub.baidubce.com/paddlepaddle/paddle:1.8.0-gpu-cuda10.0-cudnn7-trt6 /bin/bash
+```
+
+3)手动编译
+编译的方式请参照[编译文档](../user_guides/source_compile)
+
+**Note1:** cmake 期间请设置`TENSORRT_ROOT`(即TRT lib的路径),`WITH_PYTHON`(是否产出python whl包, 设置为ON)选项。
+
+**Note2:** 编译期间会出现TensorRT相关的错误。
+
+需要手动在`NvInfer.h`(trt5) 或 `NvInferRuntime.h`(trt6) 文件中为`class IPluginFactory`和`class IGpuAllocator`分别添加虚析构函数:
+
+``` c++
+virtual ~IPluginFactory() {};
+virtual ~IGpuAllocator() {};
+```
+需要将`NvInferRuntime.h`(trt6)中的 `protected: ~IOptimizationProfile() noexcept = default;`
+
+改为
+
+```
+virtual ~IOptimizationProfile() noexcept = default;
+```
+
+
+## 二:API使用介绍
+
+在[使用流程](../user_guides/tutorial)一节中,我们了解到Paddle Inference预测包含了以下几个方面:
+
+- 配置推理选项
+- 创建predictor
+- 准备模型输入
+- 模型推理
+- 获取模型输出
+
+使用Paddle-TRT 也是遵照这样的流程。我们先用一个简单的例子来介绍这一流程(我们假设您已经对Paddle Inference有一定的了解,如果您刚接触Paddle Inference,请访问[这里](../introduction/quick_start)对Paddle Inference有个初步认识。):
+
+```
+import numpy as np
+from paddle.fluid.core import AnalysisConfig
+from paddle.fluid.core import create_paddle_predictor
+
+def create_predictor():
+ # config = AnalysisConfig("")
+ config = AnalysisConfig("./resnet50/model", "./resnet50/params")
+ config.switch_use_feed_fetch_ops(False)
+ config.enable_memory_optim()
+ config.enable_use_gpu(1000, 0)
+
+ # 打开TensorRT。此接口的详细介绍请见下文
+ config.enable_tensorrt_engine(workspace_size = 1<<30,
+ max_batch_size=1, min_subgraph_size=5,
+ precision_mode=AnalysisConfig.Precision.Float32,
+ use_static=False, use_calib_mode=False)
+
+ predictor = create_paddle_predictor(config)
+ return predictor
+
+def run(predictor, img):
+ # 准备输入
+ input_names = predictor.get_input_names()
+ for i, name in enumerate(input_names):
+ input_tensor = predictor.get_input_tensor(name)
+ input_tensor.reshape(img[i].shape)
+ input_tensor.copy_from_cpu(img[i].copy())
+ # 预测
+ predictor.zero_copy_run()
+ results = []
+ # 获取输出
+ output_names = predictor.get_output_names()
+ for i, name in enumerate(output_names):
+ output_tensor = predictor.get_output_tensor(name)
+ output_data = output_tensor.copy_to_cpu()
+ results.append(output_data)
+ return results
+
+if __name__ == '__main__':
+ pred = create_predictor()
+ img = np.ones((1, 3, 224, 224)).astype(np.float32)
+ result = run(pred, [img])
+ print ("class index: ", np.argmax(result[0][0]))
+```
+
+通过例子我们可以看出,我们通过`enable_tensorrt_engine`接口来打开TensorRT选项的。
+
+```python
+config.enable_tensorrt_engine(
+ workspace_size = 1<<30,
+ max_batch_size=1, min_subgraph_size=5,
+ precision_mode=AnalysisConfig.Precision.Float32,
+ use_static=False, use_calib_mode=False)
+```
+
+接下来让我们看下该接口中各个参数的作用:
+
+- **`workspace_size`**,类型:int,默认值为1 << 30 (1G)。指定TensorRT使用的工作空间大小,TensorRT会在该大小限制下筛选最优的kernel执行预测运算。
+- **`max_batch_size`**,类型:int,默认值为1。需要提前设置最大的batch大小,运行时batch大小不得超过此限定值。
+- **`min_subgraph_size`**,类型:int,默认值为3。Paddle-TRT是以子图的形式运行,为了避免性能损失,当子图内部节点个数大于`min_subgraph_size`的时候,才会使用Paddle-TRT运行。
+- **`precision_mode`**,类型:`AnalysisConfig.Precision`, 默认值为`AnalysisConfig.Precision.Float32`。指定使用TRT的精度,支持FP32(Float32),FP16(Half),Int8(Int8)。若需要使用Paddle-TRT int8离线量化校准,需设定`precision`为 `AnalysisConfig.Precision.Int8`, 且设置`use_calib_mode` 为true。
+- **`use_static`**,类型:bool, 默认值为false。如果指定为true,在初次运行程序的时候会将TRT的优化信息进行序列化到磁盘上,下次运行时直接加载优化的序列化信息而不需要重新生成。
+- **`use_calib_mode`**,类型:bool, 默认值为false。若要运行Paddle-TRT int8离线量化校准,需要将此选项设置为true。
+
+### 运行INT8
+
+ 神经网络的参数在一定程度上是冗余的,在很多任务上,我们可以在保证模型精度的前提下,将Float32的模型转换成Int8的模型。目前,Paddle-TRT支持离线将预训练好的Float32模型转换成Int8的模型,具体的流程如下:
+
+**1. 生成校准表**(Calibration table):
+
+ a. 指定TensorRT配置时,将precision_mode 设置为`AnalysisConfig.Precision.Int8`并且设置`use_calib_mode` 为true。
+
+ b. 准备500张左右的真实输入数据,在上述配置下,运行模型。(Paddle-TRT会统计模型中每个tensor值的范围信息,并将其记录到校准表中,运行结束后,会将校准表写入模型目录下的`_opt_cache`目录中)
+
+**2. INT8预测**
+
+ 保持1中的配置不变,再次运行模型,Paddle-TRT会从模型目录下的`_opt_cache`读取校准表,进行INT8 预测。
+
+
+### 运行Dynamic shape
+
+从1.8 版本开始, Paddle对TRT子图进行了Dynamic shape的支持。
+使用接口如下:
+
+```
+config.enable_tensorrt_engine(
+ workspace_size = 1<<30,
+ max_batch_size=1, min_subgraph_size=5,
+ precision_mode=AnalysisConfig.Precision.Float32,
+ use_static=False, use_calib_mode=False)
+
+min_input_shape = {"image":[1,3, 10, 10]}
+max_input_shape = {"image":[1,3, 224, 224]}
+opt_input_shape = {"image":[1,3, 100, 100]}
+
+config.set_trt_dynamic_shape_info(min_input_shape, max_input_shape, opt_input_shape)
+
+```
+
+从上述使用方式来看,在`config.enable_tensorrt_engine` 接口的基础上,新加了一个`config.set_trt_dynamic_shape_info `的接口。
+
+该接口用来设置模型输入的最小,最大,以及最优的输入shape。 其中,最优的shape处于最小最大shape之间,在预测初始化期间,会根据opt shape对op选择最优的kernel。
+
+调用了`config.set_trt_dynamic_shape_info`接口,预测器会运行TRT子图的动态输入模式,运行期间可以接受最小,最大shape间的任意的shape的输入数据。
+
+
+
+## 三:测试样例
+
+我们在github上提供了使用TRT子图预测的更多样例:
+
+- Python 样例请访问此处[链接](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/python/paddle_trt)
+- C++ 样例地址请访问此处[链接](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c%2B%2B)
+
+## 四:Paddle-TRT子图运行原理
+
+ PaddlePaddle采用子图的形式对TensorRT进行集成,当模型加载后,神经网络可以表示为由变量和运算节点组成的计算图。Paddle TensorRT实现的功能是对整个图进行扫描,发现图中可以使用TensorRT优化的子图,并使用TensorRT节点替换它们。在模型的推断期间,如果遇到TensorRT节点,Paddle会调用TensorRT库对该节点进行优化,其他的节点调用Paddle的原生实现。TensorRT在推断期间能够进行Op的横向和纵向融合,过滤掉冗余的Op,并对特定平台下的特定的Op选择合适的kernel等进行优化,能够加快模型的预测速度。
+
+下图使用一个简单的模型展示了这个过程:
+
+**原始网络**
+
+
+
+
+**转换的网络**
+
+
+
+
+ 我们可以在原始模型网络中看到,绿色节点表示可以被TensorRT支持的节点,红色节点表示网络中的变量,黄色表示Paddle只能被Paddle原生实现执行的节点。那些在原始网络中的绿色节点被提取出来汇集成子图,并由一个TensorRT节点代替,成为转换后网络中的`block-25` 节点。在网络运行过程中,如果遇到该节点,Paddle将调用TensorRT库来对其执行。
+
diff --git a/docs/tools/visual.md b/docs/tools/visual.md
new file mode 100644
index 0000000000000..5a01ee9b02170
--- /dev/null
+++ b/docs/tools/visual.md
@@ -0,0 +1,62 @@
+## 模型可视化
+
+通过[Quick Start](../introduction/quick_start) 一节中,我们了解到,预测模型包含了两个文件,一部分为模型结构文件,通常以`model`, `__model__`文件存在;另一部分为参数文件,通常以`params`文件或一堆分散的文件存在。
+
+模型结构文件,顾名思义,存储了模型的拓扑结构,其中包括模型中各种OP的计算顺序以及OP的详细信息。很多时候,我们希望能够将这些模型的结构以及内部信息可视化,方便我们进行模型分析。接下来将会通过两种方式来讲述如何对Paddle 预测模型进行可视化。
+
+一: 通过`Netron` 可视化
+
+1) 安装
+
+Netron 是github开源的软件,我们可以进入它的[主页](https://github.com/lutzroeder/netron) 进行下载安装。
+
+2)可视化
+
+[点击](https://paddle-inference-dist.bj.bcebos.com/temp_data/sample_model/__model__)下载测试模型。
+
+打开Netron软件, 我们将Paddle 预测模型结构文件命名成`__model__`, 然后将文件通过鼠标拖入到Netron软件中完成可视化。
+
+eg:
+
+
+
+
+
+二: 通过代码方式生成dot文件
+
+1)pip 安装Paddle
+
+2)生成dot文件
+
+[点击](https://paddle-inference-dist.bj.bcebos.com/temp_data/sample_model/__model__)下载测试模型。
+
+```python
+#!/usr/bin/env python
+import paddle.fluid as fluid
+from paddle.fluid import core
+from paddle.fluid.framework import IrGraph
+
+def get_graph(program_path):
+ with open(program_path, 'rb') as f:
+ binary_str = f.read()
+ program = fluid.framework.Program.parse_from_string(binary_str)
+ return IrGraph(core.Graph(program.desc), for_test=True)
+
+if __name__ == '__main__':
+ program_path = './lecture_model/__model__'
+ offline_graph = get_graph(program_path)
+ offline_graph.draw('.', 'test_model', [])
+```
+
+3)生成svg
+
+**Note:需要环境中安装graphviz**
+
+```
+dot -Tsvg ./test_mode.dot -o test_model.svg
+```
+
+然后将test_model.svg以浏览器打开预览即可。
+
+
+
diff --git a/docs/tools/x2paddle.md b/docs/tools/x2paddle.md
new file mode 100644
index 0000000000000..7e44ba980cc68
--- /dev/null
+++ b/docs/tools/x2paddle.md
@@ -0,0 +1,69 @@
+# 模型转换工具 X2Paddle
+
+X2Paddle可以将caffe、tensorflow、onnx模型转换成Paddle支持的模型。
+
+[X2Paddle](https://github.com/PaddlePaddle/X2Paddle)支持将Caffe/TensorFlow模型转换为PaddlePaddle模型。目前X2Paddle支持的模型参考[x2paddle_model_zoo](https://github.com/PaddlePaddle/X2Paddle/blob/develop/x2paddle_model_zoo.md)。
+
+
+## 多框架支持
+
+|模型 | caffe | tensorflow | onnx |
+|---|---|---|---|
+|mobilenetv1 | Y | Y | |
+|mobilenetv2 | Y | Y | Y |
+|resnet18 | Y | Y | |
+|resnet50 | Y | Y | Y |
+|mnasnet | Y | Y | |
+|efficientnet | Y | Y | Y |
+|squeezenetv1.1 | Y | Y | Y |
+|shufflenet | Y | Y | |
+|mobilenet_ssd | Y | Y | |
+|mobilenet_yolov3 | | Y | |
+|inceptionv4 | | | |
+|mtcnn | Y | Y | |
+|facedetection | Y | | |
+|unet | Y | Y | |
+|ocr_attention | | | |
+|vgg16 | | | |
+
+
+## 安装
+
+```
+pip install x2paddle
+```
+
+安装最新版本,可使用如下安装方式
+
+```
+pip install git+https://github.com/PaddlePaddle/X2Paddle.git@develop
+```
+
+## 使用
+
+### Caffe
+
+```
+x2paddle --framework caffe \
+ --prototxt model.proto \
+ --weight model.caffemodel \
+ --save_dir paddle_model
+```
+
+### TensorFlow
+
+```
+x2paddle --framework tensorflow \
+ --model model.pb \
+ --save_dir paddle_model
+```
+
+## 转换结果说明
+
+在指定的`save_dir`下生成两个目录
+1. inference_model : 模型结构和参数均序列化保存的模型格式
+2. model_with_code : 保存了模型参数文件和模型的python代码
+
+## 问题反馈
+
+X2Paddle使用时存在问题时,欢迎您将问题或Bug报告以[Github Issues](https://github.com/PaddlePaddle/X2Paddle/issues)的形式提交给我们,我们会实时跟进。
diff --git a/docs/user_guides/cxx_api.md b/docs/user_guides/cxx_api.md
index e9b9b5d6e3c4d..f96c2d9174edd 100644
--- a/docs/user_guides/cxx_api.md
+++ b/docs/user_guides/cxx_api.md
@@ -1,7 +1,7 @@
# 使用C++API
为了简单方便地进行推理部署,飞桨提供了一套高度优化的C++ API推理接口。下面对各主要API使用方法进行详细介绍。
-在[使用流程]()一节中,我们了解到Paddle Inference预测包含了以下几个方面:
+在[使用流程](./tutorial)一节中,我们了解到Paddle Inference预测包含了以下几个方面:
- 配置推理选项
- 创建predictor
@@ -66,26 +66,29 @@ AnalysisConfig管理AnalysisPredictor的推理配置,提供了模型路径设
* non-combined形式:模型文件夹`model_dir`下存在一个模型文件和多个参数文件时,传入模型文件夹路径,模型文件名默认为`__model__`。 使用方式为:`config->SetModel("./model_dir");`。
* combined形式:模型文件夹`model_dir`下只有一个模型文件`model`和一个参数文件`params`时,传入模型文件和参数文件路径。使用方式为:`config->SetModel("./model_dir/model", "./model_dir/params");`。
-* 内存加载模式:如果模型是从内存加载,可以使用`config->SetModelBuffer(model.data(), model.size(), params.data(), params.size())`。
+* 内存加载模式:如果模型是从内存加载(模型必须为combined形式),可以使用
-关于`non-combined` 以及 `combined`模型介绍,请参照[这里]()。
+ ```c++
+ std::ifstream in_m(FLAGS_dirname + "/model");
+ std::ifstream in_p(FLAGS_dirname + "/params");
+ std::ostringstream os_model, os_param;
+ os_model << in_m.rdbuf();
+ os_param << in_p.rdbuf();
+ config.SetModelBuffer(os_model.str().data(), os_model.str().size(), os_param.str().data(), os_param.str().size());
+ ```
+
+Paddle Inference有两种格式的模型,分别为`non-combined` 以及 `combined`。这两种类型我们在[Quick Start](introduction/quick_start)一节中提到过,忘记的同学可以回顾下。
**b. 关闭Feed,Fetch op**
`config->SwitchUseFeedFetchOps(false); // 关闭feed和fetch OP使用,使用ZeroCopy接口必须设置此项`
我们用一个小的例子来说明我们为什么要关掉它们。
-
假设我们有一个模型,模型运行的序列为:
-`input -> FEED_OP -> feed_out -> CONV_OP -> conv_out -> FETCH_OP -> output`
-
-序列中大些字母的`FEED_OP`, `CONV_OP`, `FETCH_OP` 为模型中的OP, 小写字母的`input`,`feed_out`,`output` 为模型中的变量。
+`input -> FEED_OP -> feed_out -> CONV_OP -> conv_out -> FETCH_OP -> output`
-ZeroCopy模式下:
+序列中大些字母的`FEED_OP`, `CONV_OP`, `FETCH_OP` 为模型中的OP, 小写字母的`input`,`feed_out`,`output` 为模型中的变量。
-- 通过`predictor->GetInputTensor(input_names[0])`获取模型输入为`FEED_OP`的输出, 即`feed_out`。
-- 通过`predictor->GetOutputTensor(output_names[0])`接口获取的模型的输出为`FETCH_OP`的输入,即`conv_out`。
-
-ZeroCopy的方式避免了`input->FEED_OP` 以及 `FETCH_OP->output` 的copy,从而能加速推理性能(对小的模型效果加速明显)。
+在ZeroCopy模式下,我们通过`predictor->GetInputTensor(input_names[0])`获取的模型输入为`FEED_OP`的输出, 即`feed_out`,我们通过`predictor->GetOutputTensor(output_names[0])`接口获取的模型输出为`FETCH_OP`的输入,即`conv_out`,这种情况下,我们在运行期间就没有必要运行feed和fetch OP了,因此需要设置`config->SwitchUseFeedFetchOps(false)`来关闭feed和fetch op。
#### 2. 可选配置
@@ -109,7 +112,7 @@ config->SetCpuMathLibraryNumThreads(10);
config->EnableUseGpu(100, 0);
```
-如果使用的预测lib带Paddle-TRT子图功能,可以打开TRT选项进行加速:
+如果使用的预测lib带Paddle-TRT子图功能,可以打开TRT选项进行加速, 详细的请访问[Paddle-TensorRT文档](../optimize/paddle_trt):
```
// 开启TensorRT推理,可提升GPU推理性能,需要使用带TensorRT的推理库
@@ -222,7 +225,6 @@ int output_size;
float *output_d = output_t->data(PaddlePlace::kGPU, &output_size);
```
-
### 下一步
-看到这里您是否已经对Paddle Inference的C++使用有所了解了呢?请访问[这里]()进行样例测试。
+看到这里您是否已经对Paddle Inference的C++使用有所了解了呢?请访问[这里](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c%2B%2B)进行样例测试。
diff --git a/docs/user_guides/tutorial.md b/docs/user_guides/tutorial.md
index 70f8d022931d0..a4500892110e0 100644
--- a/docs/user_guides/tutorial.md
+++ b/docs/user_guides/tutorial.md
@@ -3,13 +3,45 @@
### 一: 模型准备
Paddle Inference目前支持的模型结构为PaddlePaddle深度学习框架产出的模型格式。因此,在您开始使用 Paddle Inference框架前您需要准备一个由PaddlePaddle框架保存的模型。 如果您手中的模型是由诸如Caffe2、Tensorflow等框架产出的,那么我们推荐您使用 X2Paddle 工具进行模型格式转换。
-
### 二: 环境准备
-1) 如果您想用Paddle Inference Python API接口,请参照官方主页的引导,在您的环境中安装PaddlePaddle。
-
-2) 如果您想使用Paddle Inference C++ API 接口,请参照接下来的[预测库的编译]()页面。
-
+**1) Python 环境**
+
+安装Python环境有以下三种方式:
+
+ a. 参照[官方主页](https://www.paddlepaddle.org.cn/)的引导进行pip安装。
+
+ b. 参照接下来的[预测库编译](../source_compile)页面进行自行编译。
+
+ c. 使用docker镜像
+
+ # 拉取镜像,该镜像预装Paddle 1.8 Python环境
+ docker pull hub.baidubce.com/paddlepaddle/paddle:1.8.0-gpu-cuda10.0-cudnn7-trt6
+
+ export CUDA_SO="$(\ls /usr/lib64/libcuda* | xargs -I{} echo '-v {}:{}') $(\ls /usr/lib64/libnvidia* | xargs -I{} echo '-v {}:{}')"
+ export DEVICES=$(\ls /dev/nvidia* | xargs -I{} echo '--device {}:{}')
+ export NVIDIA_SMI="-v /usr/bin/nvidia-smi:/usr/bin/nvidia-smi"
+
+ docker run $CUDA_SO $DEVICES $NVIDIA_SMI --name trt_open --privileged --security-opt seccomp=unconfined --net=host -v $PWD:/paddle -it hub.baidubce.com/paddlepaddle/paddle:1.8.0-gpu-cuda10.0-cudnn7-trt6 /bin/bash
+
+**2) C++ 环境**
+
+获取c++预测库有以下三种方式:
+
+a. [官网](https://www.paddlepaddle.org.cn/documentation/docs/zh/advanced_guide/inference_deployment/inference/build_and_install_lib_cn.html#linux)下载预编译库
+
+b. 使用docker镜像
+
+ # 拉取镜像,在容器内主目录~/下存放c++预编译库。
+ docker pull hub.baidubce.com/paddlepaddle/paddle:1.8.0-gpu-cuda10.0-cudnn7-trt6
+
+ export CUDA_SO="$(\ls /usr/lib64/libcuda* | xargs -I{} echo '-v {}:{}') $(\ls /usr/lib64/libnvidia* | xargs -I{} echo '-v {}:{}')"
+ export DEVICES=$(\ls /dev/nvidia* | xargs -I{} echo '--device {}:{}')
+ export NVIDIA_SMI="-v /usr/bin/nvidia-smi:/usr/bin/nvidia-smi"
+
+ docker run $CUDA_SO $DEVICES $NVIDIA_SMI --name trt_open --privileged --security-opt seccomp=unconfined --net=host -v $PWD:/paddle -it hub.baidubce.com/paddlepaddle/paddle:1.8.0-gpu-cuda10.0-cudnn7-trt6 /bin/bash
+
+c. 参照接下来的[预测库编译](../source_compile)页面进行自行编译。
### 三:使用Paddle Inference执行预测