简介
环境要求
1 安装 Bazel
2 安装Android NDK
3 在Ubuntu16.04下安装Docker(17.09)
构建并运行示例模型
1 拉取MACE项目
2 拉取MACE Model Zoo项目
3 构建通用MACE库
4 将预先训练的mobilenet-v2模型转换为MACE格式模型
编译运行DEMO
1 运行build.sh编译
2 使用Android Studio编译
MACE是一种针对移动异构计算平台优化的深度学习推理框架。
Github:https://github.com/xiaomi/mace
编译系统:虚拟机 ubuntu 16.04 LTS
MACE需要以下依赖项:
Software | Installation command | Tested version |
---|---|---|
Python | 2.7 | |
Bazel | bazel installation guide | 0.13.0 |
CMake | apt-get install cmake | >= 3.11.3 |
Jinja2 | pip install -I jinja2==2.10 | 2.10 |
PyYaml | pip install -I pyyaml==3.12 | 3.12.0 |
sh | pip install -I sh==1.12.14 | 1.12.14 |
Numpy | pip install -I numpy==1.14.0 | Required by model validation |
six | pip install -I six==1.11.0 | Required for Python 2 and 3 compatibility (TODO) |
Software | Installation command | Remark |
---|---|---|
Android NDK | NDK installation guide | Required by Android build, r15b, r15c, r16b, r17b |
ADB | apt-get install android-tools-adb | Required by Android run, >= 1.0.32 |
TensorFlow | pip install -I tensorflow==1.6.0 | Required by TensorFlow model |
Docker | docker installation guide | Required by docker mode for Caffe model |
Scipy | pip install -I scipy==1.0.0 | Required by model validation |
FileLock | pip install -I filelock==3.0.0 | Required by run on Android |
注:如果在使用pip来进行安装操作时碰到这样的问题:pip Import Error:cannot import name main
解决方案:
sudo gedit /usr/bin/pip
将原来的:
from pip import main
if __name__ == '__main__':
sys.exit(main())
改成:
from pip import __main__
if __name__ == '__main__':
sys.exit(__main__._main())
推荐尺寸大于bazel 0.13.0
使用以下方法之一在Ubuntu上安装Bazel
第1步:安装所需的包
首先,安装先决条件:pkg-config,zip,g++,zlib1g-dev,unzip,和python。
sudo apt-get install pkg-config zip g++ zlib1g-dev unzip python
第2步:下载Bazel
export BAZEL_VERSION=0.13.1
mkdir /bazel
cd /bazel
wget https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh
第3步:运行安装程序
chmod +x bazel-*.sh
./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh --user
第4步:删除安装包
cd /
rm -f /bazel/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh
第5步:设置环境
该--user标志将Bazel安装到$HOME/bin系统上的目录并设置.bazelrc路径$HOME/.bazelrc。使用该--help命令可以查看其他安装选项。
如果您使用--user上面的标志运行Bazel安装程序,则Bazel可执行文件将安装在您的$HOME/bin目录中。将此目录添加到默认路径,如下所示:
export PATH="$PATH:$HOME/bin"
也可以将此命令添加到~/.bashrc文件中。
注:试过通过离线下载好的包进行安装出现错误,后改成用wget在线下载进行安装成功
如果安装成功后输入命令bazel 正常,使用sudo bazel却提示找不到命令的话,解决方案如下:
以root用户身份来编辑文件/etc/sudoers
sudo vim /etc/sudoers
找到Defaults env_reset, 将其改为
Defaults !env_reset 这里加了这个感叹号表示不重置环境变量
然后,编辑用户根目录下的配置文件~/.bashrc
vim .bashrc
在文件内最后追加
alias sudo='sudo env PATH=$PATH'
最后, 使配置文件生效
source ~/.bashrc
第1步:安装JDK
安装JDK 8:
sudo apt-get install openjdk-8-jdk
在Ubuntu 14.04 LTS上,必须使用PPA:
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update && sudo apt-get install oracle-java8-installer
第2步:添加Bazel分发URI作为包源
注意:这是一次性设置步骤。
echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
如果要安装Bazel的测试版,请替换stable为testing。
第3步:安装和更新Bazel
sudo apt-get update && sudo apt-get install bazel
如果这一步出错:
由于没有公钥,无法验证下列签名: NO_PUBKEY 7EA0A9C3F273FCD8
W: 仓库 “http://mirrors.aliyun.com/docker-ce/linux/ubuntu xenial InRelease” 没有数字签名。
N: 无法认证来自该源的数据,所以使用它会带
解决办法:(红色字符串是PUBKEY的后八位)
sudo apt-key adv --recv-keys --keyserver keyserver.Ubuntu.com F273FCD8
安装后,可以使用以下命令升级到较新版本的Bazel:
sudo apt-get upgrade bazel
注:安装bazel最新版本0.17.1出现无法正常编译mace
推荐的Android NDK版本包括r15b,r15c和r16b
# Download NDK r15c
cd /opt/
wget https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip
unzip android-ndk-r15c-linux-x86_64.zip
rm -f android-ndk-r15c-linux-x86_64.zip
配置NDK系统环境变量
sudo vim /etc/profile
在文件内最后追加
export ANDROID_NDK_VERSION=r15c
export ANDROID_NDK=/opt/android-ndk-${ANDROID_NDK_VERSION}
export ANDROID_NDK_HOME=${ANDROID_NDK}
# add to PATH
export PATH=${PATH}:${ANDROID_NDK_HOME}
查看是否安装成功
ndk-build
1 安装docker:sudo apt-get install docker.io
2 检查版本: docker version 当出现client和service表面安装成功
3 启动docker:systemctl start docker.service
4 更新docker
4.1 需要使用apt-get来升级,借助阿里的docker-ce源
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
4.2 sudo apt-get update
4.3 搜索源 apt-cache madison docker-ce
会出现版本,选择一个
4.4 sudo apt-get -y install docker-ce=17.09.0~ce-0~ubuntu --allow-unauthenticated
4.5 查看是否更新
sudo docker version
首先,确保已经正确设置了环境
git clone https://github.com/XiaoMi/mace.git
cd mace/
git fetch --all --tags --prune
# Checkout the latest tag (i.e. release version)
tag_name=`git describe --abbrev=0 --tags`
git checkout tags/${tag_name}
git clone https://github.com/XiaoMi/mace-models.git
cd path/to/mace
# Build library
# output lib path: builds/lib
bash tools/build-standalone-lib.sh
注:编译时如果NDK没有设置环境变量会提示未找到NDK则需要配置NDK路径
在mace源码根目录下有一个WORKSPACE文件,请把你的NDK 路径配置在android_ndk_repository下
NDK路径是相对于mace源码的根目录
# Set up Android NDK
android_ndk_repository(
name = "androidndk",
# Android 5.0
api_level = 21,
path="../../Android/Sdk/ndk-bundle",
)
cd path/to/mace
# Build library
python tools/converter.py convert --config=/path/to/mace-models/mobilenet-v2/mobilenet-v2.yml
注: 在转换模型过程中,如果mobilenet-v2.yml格式为code时,不知为何只要Android Studio打开Demo工程就无法转换成功,关闭后就可以,但是格式为file时就不存在此问题
位置:mace/examples/android
使用以下方法之一可以生成APK
android工程目录下有一个build.sh的配置文件,运行就可以编译,但是该配置使用的模型是mobilenet,该模型只有arm64-v8a平台,而现在手机大部分是armeabi-v7a平台,所以改成使用模型mobilenet-v2
打开build.sh文件
TARGET_ABI=arm64-v8a
修改成
TARGET_ABI=armeabi-v7a
python tools/converter.py convert --config=mace/examples/android/mobilenet.yml --target_abis=$TARGET_ABI
cp -rf builds/mobilenet/include/mace/public/*.h $INCLUDE_DIR
cp -rf builds/mobilenet/model $LIBRARY_DIR
重新指定模型路径
mobilenet-v2模型路径:mace-models/mobilenet-v2/mobilenet-v2.yml替换mobilenet模型路径:mace/examples/android/mobilenet.yml
模型转换成功后会builds下生成mobilenet-v2目录
将mobilenet-v2替换mobilenet
修改完成如下所示
python tools/converter.py convert --config=mace-models/mobilenet-v2/mobilenet-v2.yml --target_abis=$TARGET_ABI
cp -rf builds/mobilenet-v2/include/mace/public/*.h $INCLUDE_DIR
cp -rf builds/mobilenet-v2/model $LIBRARY_DIR
打开macelibrary Module下CMakeLists.txt文件
set(mace_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/lib/arm64-v8a/libmace.a)
set(mobilenet_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/model/arm64-v8a/mobilenet.a)
将arm64-v8a平台换成armeabi-v7a
将mobilenet.a 修改成 mobilenet-v2.a
修改完成如下所示
set(mace_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/lib/armeabi-v7a/libmace.a)
set(mobilenet_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/model/armeabi-v7a/mobilenet-v2.a)
打开macelibrary Module工程下的build.gradle
abiFilters "arm64-v8a"
修改成
abiFilters "armeabi-v7a"
file:文件格式,tensorflow的模型将转换成 .pb格式文件
code:c++代码格式,模型加密与保护
模型转换成C++代码,防止反编译有效保护模型
model_graph_format: file
model_data_format: file
将模型图形格式和模型数据格式都转换为代码
model_graph_format: code
model_data_format: code
具体操作将mace-models/mobilenet-v2 目录下的mobilenet-v2.yml和mobilenet-v2-host.yml都修改为code,修改完成如下所示
library_name: mobilenet-v2
target_abis: [armeabi-v7a, arm64-v8a]
model_graph_format: code
model_data_format: code
在项目根目录下local.properties文件设置SDK和NDK
sdk.dir=E\:\\AndroidStudio\\SDK
ndk.dir=E\:\\AndroidStudio\\android-ndk-r16b
在项目根目录下运行
./build.sh
注:因为编译时有进行模型转换,如上所注,在编译的时候Android Studio不能打开该Demo工程,否则编译将出现错误。编译完成后可能会因为没有连接设备而提示错误,但是可以在app/build/outputs下看是否有成功打包apk
将mace-models/mobilenet-v2 目录下的mobilenet-v2.yml和mobilenet-v2-host.yml都修改为code,修改完成如下所示
library_name: mobilenet-v2
target_abis: [armeabi-v7a, arm64-v8a]
model_graph_format: code
model_data_format: code
修改完后使用命令转换
python tools/converter.py convert --config=/path/to/mace-models/mobilenet-v2/mobilenet-v2.yml
注:ndk如果设置最新的版本将无法正常编译,请选择推荐的版本
在Demo项目中的macelibrary/src/main/cpp 目录下
1 新建include/mace/public文件夹
1.1 将builds/include/mace/public/ 下的mace.h 和 mace_runtime.h复制到该文件夹下
1.2 将builds/mobilenet-v2/include/mace/public/ 下的mace_engine_factory.h 、mobilenet_v2.h复制到该文件夹下
2 新建lib文件夹
2.1 将builds/lib下的arm64-v8a、armeabi-v7a和linux-x86-64复制到该文件夹下
2.2 将cpu_gpu/下的libmace.a、libmace.so文件复制到与此同级别目录后删除cpu_gpu文件夹
3 新建model文件夹
3.1 将builds/mobilenet-v2/model 下的 arm64-v8a/mobilenet-v2.a、armeabi-v7a/mobilenet-v2.a复制到该文件夹下
3.2 将mobilenet-v2.a 重命名为 mobilenet.a 或 修改CMakeLists.txt文件 将mobilenet.a 改为 mobilenet-v2.a 如下
set(mobilenet_lib ${CMAKE_SOURCE_DIR}/src/main/cpp/model/arm64-v8a/mobilenet-v2.a)
修改以下代码,加载使用模型mobilenet_v2后点击运行