预测库编译

PaddleLite已经提供官方Release预测库下载,请参考文档

PaddleLite 提供了移动端的一键源码编译脚本 lite/tools/build.sh,编译流程如下:

  1. 环境准备(选择其一):Docker交叉编译环境、Linux交叉编译环境
  2. 编译:调用build.sh脚本一键编译

一、环境准备

目前支持三种编译的环境:

  1. Docker 容器环境,
  2. Linux(推荐 Ubuntu 16.04)环境,
  3. Mac OS 环境。

1、 Docker开发环境

Docker 是一个开源的应用容器引擎, 使用沙箱机制创建独立容器,方便运行不同程序。Docker初学者可以参考Docker使用方法正确安装Docker。

准备Docker镜像

有两种方式准备Docker镜像,推荐从Dockerhub直接拉取Docker镜像

  1. # 方式一:从Dockerhub直接拉取Docker镜像
  2. docker pull paddlepaddle/paddle-lite:2.0.0_beta
  3. # 方式二:本地源码编译Docker镜像
  4. git clone https://github.com/PaddlePaddle/Paddle-Lite.git
  5. cd Paddle-Lite/lite/tools
  6. mkdir mobile_image
  7. cp Dockerfile.mobile mobile_image/Dockerfile
  8. cd mobile_image
  9. docker build -t paddlepaddle/paddle-lite .
  10. # 镜像编译成功后,可用`docker images`命令,看到`paddlepaddle/paddle-lite`镜像。

进入Docker容器

在拉取Paddle-Lite仓库代码的上层目录,执行如下代码,进入Docker容器:

  1. docker run -it \
  2. --name paddlelite_docker \
  3. -v $PWD/Paddle-Lite:/Paddle-Lite \
  4. --net=host \
  5. paddlepaddle/paddle-lite /bin/bash

该命令的含义:将容器命名为paddlelite_docker<container-name>,将当前目录下的Paddle-Lite文件夹挂载到容器中的/Paddle-Lite这个根目录下,并进入容器中。至此,完成Docker环境的准备。

Docker常用命令

  1. # 退出容器但不停止/关闭容器:键盘同时按住三个键:CTRL + q + p
  2. # 启动停止的容器
  3. docker start <container-name>
  4. # 从shell进入已启动的容器
  5. docker attach <container-name>
  6. # 停止正在运行的Docker容器
  7. docker stop <container-name>
  8. # 重新启动正在运行的Docker容器
  9. docker restart <container-name>
  10. # 删除Docker容器
  11. docker rm <container-name>

2、Linux 开发环境

Android

交叉编译环境要求
  • gcc、g++、git、make、wget、python、adb
  • Java environment
  • cmake(建议使用3.10或以上版本)
  • Android NDK (建议ndk-r17c)
具体步骤

安装软件部分以 Ubuntu 为例,其他 Linux 发行版类似。

  1. # 1. Install basic software
  2. apt update
  3. apt-get install -y --no-install-recommends \
  4. gcc g++ git make wget python unzip adb curl
  5. # 2. Prepare Java env.
  6. apt-get install -y default-jdk
  7. # 3. Install cmake 3.10 or above
  8. wget -c https://mms-res.cdn.bcebos.com/cmake-3.10.3-Linux-x86_64.tar.gz && \
  9. tar xzf cmake-3.10.3-Linux-x86_64.tar.gz && \
  10. mv cmake-3.10.3-Linux-x86_64 /opt/cmake-3.10 && \
  11. ln -s /opt/cmake-3.10/bin/cmake /usr/bin/cmake && \
  12. ln -s /opt/cmake-3.10/bin/ccmake /usr/bin/ccmake
  13. # 4. Download Android NDK for linux-x86_64
  14. # Note: Skip this step if NDK installed
  15. # recommand android-ndk-r17c-darwin-x86_64
  16. # ref: https://developer.android.com/ndk/downloads
  17. cd /tmp && curl -O https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
  18. cd /opt && unzip /tmp/android-ndk-r17c-linux-x86_64.zip
  19. # 5. Add environment ${NDK_ROOT} to `~/.bashrc`
  20. echo "export NDK_ROOT=/opt/android-ndk-r17c" >> ~/.bashrc
  21. source ~/.bashrc

