PaddleLite使用OpenCL预测部署

    1. Docker 容器环境;
    2. Linux(推荐 Ubuntu 16.04)环境。

    详见 源码编译指南-环境准备 章节。

    1.2 编译Paddle-Lite OpenCL库范例

    注:以android/armv7/opencl的目标、Docker容器的编译开发环境为例,CMake3.10,android-ndk-r17c位于目录下。

    针对 Lite 用户的编译命令(无单元测试,有编译产物,适用于benchmark)

    • with_opencl: [ON | OFF],编译OpenCL必选;
    • arm_abi: [armv7 | armv8]
    • toolchain: [gcc | clang]
    • build_extra: [OFF | ON],编译全量op和kernel,包含控制流NLP相关的op和kernel体积会大,编译时间长;
    • build_cv: [OFF | ON],编译arm cpu neon实现的的cv预处理模块;
    • android_stl: [c++_shared | c++_static | gnu_static | gnu_shared],paddlelite的库以何种方式链接android_stl,选择c++_shared得到的动态库体积更小,但使用时候记得上传paddlelite所编译版本(armv7或armv8)一致的libc++_shared.so。默认使用c++_static

    注:该方式的编译产物中的demo/cxx/mobile_light适用于做benchmark,该过程不会打印开发中加入的log,注意需要提前转好模型。关于使用,详见下文运行示例1: 编译产物demo示例

    针对 Lite 开发者的编译命令(有单元测试,编译产物)

    注:调用./lite/tools/ci_build.sh执行编译,该命令会编译armv7和armv8的opencl库。虽然有编译产物,但因编译单元测试,编译产物包体积可能较大,生产环境不推荐使用。

    1. # 假设当前位于处于Lite源码根目录下
    2. # 导入NDK_ROOT变量,注意检查您的安装目录若与本示例不同
    3. export NDK_ROOT=/opt/android-ndk-r17c
    4. # 删除上一次CMake自动生成的.h文件
    5. rm ./lite/api/paddle_use_kernels.h
    6. rm ./lite/api/paddle_use_ops.h
    7. # 根据指定编译参数编译
    8. ./lite/tools/ci_build.sh \
    9. --arm_abi=armv8 \
    10. --arm_lang=gcc \
    11. build_opencl

    编译产物位于build.lite.android.armv8.gcc.opencl下的inference_lite_lib.android.armv8.opencl文件夹内,根据编译参数不同,文件夹名字会略有不同。这里仅罗列关键产物:

    • cxx:该目录是编译目标的C++的头文件和库文件;
    • demo:该目录包含了两个demo,用来调用使用libpaddle_api_full_bundled.alibpaddle_api_light_bundled.a,分别对应mobile_fullmobile_light文件夹。编译对应的demo仅需在mobile_fullmobile_light
      • mobile_full:使用cxx config,可直接加载fluid模型,若使用OpenCL需要在mobilenetv1_full_api.cc代码里开启DEMO_USE_OPENCL的宏,详细见该文件的代码注释;
      • mobile_light:使用mobile config,只能加载model_optimize_tool优化过的模型。 注:opencl实现的相关kernel已经打包到动态库中。

    调用libpaddle_api_full_bundled.alibpaddle_api_light_bundled.a见下一部分运行示例。

    下面以android的环境为例,介绍3个示例,分别如何在手机上执行基于OpenCL的ARM GPU推理过程。

    2.1 运行示例1: 编译产物demo示例和benchmark

    需要提前用模型优化工具opt转好模型(下面假设已经转换好模型,且模型名为mobilenetv1_opencl_fp32_opt_releasev2.6_b8234efb_20200423.nb)。编译脚本为前文针对 Lite 用户的编译命令(无单元测试,有编译产物,适用于benchmark)

    1. #################################
    2. # 假设当前位于build.xxx目录下 #
    3. #################################
    4. adb shell mkdir -p /data/local/tmp/opencl/
    5. # build demo
    6. cd inference_lite_lib.android.armv7.opencl/demo/cxx/mobile_light/
    7. cd -
    8. # push executable binary, library to device
    9. adb push inference_lite_lib.android.armv7.opencl/demo/cxx/mobile_light/mobilenetv1_light_api /data/local/tmp/opencl/
    10. adb shell chmod +x /data/local/tmp/opencl/mobilenetv1_light_api
    11. adb push inference_lite_lib.android.armv7.opencl/cxx/lib/libpaddle_light_api_shared.so /data/local/tmp/opencl/
    12. # push model with optimized(opt) to device
    13. adb push ./mobilenetv1_opencl_fp32_opt_releasev2.6_b8234efb_20200423.nb /data/local/tmp/opencl/
    14. # run demo on device
    15. adb shell "export LD_LIBRARY_PATH=/data/local/tmp/opencl/; \
    16. /data/local/tmp/opencl/mobilenetv1_light_api \
    17. /data/local/tmp/opencl/mobilenetv1_opencl_fp32_opt_releasev2.6_b8234efb_20200423.nb \
    18. 1 3 224 224 \
    19. 100 10 0" # round=100, warmup=10, print_output_tensor=0

    编译脚本为前文针对 Lite 开发者的编译命令(有单元测试,编译产物)

    • 运行文件准备
    • 执行OpenCL推理过程
    1. adb shell chmod +x /data/local/tmp/opencl/test_mobilenetv1
    2. adb shell "export GLOG_v=1; \
    3. /data/local/tmp/opencl/test_mobilenetv1 \
    4. --model_dir=/data/local/tmp/opencl/mobilenetv1_fluid/ \
    5. --repeats=100"

    2.3 运行示例3: test_layout_opencl单元测试

    编译脚本为前文针对 Lite 开发者的编译命令(有单元测试,编译产物)

    即编译产物demo/cxx/mobile_light目录下的代码,在线版参考GitHub仓库,其中也包括判断当前设备是否支持OpenCL的方法;

    注:这里给出的链接会跳转到线上最新develop分支的代码,很可能与您本地的代码存在差异,建议参考自己本地位于目录的代码,查看如何使用。