diff --git a/docs/demo_guides/huawei_kirin_npu.md b/docs/demo_guides/huawei_kirin_npu.md new file mode 100644 index 0000000000000000000000000000000000000000..4e3fb3072a004050639e7ca862f67af1e479ce76 --- /dev/null +++ b/docs/demo_guides/huawei_kirin_npu.md @@ -0,0 +1,472 @@ +# PaddleLite使用华为NPU(Kirin SoC)预测部署 + +Paddle Lite是首款支持华为自研达芬奇架构NPU(Kirin 810/990 SoC搭载的NPU)的预测框架。 +原理是在线分析Paddle模型,将Paddle算子转成HiAI IR后,调用HiAI IR/Builder/Runtime APIs生成并执行HiAI模型。 + +## 支持现状 + +### 已支持的芯片 +- Kirin 810/990/9000。 + +### 已支持的设备 + +- HUAWEI nova5、nova5i Pro、mate30、mate30 pro、mate30 5G、荣耀v30、p40、p40 pro和即将推出的mate40。 + +### 已支持的Paddle模型 + +- [MobileNetV1](https://paddlelite-demo.bj.bcebos.com/models/mobilenet_v1_fp32_224_fluid.tar.gz) +- [MobileNetV2](https://paddlelite-demo.bj.bcebos.com/models/mobilenet_v2_fp32_224_fluid.tar.gz) +- ResNet系列(例如[ResNet18](https://paddlelite-demo.bj.bcebos.com/models/resnet18_fp32_224_fluid.tar.gz)、[ResNet50](https://paddlelite-demo.bj.bcebos.com/models/resnet50_fp32_224_fluid.tar.gz)) +- [SqueezeNet](https://paddlelite-demo.bj.bcebos.com/models/squeezenet_fp32_224_fluid.tar.gz) +- [MnasNet](https://paddlelite-demo.bj.bcebos.com/models/mnasnet_fp32_224_fluid.tar.gz) +- [MobileNet-SSD](https://paddlelite-demo.bj.bcebos.com/models/ssd_mobilenet_v1_pascalvoc_fp32_300_fluid.tar.gz) * +- YOLOv3系列(例如[YOLOv3-MobileNetV3](https://paddlelite-demo.bj.bcebos.com/models/yolov3_mobilenet_v3_prune86_FPGM_320_fp32_fluid.tar.gz)) * +- [Transformer](https://github.com/PaddlePaddle/models/tree/release/1.8/PaddleNLP/machine_translation/transformer) * +- CycleGAN +- 百度内部业务模型(由于涉密,不方便透露具体细节) + +带*表示该模型的部分算子不支持NPU加速,而是采用CPU+NPU异构计算方式获得支持。 + +### 已支持(或部分支持)的Paddle算子 + +| | | | | +|-|-|-|-| +|sigmoid|relu|tanh|relu_clipped| +|leaky_relu|softsign|hard_sigmoid|log| +|sqrt|square|thresholded_relu|batch_norm| +|less_than|concat|conv2d|depthwise_conv2d| +|conv2d_transpose|dropout|elementwise_add|elementwise_sub| +|elementwise_mul|elementwise_div|expand|fusion_elementwise_add_activation| +|fusion_elementwise_sub_activation|fusion_elementwise_mul_activation|fusion_elementwise_div_activation|increment| +|instance_norm (需要HiAI DDK330)|layer_norm (需要HiAI DDK330)|fc|bilinear_interp| +|nearest_interp|matmul|mul|pad2d| +|pool2d|reduce_mean|reshape|reshape2| +|scale|shuffle_channel|softmax|split| +|transpose|transpose2|unsqueeze|unsqueeze2| + +可以通过访问[https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/kernels/npu/bridges/paddle_use_bridges.h](https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/kernels/npu/bridges/paddle_use_bridges.h)获得最新的算子支持列表。 + +## 参考示例演示 + +### 测试设备(HUAWEI Mate30 5G) +![huwei_mate30_5g](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/huawei_mate30_5g.jpg) + +### 准备设备环境 + +- 由于HiAI DDK可能依赖特定版本的ROM,建议用户更新至最新版EMUI系统,具体参考华为官方[手机升级指南](https://consumer.huawei.com/cn/support/update/)。 + +### 准备交叉编译环境 + +- 为了保证编译环境一致,建议参考[源码编译](../user_guides/source_compile)中的Docker开发环境进行配置。 + +### 运行图像分类示例程序 + +- 从[https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/PaddleLite-android-demo.tar.gz](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/PaddleLite-android-demo.tar.gz)下载示例程序,解压后清单如下: + + ```shell + - PaddleLite-android-demo + - image_classification_demo # 基于MobileNetV1的图像分类示例程序 + - assets + - images + - tabby_cat.jpg # 测试图片 + - labels + - synset_words.txt # 1000分类label文件 + - models + - mobilenet_v1_fp32_224_fluid # Paddle fluid non-combined格式的mobilenetv1 float32模型 + - mobilenet_v1_fp32_224_for_cpu + - model.nb # 已通过opt转好的、适合ARM CPU的mobilenetv1模型 + - mobilenet_v1_fp32_224_for_npu + - model.nb # 已通过opt转好的、适合华为 NPU的mobilenetv1模型 + - shell # android shell端的示例程序,注意:HiAI存在限制,拥有ROOT权限才能正常运行shell端程序 + - CMakeLists.txt # android shell端的示例程序CMake脚本 + - build + - image_classification_demo # 已编译好的android shell端的示例程序 + - image_classification_demo.cc # 示例程序源码 + - build.sh # android shell端的示例程序编译脚本 + - run.sh # android shell端的示例程序运行脚本 + - apk # 常规android应用程序,无需ROOT + - app + - src + - main + - java # java层代码 + - cpp # 自定义的jni实现 + - app.iml + - build.gradle + - gradle + ... + - libs + - PaddleLite + - bin + - opt # 适合Ubuntu x86平台、预编译的模型优化工具 + - armeabi-v7a # 适合armv7架构的PaddleLite预编译库以及HiAI运行时库 + - include # PaddleLite头文件,每次版本更新时记得替换掉,否则可能会出现segmentation fault或精度无法对齐的问题 + - lib + - libc++_shared.so # HiAI DDK中的so库是基于c++_shared编译生成的,部署时记得带上它 + - libpaddle_light_api_shared.so # 用于最终移动端部署的预编译PaddleLite库(tiny publish模式下编译生成的库) + - libpaddle_full_api_shared.so # 用于直接加载Paddle模型进行测试和Debug的预编译PaddleLite库(full publish模式下编译生成的库) + - libhiai.so # HiAI runtime库函数,主要实现模型加载、执行和Tensor的操作 + - libhiai_ir.so # HiAI IR/Graph的定义 + - libhiai_ir_build.so # HiAI IRGraph转om模型的接口 + - libhcl.so # HiAI NPU高性能算子库 + - libcpucl.so # HiAI的CPU算子库,PaddleLite中没有用到,理论上可以删掉 + - arm64-v8a # 适合armv8架构的PaddleLite预编译库以及HiAI运行时库 + - OpenCV # OpenCV 4.2 for android + - object_detection_demo # 基于YOLOv3_MobileNetV3的目标检测示例程序(手动子图划分章节会详细介绍) + ``` + +- Android shell端的示例程序 + - 按照以下命令分别运行转换后的ARM CPU模型和华为NPU模型,比较它们的性能和结果; + + ```shell + 注意: + 1)run.sh只能在连接设备的系统上运行,不能在docker环境执行(可能无法找到设备),也不能在设备上运行; + 2)build.sh需要在docker环境中执行,否则,需要将build.sh的ANDROID_NDK修改为当前环境下的NDK路径; + 3)以下执行结果均由armeabi-v7a库生成,如果需要测试arm64-v8a库,可将build.sh的ANDROID_ABI修改成arm64-v8a后重新生成image_classification_demo,同时将run.sh的ANDROID_ABI也修改成arm64-v8a即可)。 + + 运行适用于华为NPU的mobilenetv1模型 + $ cd PaddleLite-android-demo/image_classification_demo/assets/models + $ cp mobilenet_v1_fp32_224_for_npu/model.nb mobilenet_v1_fp32_224_fluid.nb + $ cd ../../shell + $ ./run.sh + ... + iter 0 cost: 2.426000 ms + iter 1 cost: 2.428000 ms + iter 2 cost: 2.465000 ms + iter 3 cost: 2.401000 ms + iter 4 cost: 2.406000 ms + iter 5 cost: 2.492000 ms + iter 6 cost: 2.411000 ms + iter 7 cost: 2.397000 ms + iter 8 cost: 2.441000 ms + iter 9 cost: 2.402000 ms + warmup: 5 repeat: 10, average: 2.426900 ms, max: 2.492000 ms, min: 2.397000 ms + results: 3 + Top0 tabby, tabby cat - 0.477539 + Top1 Egyptian cat - 0.408447 + Top2 tiger cat - 0.094788 + Preprocess time: 1.724000 ms + Prediction time: 2.426900 ms + Postprocess time: 0.127000 ms + + 运行适用于ARM CPU的mobilenetv1模型 + $ cd PaddleLite-android-demo/image_classification_demo/assets/models + $ cp mobilenet_v1_fp32_224_for_cpu/model.nb mobilenet_v1_fp32_224_fluid.nb + $ cd ../../shell + $ ./run.sh + ... + iter 0 cost: 34.467999 ms + iter 1 cost: 34.514999 ms + iter 2 cost: 34.646000 ms + iter 3 cost: 34.713001 ms + iter 4 cost: 34.612000 ms + iter 5 cost: 34.551998 ms + iter 6 cost: 34.741001 ms + iter 7 cost: 34.655998 ms + iter 8 cost: 35.035000 ms + iter 9 cost: 34.661999 ms + warmup: 5 repeat: 10, average: 34.659999 ms, max: 35.035000 ms, min: 34.467999 ms + results: 3 + Top0 tabby, tabby cat - 0.475009 + Top1 Egyptian cat - 0.409486 + Top2 tiger cat - 0.095744 + Preprocess time: 1.714000 ms + Prediction time: 34.659999 ms + Postprocess time: 0.082000 ms + ``` + + - 如果需要更改测试图片,可将图片拷贝到PaddleLite-android-demo/image_classification_demo/assets/images目录下,然后将run.sh的IMAGE_NAME设置成指定文件名即可; + - 如果需要重新编译示例程序,直接运行./build.sh即可。 + +- 常规Android应用程序 + + (如果不想按照以下步骤编译Android应用程序,可以直接在Android设备上通过浏览器访问[https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/image_classification_demo.apk](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/image_classification_demo.apk)下载和安装已编译好的apk) + - 访问[https://developer.android.google.cn/studio](https://developer.android.google.cn/studio/)下载安装Android Studio(当前Android demo app是基于Android Studio3.4开发的),如果无法访问,可以从[http://www.android-studio.org](http://www.android-studio.org/)下载; + - 打开Android Studio,在"Welcome to Android Studio"窗口点击"Open an existing Android Studio project",在弹出的路径选择窗口中进入"PaddleLite-android-demo/image_classification_demo/apk"目录,然后点击右下角的"Open"按钮即可导入工程; + - 通过USB连接Android手机、平板或开发板; + - 待工程加载完成后,首先,点击菜单栏的File->Sync Project with Gradle Files手动同步项目构建;然后,点击菜单栏的Build->Rebuild Project按钮,如果提示CMake版本不匹配,请点击错误提示中的'Install CMake xxx.xxx.xx'按钮,重新安装CMake,再次点击菜单栏的Build->Rebuild Project按钮; + - 待工程编译完成后,点击菜单栏的Run->Run 'App'按钮,在弹出的"Select Deployment Target"窗口选择已经连接的Android设备,然后点击"OK"按钮; + - 等待大约1分钟后(第一次时间比较长,需要耐心等待),app已经安装到设备上。默认使用ARM CPU模型进行推理,如下图所示,推理耗时34.8ms,整个流程(含预处理和后处理)的帧率约22fps; + + ![huawei_mate30_5g_mobilenet_v1_cpu](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/huawei_mate30_5g_mobilenet_v1_cpu.jpg) + + - 点击app界面右下角的设置按钮,在弹出的设置页面点击"Choose pre-installed models",选择"mobilenet_v1_fp32_for_npu",点击返回按钮后,app将切换到华为NPU模型,如下图所示,推理耗时下降到3.4ms,帧率提高到29fps(由于代码中帧率统计限制在30fps以内,因此实际帧率会更高,具体地,您可以手动计算截图中Read GLFBO time、Write GLTexture time、Predict time和Postprocess time的总耗时)。 + + ![huaewi_mate30_5g_mobilenet_v1_npu](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/huawei_mate30_5g_mobilenet_v1_npu.jpg) + + +### 更新模型 + +- 通过Paddle Fluid训练,或X2Paddle转换得到MobileNetv1 foat32模型[mobilenet_v1_fp32_224_fluid](https://paddlelite-demo.bj.bcebos.com/models/mobilenet_v1_fp32_224_fluid.tar.gz); +- 参考[模型转化方法](../user_guides/model_optimize_tool),利用opt工具转换生成华为NPU模型,仅需将valid_targets设置为npu,arm即可。 + + ```shell + 注意:为了保证opt工具和库版本一致,使用了PaddleLite-android-demo.tar.gz自带的opt程序(需要在Ubuntu x86平台执行)演示NPU模型生成的过程。 + $ cd PaddleLite-android-demo/image_classification_demo/assets/models + $ GLOG_v=5 ../../../libs/PaddleLite/bin/opt --model_dir=mobilenet_v1_fp32_224_fluid \ + --optimize_out_type=naive_buffer \ + --optimize_out=opt_model \ + --valid_targets=npu,arm + ... + [I 8/12 6:56:25.460 ...elease/Paddle-Lite/lite/core/optimizer.h:229 RunPasses] == Running pass: memory_optimize_pass + [I 8/12 6:56:25.460 ...elease/Paddle-Lite/lite/core/optimizer.h:242 RunPasses] - Skip memory_optimize_pass because the target or kernel does not match. + [I 8/12 6:56:25.461 ...te/lite/core/mir/generate_program_pass.h:37 GenProgram] insts.size 1 + [I 8/12 6:56:25.683 ...e-Lite/lite/model_parser/model_parser.cc:593 SaveModelNaive] Save naive buffer model in 'opt_model.nb' successfully + + 替换自带的NPU模型 + $ cp opt_model.nb mobilenet_v1_fp32_224_for_npu/model.nb + ``` + +- 注意:opt生成的模型只是标记了华为NPU支持的Paddle算子,并没有真正生成华为NPU模型,只有在执行时才会将标记的Paddle算子转成HiAI IR并组网得到HiAI IRGraph,然后生成并执行华为NPU模型(具体原理请参考Pull Request[#2576](https://github.com/PaddlePaddle/Paddle-Lite/pull/2576)); +- 不同模型,不同型号(ROM版本)的华为手机,在执行阶段,由于某些Paddle算子无法完全转成HiAI IR,或目标手机的HiAI版本过低等原因,可能导致HiAI模型无法成功生成,在这种情况下,Paddle Lite会调用CPU版算子进行运算完成整个预测任务。 + +### 更新支持华为NPU的PaddleLite库 + +- 下载PaddleLite源码和最新版HiAI DDK + + ```shell + $ git clone https://github.com/PaddlePaddle/Paddle-Lite.git + $ cd Paddle-Lite + $ git checkout + $ wget https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/hiai_ddk_lib_330.tar.gz + $ tar -xvf hiai_ddk_lib_330.tar.gz + ``` + +- 编译并生成PaddleLite+NPU for armv8 and armv7的部署库 + + ```shell + For armv8 + tiny_publish + $ ./lite/tools/build_android.sh --android_stl=c++_shared --with_extra=ON --with_log=ON --with_huawei_kirin_npu=ON --huawei_kirin_npu_sdk_root=./hiai_ddk_lib_330 + full_publish + $ ./lite/tools/build_android.sh --android_stl=c++_shared --with_extra=ON --with_log=ON --with_huawei_kirin_npu=ON --huawei_kirin_npu_sdk_root=./hiai_ddk_lib_330 full_publish + + For armv7 + tiny_publish + $ ./lite/tools/build_android.sh --arch=armv7 --android_stl=c++_shared --with_extra=ON --with_log=ON --with_huawei_kirin_npu=ON --huawei_kirin_npu_sdk_root=./hiai_ddk_lib_330 + full_publish + $ ./lite/tools/build_android.sh --arch=armv7 --android_stl=c++_shared --with_extra=ON --with_log=ON --with_huawei_kirin_npu=ON --huawei_kirin_npu_sdk_root=./hiai_ddk_lib_330 full_publish + + 备注:由于HiAI DDK的so库均基于c++_shared构建,建议将android stl设置为c++_shared,更多选项还可以通过 "./lite/tools/build_android.sh help" 查看。 + ``` + +- 将编译生成的build.lite.android.armv8.gcc/inference_lite_lib.android.armv8.npu/cxx/include替换PaddleLite-android-demo/libs/PaddleLite/arm64-v8a/include目录; +- 将tiny_publish模式下编译生成的build.lite.android.armv8.gcc/inference_lite_lib.android.armv8.npu/cxx/lib/libpaddle_light_api_shared.so替换PaddleLite-android-demo/libs/PaddleLite/arm64-v8a/lib/libpaddle_light_api_shared.so文件; +- 将full_publish模式下编译生成的build.lite.android.armv8.gcc/inference_lite_lib.android.armv8.npu/cxx/lib/libpaddle_full_api_shared.so替换PaddleLite-android-demo/libs/PaddleLite/arm64-v8a/lib/libpaddle_full_api_shared.so文件; +- 将编译生成的build.lite.android.armv7.gcc/inference_lite_lib.android.armv7.npu/cxx/include替换PaddleLite-android-demo/libs/PaddleLite/armeabi-v7a/include目录; +- 将tiny_publish模式下编译生成的build.lite.android.armv7.gcc/inference_lite_lib.android.armv7.npu/cxx/lib/libpaddle_light_api_shared.so替换PaddleLite-android-demo/libs/PaddleLite/armeabi-v7a/lib/libpaddle_light_api_shared.so文件; +- 将full_publish模式下编译生成的build.lite.android.armv7.gcc/inference_lite_lib.android.armv7.npu/cxx/lib/libpaddle_full_api_shared.so替换PaddleLite-android-demo/libs/PaddleLite/armeabi-v7a/lib/libpaddle_full_api_shared.so文件。 + +## 如何支持CPU+NPU异构计算? + +- 上述示例中所使用的MobileNetv1 foat32模型[mobilenet_v1_fp32_224_fluid](https://paddlelite-demo.bj.bcebos.com/models/mobilenet_v1_fp32_224_fluid.tar.gz),它的所有算子均能成功转成华为NPU的HiAI IR,因此,能够获得非常好的NPU加速效果; +- 而实际情况是,你的模型中可能存在NPU不支持的算子,尽管opt工具可以成功生成CPU+NPU的异构模型,但可能因为一些限制等原因,模型最终执行失败或性能不够理想; +- 我们首先用一个简单的目标检测示例程序让你直观感受到CPU+NPU异构模型带来的性能提升;然后,简要说明一下华为NPU接入PaddleLite的原理;最后,详细介绍如何使用『自定义子图分割』功能生成正常运行的CPU+NPU异构模型。 + +### 运行目标检测示例程序 + +- 『运行图像分类示例程序』章节中的PaddleLite-android-demo.tar.gz同样包含基于[YOLOv3_MobileNetV3](https://paddlelite-demo.bj.bcebos.com/models/yolov3_mobilenet_v3_prune86_FPGM_320_fp32_fluid.tar.gz)的目标检测示例程序; + + ```shell + - PaddleLite-android-demo + - image_classification_demo # 基于MobileNetV1的图像分类示例程序 + - libs # PaddleLite和OpenCV预编译库 + - object_detection_demo # 基于YOLOv3_MobileNetV3的目标检测示例程序 + - assets + - images + - kite.jpg # 测试图片 + - labels + - coco-labels-2014_2017.txt # coco数据集的label文件 + - models + - yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid # Paddle fluid combined格式的、剪枝后的YOLOv3_MobileNetV3 float32模型 + - yolov3_mobilenet_v3_prune86_FPGM_fp32_320_for_cpu + - model.nb # 已通过opt转好的、适合CPU的YOLOv3_MobileNetV3模型 + - yolov3_mobilenet_v3_prune86_FPGM_fp32_320_for_hybrid_cpu_npu + - model.nb # 已通过opt转好的、适合NPU+CPU的YOLOv3_MobileNetV3异构模型 + - subgraph_custom_partition_config_file.txt # YOLOv3_MobileNetV3自定义子图分割配置文件 + - shell # android shell端的示例程序,注意:HiAI存在限制,拥有ROOT权限才能正常运行shell端程序 + - CMakeLists.txt # android shell端的示例程序CMake脚本 + - build + - object_detection_demo # 已编译好的android shell端的示例程序 + - object_detection_demo.cc.cc # 示例程序源码 + - build.sh # android shell端的示例程序编译脚本 + - run.sh # android shell端的示例程序运行脚本 + - apk # 常规android应用程序,无需ROOT + ``` + +- 运行Android shell端的示例程序 + - 参考『运行图像分类示例程序』章节的类似步骤,通过以下命令比较CPU模型、CPU+NPU异构模型的性能和结果; + + ```shell + 运行YOLOv3_MobileNetV3 CPU模型 + $ cd PaddleLite-android-demo/object_detection_demo/assets/models + $ cp yolov3_mobilenet_v3_prune86_FPGM_fp32_320_for_cpu/model.nb yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid.nb + $ cd ../../shell + $ ./run.sh + ... + warmup: 5 repeat: 10, average: 53.963000 ms, max: 54.161999 ms, min: 53.562000 ms + results: 24 + [0] person - 0.986361 211.407288,334.633301,51.627228,133.759537 + [1] person - 0.879052 261.493347,342.849823,40.597961,120.775108 + ... + [22] kite - 0.272905 362.982941,119.011330,14.060059,11.157372 + [23] kite - 0.254866 216.051910,175.607956,70.241974,23.265827 + Preprocess time: 4.882000 ms + Prediction time: 53.963000 ms + Postprocess time: 0.548000 ms + + 运行YOLOv3_MobileNetV3 CPU+NPU异构模型 + $ cd PaddleLite-android-demo/object_detection_demo/assets/models + $ cp yolov3_mobilenet_v3_prune86_FPGM_fp32_320_for_hybrid_cpu_npu/model.nb yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid.nb + $ cd ../../shell + $ ./run.sh + ... + warmup: 5 repeat: 10, average: 23.767200 ms, max: 25.287001 ms, min: 22.292000 ms + results: 24 + [0] person - 0.986164 211.420929,334.705780,51.559906,133.627930 + [1] person - 0.879287 261.553680,342.857300,40.531372,120.751106 + ... + [22] kite - 0.271422 362.977722,119.014709,14.053833,11.162636 + [23] kite - 0.257437 216.123276,175.631500,70.095078,23.248249 + Preprocess time: 4.951000 ms + Prediction time: 23.767200 ms + Postprocess time: 1.015000 ms + ``` + +- 运行常规Android应用程序 + + (如果不想按照以下步骤编译Android应用程序,可以直接在Android设备上通过浏览器访问[https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/object_detection_demo.apk](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/object_detection_demo.apk)下载和安装已编译好的apk) + - 参考『运行图像分类示例程序』章节的类似步骤,通过Android Studio导入"PaddleLite-android-demo/object_detection_demo/apk"工程,生成和运行常规Android应用程序; + - 默认使用ARM CPU模型进行推理,如下图所示,推理耗时55.1ms,整个流程(含预处理和后处理)的帧率约15fps; + + ![huawei_mate30_5g_yolov3_mobilenet_v3_cpu](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/huawei_mate30_5g_yolov3_mobilenet_v3_cpu.jpg) + + - 选择"yolov3_mobilenet_v3_for_hybrid_cpu_npu"后,如下图所示,推理耗时下降到26.9ms,帧率提高到28fps + + ![huawei_mate30_5g_yolov3_mobilenet_v3_hybrid_cpu_npu](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/huawei_mate30_5g_yolov3_mobilenet_v3_hybrid_cpu_npu.jpg) + +### PaddleLite是如何支持华为NPU的? + +- PaddleLite是如何加载Paddle模型并执行一次推理的? + - 如下图左半部分所示,Paddle模型的读取和执行,经历了Paddle推理模型文件的加载和解析、计算图的转化、图分析和优化、运行时程序的生成和执行等步骤: + + ![how_to_intergrate_hiai_to_paddlelite](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/how_to_intergrate_hiai_to_paddlelite.png) + + - Paddle推理模型文件的加载和解析:基于ProtoBuf协议对Paddle推理模型文件进行反序列化,解析生成网络结构(描述算子和张量的关系)和参数信息(包括算子属性和权重张量); + - 计算图的转化:为了更好的描述网络拓扑结构和方便后续的优化,依据算子的输入、出张量关系,构建一个由算子节点、张量节点组成的有向无环图; + - 图分析和优化:由一些列pass(优化器)组成,pass是用于描述一个计算图优化生成另一个计算图的过程;例如conv2d_bn_fuse_pass,它用于将模型中每一个conv2d、batch_norm相连的算子对融合成一个conv2d算子以便获得性能上的提升; + - 运行时程序的生成和执行:按照拓扑顺序遍历最终优化后的计算图,生成算子kernel列表,依次执行每一个算子kernel后即完成一次模型的推理。 +- PaddleLite是如何支持华为NPU呢? + - 为了支持华为NPU,我们额外增加了(如上图标黄的区域):Subgraph detection pass、NPU subgraph op kernel和Paddle2HiAI op/tensor bridges。其中Subgraph detection pass是后续自定义子图划分涉及的关键步骤; + - Subgraph detection pass:该pass的作用是遍历计算图中所有的算子节点,标记能够转成HiAI IR的算子节点,然后通过图分割算法,将那些支持转为HiAI IR的、相邻的算子节点融合成一个subgraph(子图)算子节点(需要注意的是,这个阶段算子节点并没有真正转为HiAI IR,更没有生成HiAI模型); + - NPU subgraph op kernel:根据Subgraph detection pass的分割结果,在生成的算子kernel列表中,可能存在多个subgraph算子kernel;每个subgraph算子kernel,都会将它所包裹的、能够转成HiAI IR的、所有Paddle算子,如上图右半部所示,依次调用对应的op bridge,组网生成一个HiAI Graph,最终,调用HiAI Runtime APIs生成并执行NPU模型; + - Paddle2HiAI op/tensor bridges:Paddle算子/张量转HiAI IR/tensor的桥接器,其目的是将Paddle算子、输入、输出张量转为HiAI组网IR和常量张量。 + +### 编写配置文件完成自定义子图分割,生成华为NPU与ARM CPU的异构模型 + +- 为什么需要进行手动子图划分?如果模型中存在不支持转HiAI IR的算子,Subgraph detection pass会在没有人工干预的情况下,可能将计算图分割为许多小的子图,而出现如下问题: + - 过多的子图会产生频繁的CPU<->NPU数据传输和NPU任务调度,影响整体性能; + - 由于NPU模型暂时不支持dynamic shape,因此,如果模型中存在输入和输出不定长的算子(例如一些检测类算子,NLP类算子),在模型推理过程中,可能会因输入、输出shape变化而不断生成NPU模型,从而导致性能变差,更有可能使得NPU模型生成失败。 +- 实现原理 + - Subgraph detection pass在执行分割任务前,通过读取指定配置文件的方式获得禁用NPU的算子列表,实现人为干预分割结果的目的。 +- 具体步骤(以YOLOv3_MobileNetV3目标检测示例程序为例) + - 步骤1:查看[YOLOv3_MobileNetV3](https://paddlelite-demo.bj.bcebos.com/models/yolov3_mobilenet_v3_prune86_FPGM_320_fp32_fluid.tar.gz)的模型结构,具体是将PaddleLite-android-demo/object_detection_demo/assets/models/yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid目录下的model复制并重名为__model__后,拖入[Netron页面](https://lutzroeder.github.io/netron/)即得到如下图所示的网络结构(部分): + + ![yolov3_mobilenet_v3_netron](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/yolov3_mobilenet_v3_netron.jpg) + + - 步骤2:访问[https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/kernels/npu/bridges/paddle_use_bridges.h](https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/kernels/npu/bridges/paddle_use_bridges.h)查看已支持的算子列表,发现NPU不支持yolo_box、multiclass_nms这两个算子; + + - 步骤3:如果直接使用opt工具生成NPU模型,会发现整个网络被分割成3个子图(即3个subgraph op),subgraph1为MobileNetV3 backbone,subgraph2为1个transpose2和1个concat,subgraph3为2个transpose2和1个concat,它们都将运行在NPU上; + + ```shell + $ cd PaddleLite-android-demo/object_detection_demo/assets/models + $ GLOG_v=5 ../../../libs/PaddleLite/bin/opt --model_file=yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid/model \ + --param_file=yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid/params \ + --optimize_out_type=protobuf \ + --optimize_out=opt_model \ + --valid_targets=npu,arm + ... + [4 8/12 14:12:50.559 ...e/Paddle-Lite/lite/core/mir/ssa_graph.cc:27 CheckBidirectionalConnection] node count 398 + [4 8/12 14:12:50.560 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement feed host/any/any + [4 8/12 14:12:50.560 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement feed host/any/any + [4 8/12 14:12:50.560 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement subgraph npu/any/NCHW + [4 8/12 14:12:50.560 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement yolo_box arm/float/NCHW + [4 8/12 14:12:50.561 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement yolo_box arm/float/NCHW + [4 8/12 14:12:50.561 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement yolo_box arm/float/NCHW + [4 8/12 14:12:50.561 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement subgraph npu/any/NCHW + [4 8/12 14:12:50.561 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement subgraph npu/any/NCHW + [4 8/12 14:12:50.561 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement multiclass_nms host/float/NCHW + [4 8/12 14:12:50.561 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement fetch host/any/any + [I 8/12 14:12:50.561 ...te/lite/core/mir/generate_program_pass.h:37 GenProgram] insts.size 1 + [4 8/12 14:12:50.836 ...e-Lite/lite/model_parser/model_parser.cc:308 SaveModelPb] Save protobuf model in 'opt_model' successfully + + 注意:为了方便查看优化后的模型,上述命令将`optimize_out_type`参数设置为protobuf,执行成功后将opt_model目录下的model文件复制为__model__并拖入Netron页面进行可视化。 + ``` + + ![yolov3_mobilenet_v3_hybrid_cpu_npu_auto_split_netron](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/yolov3_mobilenet_v3_hybrid_cpu_npu_auto_split_netron.jpg) + + - 步骤4:为了防止CPU与NPU频繁切换,去除subgraph2和subgraph3,强制让transpose2和concat运行在CPU上。那么,我们就需要通过环境变量SUBGRAPH_CUSTOM_PARTITION_CONFIG_FILE设置『自定义子图分割配置文件』,实现人为干预分割结果; + + ```shell + $ cd PaddleLite-android-demo/object_detection_demo/assets/models + $ cat ./subgraph_custom_partition_config_file.txt + transpose2:yolo_box0.tmp_1:transpose_0.tmp_0,transpose_0.tmp_1 + transpose2:yolo_box1.tmp_1:transpose_1.tmp_0,transpose_1.tmp_1 + transpose2:yolo_box2.tmp_1:transpose_2.tmp_0,transpose_2.tmp_1 + concat:yolo_box0.tmp_0,yolo_box1.tmp_0,yolo_box2.tmp_0:concat_2.tmp_0 + concat:transpose_0.tmp_0,transpose_1.tmp_0,transpose_2.tmp_0:concat_3.tmp_0 + $ export SUBGRAPH_CUSTOM_PARTITION_CONFIG_FILE=./subgraph_custom_partition_config_file.txt + $ GLOG_v=5 ../../../libs/PaddleLite/bin/opt --model_file=yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid/model \ + --param_file=yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid/params \ + --optimize_out_type=protobuf \ + --optimize_out=opt_model \ + --valid_targets=npu,arm + ... + [4 8/12 14:15:37.609 ...e/Paddle-Lite/lite/core/mir/ssa_graph.cc:27 CheckBidirectionalConnection] node count 401 + [4 8/12 14:15:37.610 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement feed host/any/any + [4 8/12 14:15:37.610 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement feed host/any/any + [4 8/12 14:15:37.610 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement subgraph npu/any/NCHW + [4 8/12 14:15:37.610 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement yolo_box arm/float/NCHW + [4 8/12 14:15:37.610 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement transpose2 arm/float/NCHW + [4 8/12 14:15:37.610 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement yolo_box arm/float/NCHW + [4 8/12 14:15:37.610 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement transpose2 arm/float/NCHW + [4 8/12 14:15:37.611 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement yolo_box arm/float/NCHW + [4 8/12 14:15:37.611 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement transpose2 arm/float/NCHW + [4 8/12 14:15:37.611 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement concat arm/any/NCHW + [4 8/12 14:15:37.611 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement concat arm/any/NCHW + [4 8/12 14:15:37.611 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement multiclass_nms host/float/NCHW + [4 8/12 14:15:37.611 ...e/lite/core/mir/generate_program_pass.cc:46 Apply] Statement fetch host/any/any + [I 8/12 14:15:37.611 ...te/lite/core/mir/generate_program_pass.h:37 GenProgram] insts.size 1 + [4 8/12 14:15:37.998 ...e-Lite/lite/model_parser/model_parser.cc:308 SaveModelPb] Save protobuf model in 'opt_model'' successfully + ``` + + ![yolov3_mobilenet_v3_hybrid_cpu_npu_manual_split_netron](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/yolov3_mobilenet_v3_hybrid_cpu_npu_manual_split_netron.jpg) + + - 步骤5:上述步骤中,PaddleLite-android-demo/object_detection_demo/assets/models/subgraph_custom_partition_config_file.txt是示例自带的『自定义子图分割配置文件』,它的格式是什么样的呢? + - 每行记录由『算子类型:输入张量名列表:输出张量名列表』组成(即以分号分隔算子类型、输入和输出张量名列表),以逗号分隔输入、输出张量名列表中的每个张量名; + - 可省略输入、输出张量名列表中的部分张量名(如果不设置任何输入、输出张量列表,则代表计算图中该类型的所有算子节点均被强制运行在CPU上); + - 示例说明: + + ``` + op_type0:var_name0,var_name1:var_name2 表示将算子类型为op_type0、输入张量为var_name0和var_name1、输出张量为var_name2的节点强制运行在CPU上 + op_type1::var_name3 表示将算子类型为op_type1、任意输入张量、输出张量为var_name3的节点强制运行在CPU上 + op_type2:var_name4 表示将算子类型为op_type2、输入张量为var_name4、任意输出张量的节点强制运行在CPU上 + op_type3 表示任意算子类型为op_type3的节点均被强制运行在CPU上 + ``` + + - 步骤6:对于YOLOv3_MobileNetV3的模型,我们如何得到PaddleLite-android-demo/object_detection_demo/assets/models/subgraph_custom_partition_config_file.txt的配置呢? + - 重新在Netron打开PaddleLite-android-demo/object_detection_demo/assets/models/yolov3_mobilenet_v3_prune86_FPGM_fp32_320_fluid模型,如下图所示,1~5号节点需要强制放在CPU上运行。 + + ![yolov3_mobilenet_v3_hybrid_cpu_npu_manual_split_step1_netron](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/yolov3_mobilenet_v3_hybrid_cpu_npu_manual_split_step1_netron.jpg) + + - 在Netron中依次点击1~5号节点,右侧将显示每个节点的输入、输出张量名称,如下图所示,1号节点为transpose2类型算子,它的输入为yolo_box0.tmp1、输出为transpose_0.tmp_0,transpose_0.tmp_1,即可得到配置文件的第一条记录"transpose2:yolo_box0.tmp_1:transpose_0.tmp_0,transpose_0.tmp_1"; + + ![yolov3_mobilenet_v3_hybrid_cpu_npu_manual_split_step2_netron](https://paddlelite-demo.bj.bcebos.com/devices/huawei/kirin/yolov3_mobilenet_v3_hybrid_cpu_npu_manual_split_step2_netron.jpg) + + - 步骤7:将步骤4中的"optimize_out_type"修改为naive_buffer,重新执行步骤4即可以生成用于部署的CPU+NPU异构模型。 + + +## 其它说明 + +- 华为达芬奇架构的NPU内部大量采用float16进行运算,因此,预测结果会存在偏差,但大部分情况下精度不会有较大损失,可参考[Paddle-Lite-Demo](https://github.com/PaddlePaddle/Paddle-Lite-Demo)中Image Classification Demo for Android对同一张图片CPU与NPU的预测结果。 +- 华为Kirin 810/990 Soc搭载的自研达芬奇架构的NPU,与Kirin 970/980 Soc搭载的寒武纪NPU不一样,同样的,与Hi3559A、Hi3519A使用的NNIE也不一样,Paddle Lite只支持华为自研达芬奇架构NPU。 +- 我们正在持续增加能够适配HiAI IR的Paddle算子bridge/converter,以便适配更多Paddle模型,同时华为研发同学也在持续对HiAI IR性能进行优化。 diff --git a/docs/demo_guides/npu.md b/docs/demo_guides/npu.md deleted file mode 100644 index 86774a956d0c8417a1cf6afabd2fd7428f9666cd..0000000000000000000000000000000000000000 --- a/docs/demo_guides/npu.md +++ /dev/null @@ -1,200 +0,0 @@ -# PaddleLite使用NPU(华为)预测部署 - -Paddle Lite是首款支持华为自研达芬奇架构NPU(Kirin 810/990 SoC搭载的NPU)的预测框架。 -原理是在线分析Paddle模型,将Paddle算子转成HiAI IR后,调用HiAI IR/Builder/Runtime APIs生成并执行HiAI模型。 - -## 已支持的设备 - -- 华为nova5、nova5i pro、mate30、mate30 pro、mate30 5G、荣耀v30、p40、p40 pro,以及即将推出的mate40、。据华为透露,今后上市的大部分手机都会搭载其自研达芬奇架构NPU。 - -## 已支持的模型 - -- MobileNetV1 -- MobileNetV2 -- ResNet-18/50 -- ShuffleNetV2 -- squeezenet -- mnasnet -- yolov3 -- CycleGAN (暂时需要华为内部rom的支持) -- 百度内部业务模型(由于涉密,不方便透露具体细节) - -*CPU/NPU混合调度在部分模型可以获得更佳的性能* - -## 已支持(或部分支持)的Paddle算子 - -- sigmoid -- relu -- tanh -- relu_clipped -- leaky_relu -- softsign -- hard_sigmoid -- batch_norm -- concat -- conv2d -- depthwise_conv2d -- conv2d_transpose -- dropout -- elementwise_add -- elementwise_sub -- elementwise_mul -- elementwise_div -- fusion_elementwise_add_activation -- fusion_elementwise_sub_activation -- fusion_elementwise_mul_activation -- fusion_elementwise_div_activation -- fc -- bilinear_interp -- nearest_interp -- matmul -- mul -- pad2d -- pool2d -- reduce_mean -- reshape -- reshape2 -- scale -- shuffle_channel -- softmax -- split -- sqrt -- square -- transpose -- transpose2 -- unsqueeze -- unsqueeze2 -- instance_norm (暂时需要华为内部rom的支持) -- layer_norm (暂时需要华为内部rom的支持) - -## 编译支持NPU的Paddle Lite库 - -- 从[华为HiAI平台](https://developer.huawei.com/consumer/cn/hiai)下载华为HiAI DDK后解压到任意路径(注意:华为提供了多个版本的DDK,我们需要下载针对麒麟810/990芯片HiAI Foundation开发套件,例如[DDK V310版本](https://obs.cn-north-2.myhwclouds.com/hms-ds-wf/sdk/hwhiai-ddk-100.310.011.010.zip))。 -- 将HiAI DDK中的ai_ddk_lib目录拷贝至Paddle Lite源码根目录后,使用[编译脚本](https://github.com/PaddlePaddle/Paddle-Lite/blob/develop/lite/tools/build_android.sh)编译 (需要指定NPU相关选项)。 - -注意:以下是HiAI DDK V310版解压后的目录结构,需要将ai_ddk_lib目录拷贝至Paddle Lite源码根目录。 -```shell -- app_sample -- ddk - - ai_ddk_lib - - include - - lib # for armv7 - - lib64 # for armv8 -- document -- tools -``` - -- 推荐编译命令。由于HiAI DDK的so库均基于c++_shared构建,因此,建议使用c++_shared编译Paddle Lite。 -```shell -# huawei_kirin_npu_sdk_root 需要指向 ai_ddk_lib 的路径 -$ ./lite/tools/build_android.sh --android_stl=c++_shared --with_huawei_kirin_npu=ON --huawei_kirin_npu_sdk_root= -# 其它选项可以通过 "./lite/tools/build_android.sh help" 查看,例如arm版本等 -``` - -注意:为了保证编译环境一致,建议参考[源码编译](../user_guides/source_compile)中的Docker开发环境进行配置,然后再执行上述命令。 - -## 优化生成NPU模型 - -- model_optimize_tool工具已经支持生成NPU模型,仅需要将valid_targets设置为npu,arm即可,具体参考[模型转化方法](../user_guides/model_optimize_tool)。 -```shell -./model_optimize_tool --model_dir= \ - --model_file= \ - --param_file= \ - --optimize_out_type=(protobuf|naive_buffer) \ - --optimize_out= \ - --valid_targets=npu,arm \ - --record_tailoring_info =(true|false) -``` -- model_optimize_tool生成的模型只是标记了NPU支持的Paddle算子,并没有真正生成NPU HiAI模型,只有在执行时才会将标记的Paddle算子转成HiAI IR,最终生成并执行HiAI模型,具体实现参考PR[2576](https://github.com/PaddlePaddle/Paddle-Lite/pull/2576)。 -- 不同模型,不同型号(ROM版本)的华为手机,在执行阶段,由于某些Paddle算子无法完全转成HiAI IR,或目标手机的HiAI版本过低等原因,可能导致HiAI模型无法成功生成,在这种情况下,Paddle Lite会调用CPU版算子进行运算完成整个预测任务。 - -## 通过JAVA接口加载并执行NPU模型 - -**注意:由于华为手机root权限限制,现在仅支持JAVA接口加载和执行NPU模型** - -- 使用方法和[Java实例](java_demo)一致,无需额外设置任何参数,只需将模型换成NPU模型即可。[Paddle-Lite-Demo](https://github.com/PaddlePaddle/Paddle-Lite-Demo)中的Image Classification Demo for Android是同时支持CPU和NPU两种模型的图像分类Demo。 - -注意:在拷贝libpaddle_lite_jni.so的时候,由于依赖HiAI DDK so和libc++_shared.so库,需要将HiAI DDK中ai_ddk_lib/lib或ai_ddk_lib/lib64目录下的所有so和libc++_shared.so,拷到libpaddle_lite_jni.so同级目录下。 - -## 其它说明 - -- 华为达芬奇架构的NPU内部大量采用float16进行运算,因此,预测结果会存在偏差,但大部分情况下精度不会有较大损失,可参考[Paddle-Lite-Demo](https://github.com/PaddlePaddle/Paddle-Lite-Demo)中Image Classification Demo for Android对同一张图片CPU与NPU的预测结果。 -- 华为Kirin 810/990 Soc搭载的自研达芬奇架构的NPU,与Kirin 970/980 Soc搭载的寒武纪NPU不一样,同样的,与Hi3559A、Hi3519A使用的NNIE也不一样,Paddle Lite只支持华为自研达芬奇架构NPU。 -- 我们正在持续增加能够适配HiAI IR的Paddle算子bridge/converter,以便适配更多Paddle模型,同时华为研发同学也在持续对HiAI IR性能进行优化。 - - -## 手动分割子图 - -### 背景 -- Paddle-Lite已经支持了大量的华为NPU的算子,但是仍然不能满足所有模型的需求。对于一个有部分算子不支持的模型,Paddle-Lite会将模型划分为可以跑在NPU上的子图和跑在CPU上的子图,实现NPU和CPU自动调度的功能,通常情况下可以获得比较好的性能。在一些特殊情况下,模型会被自动划分为比较多的子图,导致CPU和NPU的切换开销很大,从而导致整体性能变差。因此,需要手动分割子图的功能来指定一些算子跑在CPU上,避免子图过多。 - -### 功能 -- 通过配置文件来指定需要强制跑在CPU上的算子 - -### 使用方法 -- 1、通过netron打开paddle模型文件,可以查看模型结构,获得算子的类型、输入名称。输出名称。 - - 注意:Paddle-Lite会对模型进行优化,模型算子可以改变,需要以优化后的模型算子为准。后面会举例说明。 -- 2、生成配置文件 ```split_cfg.txt```,记录需要跑在CPU上的算子信息。 - - 每行一条OP记录信息,以冒号":"分隔"op名称","op输入名","op输出名",以逗号","分隔"op输入名"和"op输出名"中的不同var名。 - - 可以部分省略输入或者输出名。比如:```op3:in3_var0```表示,指定类型为"op3",输入为"in3_var0"的算子;```op4```表示所有类型为"op4"的算子 - - 例子1: - ``` - op0:in0_var0,in0_var1:out0_var0,out0_var1 - op1:in1_var0,in1_var1:out1_var0 - op2::out2_var0 - op3:in3_var0 - op4 - ``` - - 例子2: - ``` - transpose:conv2d_22.tmp_1:transpose_0.tmp_0 - ``` - ![image](https://user-images.githubusercontent.com/50474132/80475316-4a5fda80-897b-11ea-910a-6aee13243387.png) - -- 3、使用环境变量```SUBGRAPH_CUSTOM_PARTITION_CONFIG_FILE```指定配置文件的位置。 - - 例如: - ``` - export SUBGRAPH_CUSTOM_PARTITION_CONFIG_FILE=/data/local/tmp/split_sfg.txt - ``` -- 4、以上步骤完成后,运行的模型中符合条件的算子将被强制跑在CPU上。 - -### 举例 -- 以模型[image](https://paddlelite-demo.bj.bcebos.com/models/ssd_mobilenet_v1_pascalvoc_fp32_300_fluid.tar.gz)为例 - -- 1、可以使用netron查看模型 - -- 2、初步分析 - - - 下图是ssd_mobilenet_v1中的部分结构。其中红色部分暂时不支持在NPU上运行,蓝色部分可能NPU上的性能不理想。此时,如果直接让预测库自动调度的话,可能会分成多个子图,而且整体性能不佳。因此,可以将蓝色部分和绿色部分整体指定在CPU上运行,让其他部分自动运行在NPU上(红色部分会自动在CPU上运行)。 - ![](https://user-images.githubusercontent.com/50474132/80453173-525b5280-895a-11ea-847f-c7dd5b5799de.png) - -- 3、使用opt转换模型 - - - opt转换过程中会打印log信息。在log中搜索```digraph G```和```// end G```可以找到优化后的模型图。 - ![](https://user-images.githubusercontent.com/50474132/80454098-145f2e00-895c-11ea-9f16-dde1483a9beb.png) - ![](https://user-images.githubusercontent.com/50474132/80454123-1de89600-895c-11ea-86b9-a62d78a6616d.png) - - 将从```digraph G```开始的,到```// end G```结束的整段模型图信息,保存到```.dot```格式的文件中。可以用```graphviz```打开查看,或者在[网页版](http://dreampuf.github.io/GraphvizOnline/)查看。 - ![](https://user-images.githubusercontent.com/50474132/80454841-47ee8800-895d-11ea-9531-5689c5560fcb.png) - - 在此处确认需要被指定的算子是否被优化了。(期望是被指定的算子都还独立存在,如果被融合为了一个算子,需要指定此时融合后的算子)。 - -- 4、写配置文件 - - - 在配置文件中指定可以支持NPU但是需要指定在CPU上运行的算子。 - ``` - reshape - transpose - concat - softmax - ``` - - 由于这些算子都指定在CPU上运行,因此不需要特意配置算子的输入输出名称。 - -- 5、指定配置文件路径 - - - 通过```export SUBGRAPH_CUSTOM_PARTITION_CONFIG_FILE=your_split_config_file```的方式实现。 - -- 6、性能测试 - - - 设备:华为mate30 5G - - HIAI ddk版本:320 - - 性能:CPU约71.8ms,NPU约16.6ms。 - diff --git a/docs/index.rst b/docs/index.rst index 9f74816ccf0a68299975793e498941eef9c0a2a8..24dac7f3692649f99bbeabafab53896c2221c29c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -60,7 +60,7 @@ Welcome to Paddle-Lite's documentation! demo_guides/cuda demo_guides/opencl demo_guides/fpga - demo_guides/npu + demo_guides/huawei_kirin_npu demo_guides/baidu_xpu demo_guides/rockchip_npu demo_guides/mediatek_apu