ARM Linux

适用于基于 ARMv8 和 ARMv7 架构 CPU 的各种开发板,例如 RK3399,树莓派等,目前支持交叉编译和本地编译两种方式,对于交叉编译方式,在完成目标程序编译后,可通过 scp 方式将程序拷贝到开发板运行。

交叉编译
编译环境要求
  • gcc、g++、git、make、wget、python、scp
  • cmake(建议使用3.10或以上版本)
具体步骤

安装软件部分以 Ubuntu 为例,其他 Linux 发行版类似。

  1. # 1. Install basic software
  2. apt update
  3. apt-get install -y --no-install-recommends \
  4. gcc g++ git make wget python unzip
  5. # 2. Install arm gcc toolchains
  6. apt-get install -y --no-install-recommends \
  7. g++-arm-linux-gnueabi gcc-arm-linux-gnueabi \
  8. g++-arm-linux-gnueabihf gcc-arm-linux-gnueabihf \
  9. gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
  10. # 3. Install cmake 3.10 or above
  11. wget -c https://mms-res.cdn.bcebos.com/cmake-3.10.3-Linux-x86_64.tar.gz && \
  12. tar xzf cmake-3.10.3-Linux-x86_64.tar.gz && \
  13. mv cmake-3.10.3-Linux-x86_64 /opt/cmake-3.10 && \
  14. ln -s /opt/cmake-3.10/bin/cmake /usr/bin/cmake && \
  15. ln -s /opt/cmake-3.10/bin/ccmake /usr/bin/ccmake
本地编译(直接在RK3399或树莓派上编译)
编译环境要求
  • gcc、g++、git、make、wget、python
  • cmake(建议使用3.10或以上版本)
具体步骤

安装软件部分以 Ubuntu 为例,其他 Linux 发行版本类似。

  1. # 1. Install basic software
  2. apt update
  3. apt-get install -y --no-install-recomends \
  4. gcc g++ make wget python unzip
  5. # 2. install cmake 3.10 or above
  6. wget https://www.cmake.org/files/v3.10/cmake-3.10.3.tar.gz
  7. tar -zxvf cmake-3.10.3.tar.gz
  8. cd cmake-3.10.3
  9. ./configure
  10. make
  11. sudo make install

之后可通过cmake —version查看cmake是否安装成功。

至此,完成 Linux 交叉编译环境的准备。

3、Mac OS 开发环境

交叉编译环境要求

  • gcc、git、make、curl、unzip、java
  • cmake(Android编译请使用3.10版本,IOS编译请使用3.15版本)
  • 编译Android: Android NDK (建议ndk-r17c)
  • 编译IOS: XCode(Version 10.1)

具体步骤

  1. # 1. Install basic software
  2. brew install curl gcc git make unzip wget
  3. # 2. Install cmake: mac上实现IOS编译和Android编译要求的cmake版本不一致,可以根据需求选择安装。
  4. # (1)在mac环境编译 Paddle-Lite 的Android版本,需要安装cmake 3.10
  5. # mkdir /usr/local/Cellar/cmake/ && cd /usr/local/Cellar/cmake/
  6. # wget https://cmake.org/files/v3.10/cmake-3.10.2-Darwin-x86_64.tar.gz
  7. # tar zxf ./cmake-3.10.2-Darwin-x86_64.tar.gz
  8. # mv cmake-3.10.2-Darwin-x86_64/CMake.app/Contents/ ./3.10.2
  9. # ln -s /usr/local/Cellar/cmake/3.10.2/bin/cmake /usr/local/bin/cmake
  10. # (2)在mac环境编译 Paddle-Lite 的IOS版本,需要安装cmake 3.15
  11. # mkdir /usr/local/Cellar/cmake/ && cd /usr/local/Cellar/cmake/
  12. # cd /usr/local/Cellar/cmake/
  13. # wget https://cmake.org/files/v3.15/cmake-3.15.2-Darwin-x86_64.tar.gz
  14. # tar zxf ./cmake-3.15.2-Darwin-x86_64.tar.gz
  15. # mv cmake-3.15.2-Darwin-x86_64/CMake.app/Contents/ ./3.15.2
  16. # ln -s /usr/local/Cellar/cmake/3.15.2/bin/cmake /usr/local/bin/cmake
  17. # 3. Download Android NDK for Mac
  18. # recommand android-ndk-r17c-darwin-x86_64
  19. # ref: https://developer.android.com/ndk/downloads
  20. # Note: Skip this step if NDK installed
  21. cd ~/Documents && curl -O https://dl.google.com/android/repository/android-ndk-r17c-darwin-x86_64.zip
  22. cd ~/Library && unzip ~/Documents/android-ndk-r17c-darwin-x86_64.zip
  23. # 4. Add environment ${NDK_ROOT} to `~/.bash_profile`
  24. echo "export NDK_ROOT=~/Library/android-ndk-r17c" >> ~/.bash_profile
  25. source ~/.bash_profile
  26. # 5. Install Java Environment
  27. brew cask install java
  28. # 6. 编译IOS需要安装XCode(Version 10.1),可以在App Store里安装。安装后需要启动一次并执行下面语句。
  29. # sudo xcode-select -s /Applications/Xcode.app/Contents/Developer

