|
| 1 | +# 飞桨框架 MLU 版预测示例 |
| 2 | + |
| 3 | +使用寒武纪 MLU 进行预测与使用 Intel CPU/Nvidia GPU 预测相同,支持飞桨原生推理库(Paddle Inference),适用于高性能服务器端、云端推理。当前 Paddle MLU 版本完全兼容 Paddle CUDA 版本的 API,直接使用原有的 GPU 预测命令和参数即可。 |
| 4 | + |
| 5 | +<!-- ## C++预测部署 |
| 6 | +
|
| 7 | +**注意**:更多 C++预测 API 使用说明请参考 [Paddle Inference - C++ API](https://paddleinference.paddlepaddle.org.cn/api_reference/cxx_api_index.html) |
| 8 | +
|
| 9 | +**第一步**:源码编译 C++预测库 |
| 10 | +
|
| 11 | +当前 Paddle MLU 版支持通过源码编译的方式提供 C++预测库。编译环境准备请参考 [飞桨框架 MLU 版安装说明:通过源码编译安装](./paddle_install_cn.html)。 |
| 12 | +
|
| 13 | +```bash |
| 14 | +# 下载源码 |
| 15 | +git clone https://github.com/PaddlePaddle/Paddle.git |
| 16 | +cd Paddle |
| 17 | +
|
| 18 | +# 创建编译目录 |
| 19 | +mkdir build && cd build |
| 20 | +
|
| 21 | +# 执行 cmake,注意这里需打开预测优化选项 ON_INFER |
| 22 | +cmake .. -DPY_VERSION=3.7 -DWITH_MLU=ON -DWITH_TESTING=OFF -DON_INFER=ON \ |
| 23 | + -DCMAKE_BUILD_TYPE=Release -DWITH_DISTRIBUTE=ON -DWITH_CNCL=ON |
| 24 | +
|
| 25 | +# 使用以下命令来编译 |
| 26 | +make -j$(nproc) |
| 27 | +``` |
| 28 | +
|
| 29 | +编译完成之后,`build` 目录下的 `paddle_inference_install_dir` 即为 C++ 预测库,目录结构如下: |
| 30 | +
|
| 31 | +```bash |
| 32 | +paddle_inference_install_dir/ |
| 33 | +|-- CMakeCache.txt |
| 34 | +|-- paddle |
| 35 | +| |-- include |
| 36 | +| | |-- crypto |
| 37 | +| | |-- experimental |
| 38 | +| | |-- internal |
| 39 | +| | |-- paddle_analysis_config.h |
| 40 | +| | |-- paddle_api.h |
| 41 | +| | |-- paddle_infer_contrib.h |
| 42 | +| | |-- paddle_infer_declare.h |
| 43 | +| | |-- paddle_inference_api.h |
| 44 | +| | |-- paddle_mkldnn_quantizer_config.h |
| 45 | +| | |-- paddle_pass_builder.h |
| 46 | +| | `-- paddle_tensor.h |
| 47 | +| `-- lib |
| 48 | +| |-- libpaddle_inference.a |
| 49 | +| `-- libpaddle_inference.so |
| 50 | +|-- third_party |
| 51 | +| |-- install |
| 52 | +| | |-- cryptopp |
| 53 | +| | |-- gflags |
| 54 | +| | |-- glog |
| 55 | +| | |-- mkldnn |
| 56 | +| | |-- mklml |
| 57 | +| | |-- protobuf |
| 58 | +| | |-- utf8proc |
| 59 | +| | `-- xxhash |
| 60 | +| `-- threadpool |
| 61 | +| `-- ThreadPool.h |
| 62 | +`-- version.txt |
| 63 | +``` |
| 64 | +
|
| 65 | +其中 `version.txt` 文件中记录了该预测库的版本信息,包括 Git Commit ID、使用 OpenBlas 或 MKL 数学库、ROCm/MIOPEN 版本号,如: |
| 66 | +
|
| 67 | +```bash |
| 68 | +GIT COMMIT ID: c7d60ce44714d6888a5e50d29ab885fec16b995e |
| 69 | +WITH_MKL: ON |
| 70 | +WITH_MKLDNN: ON |
| 71 | +WITH_GPU: OFF |
| 72 | +WITH_ROCM: OFF |
| 73 | +WITH_ASCEND_CL: OFF |
| 74 | +WITH_ASCEND_CXX11: OFF |
| 75 | +WITH_IPU: OFF |
| 76 | +CXX compiler version: 8.2.0 |
| 77 | +``` |
| 78 | +
|
| 79 | +**第二步**:准备预测部署模型 |
| 80 | +
|
| 81 | +下载 [ResNet50](https://paddle-inference-dist.bj.bcebos.com/Paddle-Inference-Demo/resnet50.tgz) 模型后解压,得到 Paddle 预测格式的模型,位于文件夹 ResNet50 下。如需查看模型结构,可将 inference.pdmodel 文件通过模型可视化工具 [Netron](https://netron.app/) 打开。 |
| 82 | +
|
| 83 | +```bash |
| 84 | +wget https://paddle-inference-dist.bj.bcebos.com/Paddle-Inference-Demo/resnet50.tgz |
| 85 | +tar zxf resnet50.tgz |
| 86 | +
|
| 87 | +# 获得模型目录即文件如下 |
| 88 | +resnet50/ |
| 89 | +├── inference.pdmodel |
| 90 | +├── inference.pdiparams.info |
| 91 | +└── inference.pdiparams |
| 92 | +``` |
| 93 | +
|
| 94 | +**第三步**:获取预测示例代码并编译运行 |
| 95 | +
|
| 96 | +**预先要求**: |
| 97 | +
|
| 98 | +本章节 C++ 预测示例代码位于 [Paddle-Inference-Demo/c++/resnet50](https://github.com/PaddlePaddle/Paddle-Inference-Demo/tree/master/c++/resnet50)。 |
| 99 | +
|
| 100 | +请先将示例代码下载到本地,再将第一步中编译得到的 `paddle_inference_install_dir` 重命名为 `paddle_inference` 文件夹,移动到示例代码的 `Paddle-Inference-Demo/c++/lib` 目录下。使用到的文件如下所示: |
| 101 | +
|
| 102 | +```bash |
| 103 | +-rw-r--r-- 1 root root 3479 Jun 2 03:14 README.md README 说明 |
| 104 | +-rw-r--r-- 1 root root 3051 Jun 2 03:14 resnet50_test.cc 预测 C++ 源码程序 |
| 105 | +drwxr-xr-x 2 root root 4096 Mar 5 07:43 resnet50 第二步中下载并解压的预测部署模型文件夹 |
| 106 | +-rw-r--r-- 1 root root 387 Jun 2 03:14 run.sh 运行脚本 |
| 107 | +-rwxr-xr-x 1 root root 1077 Jun 2 03:14 compile.sh 编译脚本 |
| 108 | +-rw-r--r-- 1 root root 9032 Jun 2 07:26 ../lib/CMakeLists.txt CMAKE 文件 |
| 109 | +drwxr-xr-x 1 root root 9032 Jun 2 07:26 ../lib/paddle_inference 第一步编译的到的 Paddle Infernece C++ 预测库文件夹 |
| 110 | +``` |
| 111 | +
|
| 112 | +编译运行预测样例之前,需要根据运行环境配置编译脚本 `compile.sh`。 |
| 113 | +
|
| 114 | +```bash |
| 115 | +# 根据预编译库中的 version.txt 信息判断是否将以下标记打开 |
| 116 | +WITH_MKL=ON |
| 117 | +WITH_GPU=OFF # 注意这里需要关掉 WITH_GPU |
| 118 | +USE_TENSORRT=OFF |
| 119 | +
|
| 120 | +WITH_ROCM=ON # 注意这里需要打开 WITH_ROCM |
| 121 | +ROCM_LIB=/opt/rocm/lib |
| 122 | +``` |
| 123 | +
|
| 124 | +运行 `run.sh` 脚本进行编译和运行,即可获取最后的预测结果: |
| 125 | +
|
| 126 | +```bash |
| 127 | +bash run.sh |
| 128 | +
|
| 129 | +# 成功执行之后,得到的预测输出结果如下: |
| 130 | +... ... |
| 131 | +I0602 04:12:03.708333 52627 analysis_predictor.cc:595] ======= optimize end ======= |
| 132 | +I0602 04:12:03.709321 52627 naive_executor.cc:98] --- skip [feed], feed -> inputs |
| 133 | +I0602 04:12:03.710139 52627 naive_executor.cc:98] --- skip [save_infer_model/scale_0.tmp_1], fetch -> fetch |
| 134 | +I0602 04:12:03.711813 52627 device_context.cc:624] oneDNN v2.2.1 |
| 135 | +WARNING: Logging before InitGoogleLogging() is written to STDERR |
| 136 | +I0602 04:12:04.106405 52627 resnet50_test.cc:73] run avg time is 394.801 ms |
| 137 | +I0602 04:12:04.106503 52627 resnet50_test.cc:88] 0 : 0 |
| 138 | +I0602 04:12:04.106525 52627 resnet50_test.cc:88] 100 : 2.04163e-37 |
| 139 | +I0602 04:12:04.106552 52627 resnet50_test.cc:88] 200 : 2.1238e-33 |
| 140 | +I0602 04:12:04.106573 52627 resnet50_test.cc:88] 300 : 0 |
| 141 | +I0602 04:12:04.106591 52627 resnet50_test.cc:88] 400 : 1.6849e-35 |
| 142 | +I0602 04:12:04.106603 52627 resnet50_test.cc:88] 500 : 0 |
| 143 | +I0602 04:12:04.106618 52627 resnet50_test.cc:88] 600 : 1.05767e-19 |
| 144 | +I0602 04:12:04.106643 52627 resnet50_test.cc:88] 700 : 2.04094e-23 |
| 145 | +I0602 04:12:04.106670 52627 resnet50_test.cc:88] 800 : 3.85254e-25 |
| 146 | +I0602 04:12:04.106683 52627 resnet50_test.cc:88] 900 : 1.52391e-30 |
| 147 | +``` --> |
| 148 | + |
| 149 | +## Python 预测部署示例 |
| 150 | + |
| 151 | +**注意**:更多 Python 预测 API 使用说明请参考 [Paddle Inference - Python API](https://paddleinference.paddlepaddle.org.cn/api_reference/python_api_index.html) |
| 152 | + |
| 153 | +**第一步**:安装 Python 预测库 |
| 154 | + |
| 155 | +Paddle MLU 版的 Python 预测库请参考 [飞桨框架 MLU 版安装说明](./paddle_install_cn.html) 进行安装或编译。 |
| 156 | + |
| 157 | +**第二步**:准备预测部署模型 |
| 158 | + |
| 159 | +下载 [ResNet50](https://paddle-inference-dist.bj.bcebos.com/Paddle-Inference-Demo/resnet50.tgz) 模型后解压,得到 Paddle 预测格式的模型,位于文件夹 ResNet50 下。如需查看模型结构,可将 inference.pdmodel 文件通过模型可视化工具 [Netron](https://netron.app/) 打开。 |
| 160 | + |
| 161 | +```bash |
| 162 | +wget https://paddle-inference-dist.bj.bcebos.com/Paddle-Inference-Demo/resnet50.tgz |
| 163 | +tar zxf resnet50.tgz |
| 164 | + |
| 165 | +# 获得模型目录即文件如下 |
| 166 | +resnet50/ |
| 167 | +├── inference.pdmodel |
| 168 | +├── inference.pdiparams.info |
| 169 | +└── inference.pdiparams |
| 170 | +``` |
| 171 | + |
| 172 | +**第三步**:准备预测部署程序 |
| 173 | + |
| 174 | +将以下代码保存为 `python_demo.py` 文件: |
| 175 | + |
| 176 | +```bash |
| 177 | +import argparse |
| 178 | +import numpy as np |
| 179 | + |
| 180 | +# 引用 paddle inference 预测库 |
| 181 | +import paddle.inference as paddle_infer |
| 182 | + |
| 183 | +def main(): |
| 184 | + args = parse_args() |
| 185 | + |
| 186 | + # 创建 config |
| 187 | + config = paddle_infer.Config(args.model_file, args.params_file) |
| 188 | + |
| 189 | + # 根据 config 创建 predictor |
| 190 | + predictor = paddle_infer.create_predictor(config) |
| 191 | + |
| 192 | + # 获取输入的名称 |
| 193 | + input_names = predictor.get_input_names() |
| 194 | + input_handle = predictor.get_input_handle(input_names[0]) |
| 195 | + |
| 196 | + # 设置输入 |
| 197 | + fake_input = np.random.randn(args.batch_size, 3, 318, 318).astype("float32") |
| 198 | + input_handle.reshape([args.batch_size, 3, 318, 318]) |
| 199 | + input_handle.copy_from_cpu(fake_input) |
| 200 | + |
| 201 | + # 运行 predictor |
| 202 | + predictor.run() |
| 203 | + |
| 204 | + # 获取输出 |
| 205 | + output_names = predictor.get_output_names() |
| 206 | + output_handle = predictor.get_output_handle(output_names[0]) |
| 207 | + output_data = output_handle.copy_to_cpu() # numpy.ndarray 类型 |
| 208 | + print("Output data size is {}".format(output_data.size)) |
| 209 | + print("Output data shape is {}".format(output_data.shape)) |
| 210 | + |
| 211 | +def parse_args(): |
| 212 | + parser = argparse.ArgumentParser() |
| 213 | + parser.add_argument("--model_file", type=str, help="model filename") |
| 214 | + parser.add_argument("--params_file", type=str, help="parameter filename") |
| 215 | + parser.add_argument("--batch_size", type=int, default=1, help="batch size") |
| 216 | + return parser.parse_args() |
| 217 | + |
| 218 | +if __name__ == "__main__": |
| 219 | + main() |
| 220 | +``` |
| 221 | +
|
| 222 | +**第四步**:执行预测程序 |
| 223 | +
|
| 224 | +```bash |
| 225 | +# 参数输入为本章节第 2 步中下载的 ResNet50 模型 |
| 226 | +python python_demo.py --model_file ./resnet50/inference.pdmodel \ |
| 227 | + --params_file ./resnet50/inference.pdiparams \ |
| 228 | + --batch_size 2 |
| 229 | + |
| 230 | +# 成功执行之后,得到的预测输出结果如下: |
| 231 | +... ... |
| 232 | +I0602 04:14:13.455812 52741 analysis_predictor.cc:595] ======= optimize end ======= |
| 233 | +I0602 04:14:13.456934 52741 naive_executor.cc:98] --- skip [feed], feed -> inputs |
| 234 | +I0602 04:14:13.458562 52741 naive_executor.cc:98] --- skip [save_infer_model/scale_0.tmp_1], fetch -> fetch |
| 235 | +Output data size is 2000 |
| 236 | +Output data shape is (2, 1000) |
| 237 | +``` |
0 commit comments