docs/demo_guides/eeasytech_npu.md
Paddle Lite 已支持 亿智 NPU (eeasytech NPU) 的预测部署。 其接入原理是使用亿智 NPU DDK(EEASYTECH DDK)。首先加载并分析 Paddle 模型,首先将 Paddle 算子转成 NNAdapter 标准算子,其次再调用 EEASYTECH DDK 组网 API 进行网络构建,在线生成并执行模型。
测试环境
编译环境
硬件环境
测试方法
paddle::lite_api::PowerMode CPU_POWER_MODE 设置为 paddle::lite_api::PowerMode::LITE_POWER_HIGH测试结果
| 模型 | SH506 | |
|---|---|---|
| CPU(ms) | NPU(ms) | |
| mobilenet_v1_int8_per_layer_log2 | 672.450012 | 47.832000 |
| mobilenet_v2_int8_per_layer_log2 | 518.518982 | 53.127300 |
您可以查阅 NNAdapter 算子支持列表获得各算子在不同新硬件上的最新支持信息。
为了保证编译环境一致,建议参考 Docker 统一编译环境搭建 中的 Docker 开发环境进行配置;
由于有些设备只提供网络访问方式(具体看开发板的实际情况),需要通过 scp 和 ssh 命令将交叉编译生成的 Paddle Lite 库和示例程序传输到设备上执行,因此,在进入 Docker 容器后还需要安装如下软件:
$ apt-get install openssh-client sshpass
下载 Paddle Lite 通用示例程序 PaddleLite-generic-demo.tar.gz ,解压后目录主体结构如下:
- PaddleLite-generic-demo
- image_classification_demo
- assets
- configs
- imagenet_224.txt # config 文件
- synset_words.txt # 1000 分类 label 文件
- datasets
- test # dataset
- inputs
- tabby_cat.jpg # 输入图片
- outputs
- tabby_cat.jpg # 输出图片
- list.txt # 图片清单
- models
- mobilenet_v1_int8_per_layer_log2
- __model__ # Paddle fluid 模型组网文件,可使用 netron 查看网络结构
— conv1_weights # Paddle fluid 模型参数文件
- batch_norm_0.tmp_2.quant_dequant.scale # Paddle fluid 模型量化参数文件
— subgraph_partition_config_file.txt # 自定义子图分割配置文件
...
- shell
- CMakeLists.txt # 示例程序 CMake 脚本
- build.linux.arm64 # arm64 编译工作目录
- demo # 已编译好的,适用于 arm64 的示例程序
- build.linux.armhf # armhf编译工作目录
- demo # 已编译好的,适用于 armhf 的示例程序
...
- demo.cc # 示例程序源码
- build.sh # 示例程序编译脚本
- run.sh # 示例程序本地运行脚本
- run_with_ssh.sh # 示例程序ssh运行脚本
- run_with_adb.sh # 示例程序adb运行脚本
- libs
- PaddleLite
- linux
- armhf # Linux 32 位系统
- include # Paddle Lite 头文件
- lib # Paddle Lite 库文件
- eeasytech_npu # 亿智 NPU DDK、NNAdapter 运行时库、device HAL 库
- libnnadapter.so # NNAdapter 运行时库
- libeeasytech_npu.so.so # NNAdapter device HAL 库
- libeznpu_ddk.so.so # 亿智 NPU DDK
- libnn.so # 亿智 DDK
- libopenvx-nn.so # 亿智 DDK
- libopenvx.so # 亿智 DDK
- libsoft-nn.so # 亿智 DDK
- libpaddle_full_api_shared.so # 预编译 Paddle Lite full api 库
- libpaddle_light_api_shared.so # 预编译 Paddle Lite light api 库
...
- android
- OpenCV # OpenCV 预编译库
- object_detection_demo # 目标检测示例程序
按照以下命令分别运行转换后的 ARM CPU 模型和 亿智 NPU 模型,比较它们的性能和结果;
注意:
1)`run_with_adb.sh` 不能在 Docker 环境执行,否则可能无法找到设备,也不能在设备上运行。
2)`run_with_ssh.sh` 不能在设备上运行,且执行前需要配置目标设备的IP地址、SSH账号和密码。
3)`build.sh` 根据入参生成针对不同操作系统、体系结构的二进制程序,需查阅注释信息配置正确的参数值。
4)`run_with_adb.sh` 入参包括模型名称、操作系统、体系结构、目标设备、设备序列号等,需查阅注释信息配置正确的参数值。
5)`run_with_ssh.sh` 入参包括模型名称、操作系统、体系结构、目标设备、ip 地址、用户名、用户密码等,需查阅注释信息配置正确的参数值。
6)下述命令行示例中涉及的具体IP、SSH账号密码、设备序列号等均为示例环境,请用户根据自身实际设备环境修改。
在 ARM CPU 上运行 mobilenet_v1_int8_per_layer_log2 全量化模型
$ cd PaddleLite-generic-demo/image_classification_demo/shell
For SH506 CPU
$ ./run_with_adb.sh mobilenet_v1_int8_per_layer_log2 imagenet_224.txt test linux armhf cpu adb设备号
(RK1808 EVB)
Top1 tabby, tabby cat - 0.751034
Top2 Egyptian cat - 0.183955
Top3 tiger cat - 0.045455
Top4 lynx, catamount - 0.003305
Top5 ping-pong ball - 0.002057
Preprocess time: 59.751000 ms, avg 59.751000 ms, max 59.751000 ms, min 59.751000 ms
Prediction time: 679.279000 ms, avg 679.279000 ms, max 679.279000 ms, min 679.279000 ms
Postprocess time: 58.927000 ms, avg 58.927000 ms, max 58.927000 ms, min 58.927000 ms
------------------------------
在 EEASYTECH NPU 上运行 mobilenet_v1_int8_per_layer_log2 全量化模型
$ cd PaddleLite-generic-demo/image_classification_demo/shell
For SH506 NPU
$ ./run_with_adb.sh mobilenet_v1_int8_per_layer_log2 imagenet_224.txt test linux armhf eeasytech_npu adb设备号
Top1 tabby, tabby cat - 0.725007
Top2 Egyptian cat - 0.183262
Top3 tiger cat - 0.054423
Top4 ping-pong ball - 0.003798
Top5 lynx, catamount - 0.003338
Preprocess time: 61.407000 ms, avg 61.407000 ms, max 61.407000 ms, min 61.407000 ms
Prediction time: 48.100000 ms, avg 48.100000 ms, max 48.100000 ms, min 48.100000 ms
Postprocess time: 59.201000 ms, avg 59.201000 ms, max 59.201000 ms, min 59.201000 ms
如果需要更改测试图片,可将图片拷贝到 PaddleLite-generic-demo/image_classification_demo/assets/datasets/test/inputs 目录下,同时将图片文件名添加到 PaddleLite-generic-demo/image_classification_demo/assets/datasets/test/list.txt 中;
重新编译示例程序:
注意:
1)请根据 `buid.sh`配置正确的参数值。
2)需在 Docker 环境中编译。
$ ./build.sh linux armhf
- PaddleSlim-quant-demo
- image_classification_demo
- quant_post # 后量化
- quant_post_rockchip_npu.sh # 一键量化脚本
- README.md # 环境配置说明,涉及 PaddlePaddle、PaddleSlim 的版本选择、编译和安装步骤
- datasets # 量化所需要的校准数据集合
- ILSVRC2012_val_100 # 从 ImageNet2012 验证集挑选的 100 张图片
- inputs # 待量化的 fp32 模型
- mobilenet_v1
- resnet50
- outputs # 产出的全量化模型
- scripts # 后量化内置脚本
README.md 完成 PaddlePaddle 和 PaddleSlim 的安装python -c "import paddle; print(paddle)" 找到 PaddlePaddle 的 python 包,例如 '/usr/local/lib/python3.7/site-packages/paddle/init.py',既 PaddlePaddle 的 python 包路径为 '/usr/local/lib/python3.7/site-packages/paddle/',进入该目录,并找到文件fluid/contrib/slim/quantization/post_training_quantization.py,备份./quant_post_rockchip_npu.sh 即可在 outputs 目录下生成 mobilenet_v1_int8_per_layer_log2 量化模型
----------- Configuration Arguments -----------
activation_bits: 8
activation_quantize_type: moving_average_abs_max
algo: KL
batch_nums: 10
batch_size: 10
data_dir: ../dataset/ILSVRC2012_val_100
is_full_quantize: 1
is_use_cache_file: 0
model_path: ../models/mobilenet_v1
optimize_model: 1
output_path: ../outputs/mobilenet_v1
quantizable_op_type: conv2d,depthwise_conv2d,mul
use_gpu: 0
use_slim: 1
weight_bits: 8
weight_quantize_type: abs_max
------------------------------------------------
quantizable_op_type:['conv2d', 'depthwise_conv2d', 'mul']
2021-08-30 05:52:10,048-INFO: Load model and set data loader ...
2021-08-30 05:52:10,129-INFO: Optimize FP32 model ...
I0830 05:52:10.139564 14447 graph_pattern_detector.cc:91] --- detected 14 subgraphs
I0830 05:52:10.148236 14447 graph_pattern_detector.cc:91] --- detected 13 subgraphs
2021-08-30 05:52:10,167-INFO: Collect quantized variable names ...
2021-08-30 05:52:10,168-WARNING: feed is not supported for quantization.
2021-08-30 05:52:10,169-WARNING: fetch is not supported for quantization.
2021-08-30 05:52:10,170-INFO: Preparation stage ...
2021-08-30 05:52:11,853-INFO: Run batch: 0
2021-08-30 05:52:16,963-INFO: Run batch: 5
2021-08-30 05:52:21,037-INFO: Finish preparation stage, all batch:10
2021-08-30 05:52:21,048-INFO: Sampling stage ...
2021-08-30 05:52:31,800-INFO: Run batch: 0
2021-08-30 05:53:23,443-INFO: Run batch: 5
2021-08-30 05:54:03,773-INFO: Finish sampling stage, all batch: 10
2021-08-30 05:54:03,774-INFO: Calculate KL threshold ...
2021-08-30 05:54:28,580-INFO: Update the program ...
2021-08-30 05:54:29,194-INFO: The quantized model is saved in ../outputs/mobilenet_v1
post training quantization finish, and it takes 139.42292165756226.
----------- Configuration Arguments -----------
batch_size: 20
class_dim: 1000
data_dir: ../dataset/ILSVRC2012_val_100
image_shape: 3,224,224
inference_model: ../outputs/mobilenet_v1
input_img_save_path: ./img_txt
save_input_img: False
test_samples: -1
use_gpu: 0
------------------------------------------------
Testbatch 0, acc1 0.8, acc5 1.0, time 1.63 sec
End test: test_acc1 0.76, test_acc5 0.92
--------finish eval int8 model: mobilenet_v1-------------
valid_targets 设置为 eeasytech_npu,arm 即可。$ ./opt --model_dir=mobilenet_v1_int8_224_per_layer \
--optimize_out_type=naive_buffer \
--optimize_out=opt_model \
--valid_targets=eeasytech_npu,arm
下载 Paddle Lite 源码和 EEASYTECH NPU DDK
$ git clone https://github.com/PaddlePaddle/Paddle-Lite.git
$ cd Paddle-Lite
$ git checkout <release-version-tag>
$ wget https://paddlelite-demo.bj.bcebos.com/devices/eeasytech/eznpu_ddk.tar.gz
$ tar -zxvf eznpu_ddk.tar.gz
编译并生成 Paddle Lite + EEASYTECH NPU for armhf 的部署库
tiny_publish 编译方式
$ ./lite/tools/build_linux.sh --toolchain=clang --with_extra=ON --with_log=ON --with_exception=ON --arch=armv7hf --with_nnadapter=ON --nnadapter_with_eeasytech_npu=ON --nnadapter_eeasytech_npu_sdk_root=$(pwd)/eznpu_ddk
full_publish 编译方式
$ ./lite/tools/build_linux.sh --toolchain=clang --with_extra=ON --with_log=ON --with_exception=ON --arch=armv7hf --with_nnadapter=ON --nnadapter_with_eeasytech_npu=ON --nnadapter_eeasytech_npu_sdk_root=$(pwd)/eznpu_ddk full_publish
替换头文件和库
替换 include 目录
$ cp -rf build.lite.linux.armv7hf.clang/inference_lite_lib.armlinux.armv7hf.nnadapter/cxx/include/ PaddleLite-generic-demo/libs/PaddleLite/linux/armhf/include/
替换 NNAdapter 运行时库
$ cp -rf build.lite.linux.armv7hf.clang/inference_lite_lib.armlinux.armv7hf.nnadapter/cxx/lib/libnnadapter.so PaddleLite-generic-demo/libs/PaddleLite/linux/armhf/lib/eeasytech_npu/
替换 NNAdapter device HAL 库
$ cp -rf build.lite.linux.armv7hf.clang/inference_lite_lib.armlinux.armv7hf.nnadapter/cxx/lib/libeeasytech_npu.so PaddleLite-generic-demo/libs/PaddleLite/linux/armhf/lib/eeasytech_npu/
替换 libpaddle_light_api_shared.so
$ cp -rf build.lite.linux.armv7hf.clang/inference_lite_lib.armlinux.armv7hf.nnadapter/cxx/lib/libpaddle_light_api_shared.so PaddleLite-generic-demo/libs/PaddleLite/linux/armhf/lib/
替换 libpaddle_full_api_shared.so (仅在 full_publish 编译方式下)
$ cp -rf build.lite.linux.armv7hf.clang/inference_lite_lib.armlinux.armv7hf.nnadapter/cxx/lib/libpaddle_full_api_shared.so PaddleLite-generic-demo/libs/PaddleLite/linux/armhf/lib/
替换头文件后需要重新编译示例程序