至此,完成 Mac 交叉编译环境的准备。

注意: Mac上编译Paddle-Lite的full_publish版本时,Paddle-Lite所在路径中不可以含有中文字符

二、编译PaddleLite

下载代码

  1. git clone https://github.com/PaddlePaddle/Paddle-Lite.git
  2. cd Paddle-Lite
  3. git checkout <release-version-tag>

编译模式与参数

编译脚本./lite/tools/build.sh,支持三种编译模式:

编译模式介绍适用对象
tiny_publish编译移动端部署库,无第三方库依赖用户
full_publish编译移动端部署库,有第三方依赖如protobuf、glags等,含有可将模型转换为无需protobuf依赖的naive buffer格式的工具,供tiny_publish库使用用户
test编译指定arm_osarm_abi下的移动端单元测试框架开发者

编译脚本./lite/tools/build.sh,追加参数说明:

参数介绍
—arm_os必选,选择安装平台androidiosios64armlinux
—arm_abi必选,选择编译的arm版本,其中armv7hf为ARMLinux编译时选用armv8armv7armv7hf(仅armlinux支持)
—arm_langarm_os=android时必选,选择编译器gccclang(clang当前暂不支持)
—android_stlarm_os=android时必选,选择静态链接STL或动态链接STLc++_staticc++_shared
—build_java可选,是否编译java预测库(默认为ON)ONOFF
—build_extra可选,是否编译全量预测库(默认为OFF)。详情可参考预测库说明ONOFF
target必选,选择编译模式,tiny_publish为编译移动端部署库、full_publish为带依赖的移动端部署库、test为移动端单元测试、ios为编译ios端tiny_publishtiny_publishfull_publishtestios

编译代码

注意:非开发者建议在编译前使用“加速第三方依赖库的下载”的方法,加速工程中第三方依赖库的下载与编译。

编译tiny publish动态库

Android
  1. ./lite/tools/build.sh \
  2. --arm_os=android \
  3. --arm_abi=armv8 \
  4. --build_extra=OFF \
  5. --arm_lang=gcc \
  6. --android_stl=c++_static \
  7. tiny_publish
IOS
  1. ./lite/tools/build.sh \
  2. --arm_os=ios64 \
  3. --arm_abi=armv8 \
  4. --build_extra=OFF \
  5. ios

注意:mac环境编译IOS 时,cmake版本需要高于cmake 3.15;mac环境上编译Android时,cmake版本需要设置为cmake 3.10。

ios tiny publish支持的编译选项:

  • --arm_os: 可选ios或者ios64
  • --arm_abi: 可选armv7和armv8(注意:当arm_os=ios时只能选择arm_abi=armv7,当arm_os=ios64时只能选择arm_abi=armv8
  • 如果mac编译过程中报错:”Invalid CMAKE_DEVELOPER_ROOT: does not exist”, 运行:
  1. sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
ARMLinux
  1. ./lite/tools/build.sh \
  2. --build_extra=OFF \
  3. --arm_os=armlinux \
  4. --arm_abi=armv7hf \
  5. --arm_lang=gcc \
  6. tiny_publish
  • --arm_abi: 树莓派3b使用armv7hf,RK3399使用armv8

编译full publish动态库

Android
  1. ./lite/tools/build.sh \
  2. --arm_os=android \
  3. --arm_abi=armv8 \
  4. --build_extra=OFF \
  5. --arm_lang=gcc \
  6. --android_stl=c++_static \
  7. full_publish
ARMLinux
  1. ./lite/tools/build.sh \
  2. --arm_os=armlinux \
  3. --arm_abi=armv7hf \
  4. --arm_lang=gcc \
  5. --build_extra=OFF \
  6. full_publish
  • --arm_abi: 树莓派3b使用armv7hf,RK3399使用armv8

编译结果说明

编译最终产物位置build.lite.xxx.xxx.xxx 下的 inference_lite_lib.xxx.xxx ,如 Android 下 ARMv8 的产物位于inference_lite_lib.android.armv8

https://user-images.githubusercontent.com/45189361/65375706-204e8780-dccb-11e9-9816-ab4563ce0963.png

目录内容(可能)如下:

Full_publish编译结果:

https://user-images.githubusercontent.com/45189361/65375704-19c01000-dccb-11e9-9650-6856c7a5bf82.png

Tiny_publish结果:

https://user-images.githubusercontent.com/45189361/65375726-3bb99280-dccb-11e9-9903-8ce255371905.png

IOS编译结果:

https://user-images.githubusercontent.com/45189361/65375726-3bb99280-dccb-11e9-9903-8ce255371905.png

具体内容说明:

1、 bin文件夹:可执行工具文件 paddle_code_generatortest_model_bin

2、 cxx文件夹:包含c++的库文件与相应的头文件

  • include : 头文件
  • lib : 库文件
    • 打包的静态库文件:
      • libpaddle_api_full_bundled.a :包含 full_api 和 light_api 功能的静态库
      • libpaddle_api_light_bundled.a :只包含 light_api 功能的静态库
    • 打包的动态态库文件:
      • libpaddle_full_api_shared.so :包含 full_api 和 light_api 功能的动态库
      • libpaddle_light_api_shared.so:只包含 light_api 功能的动态库

3、 demo文件夹:示例 demo ,包含 C++ demo 和 Java demo。

  • cxx : C++示例 demo
    • mobile_full : full_api 的使用示例
    • mobile_light : light_api的使用示例
  • java :Java 示例 demo
    • android : Java的 Android 示例

4、 java 文件夹:包含 Jni 的动态库文件与相应的 Jar 包

  • jar : PaddlePredictor.jar
  • so : Jni动态链接库 libpaddle_lite_jni.so

5、 third_party 文件夹:第三方库文件gflags

注意:

1、 只有当--arm_os=android 时才会编译出:

  • Java库文件与示例:Javademo/java
  • 动态库文件:libpaddle_full_api_shared.so,libpaddle_light_api_shared.so

2、 tiny_publish编译结果不包括 C++ demo和 C++ 静态库,但提供 C++ 的 light_api 动态库、 Jni 动态库和Java demo

加速第三方依赖库的下载

移动端相关编译所需的第三方库均位于 <PaddleLite>/third-party 目录下,默认编译过程中,会利用git submodule update --init --recursive链上相关的第三方依赖的仓库。

为加速full_publishtest编译模式中对protobuf等第三方依赖的下载,build.shci_build.sh支持了从国内 CDN 下载第三方依赖的压缩包。

使用方法:git clonePaddle-Lite仓库代码后,手动删除本地仓库根目录下的third-party目录:

  1. git clone https://github.com/PaddlePaddle/Paddle-Lite.git
  2. git checkout <release-version-tag>
  3. cd Paddle-Lite
  4. rm -rf third-party

之后再根据本文档,进行后续编译时,便会忽略第三方依赖对应的submodule,改为下载第三方压缩包。