学习MACE也有一个月了,将其划分三步来学习。本文是MACE学习的第一步即MACE环境的搭建。之后还有两步mace的编译和mace工程化。

  MACE(2)-----模型编译:https://www.cnblogs.com/missidiot/p/9509831.html

  MACE(3)-----工程化:https://www.cnblogs.com/missidiot/p/9717633.html

文章内容翻译自 MACE 官方手册,记录本人阅读与开发过程,力求不失原意,但推荐阅读原文。

  MACE官方文档:https://media.readthedocs.org/pdf/mace/latest/mace.pdf

  小米MACE Github地址:https://github.com/xiaomi/mace

  小米MACE安装说明:https://mace.readthedocs.io/en/latest/

  

MACE

目录

  介绍

  环境搭建

  实例运行

一、简介(Introduction)

  MACE(移动AI计算引擎)是小米开发的一款针对移动异构计算平台优化的深度学习推理框架。MACE覆盖了常见的移动端计算设备(CPU,GPU和DSP),并且提供了完整的工具链和文档,帮助用户将深度学习模型部署到手机,平板电脑,个人电脑和物联网设备。MACE已经在小米内部广泛使用并且被充分验证具有业界领先的性能和稳定性。

框架(Architecture)

  上图描述了MACE的基本框架。

1. MACE Model

  MACE定义了自有的模型格式(类似于Caffe2),通过MACE提供的工具可以将Caffe和TensorFlow的模型 转为MACE模型。

2. MACE Interpreter

  MACE Interpreter主要负责解析运行神经网络图(DAG)并管理网络中的Tensors。

3. Run Time

  CPU/GPU/DSP Runtime对应于各个计算设备的算子实现。

使用流程

1. 配置模型部署文件(model.yml)

  模型部署文件详细描述了需要部署的模型以及生成库的信息,MACE根据该文件最终生成对应的库文件。

2. 编译MACE库

  编译MACE的静态库或者动态库。

3. 模型转换

  将TensorFlow 或者 Caffe的模型转为MACE的模型。

4.1 部署

  根据不同使用目的集成Build阶段生成的库文件,然后调用MACE相应的接口执行模型。

4.2 命令行运行

  MACE提供了命令行工具,可以在命令行运行模型,可以用来测试模型运行时间,内存占用和正确性。

4.3 Benchmark

  MACE提供了命令行benchmark工具,可以细粒度的查看模型中所涉及的所有算子的运行时间。

总结 

  以上步骤是基于官方文档,以下为博主理解:最初我们设计算法为python文件(model.py)训练完成后生成model.pb模型文件。再将model.pb文件部署在model.yml文件中,之后经过编译转换将model.yml文件经过converter.py转换生成库文件。最终进入第四步按需求去调用这些库文件即可。

二、环境搭建

  环境要求:本文基于Ubuntu 16.04搭建,所需安装的软件主要包括docker,bazel和Android jdk,以及python的依赖库,Cmake在构建工程时候Android stdio会自动更新下载。当这些所需的库安装好后便可以在MACE官方pull mace镜像了。

  下图为所需的依赖库:

1. 在Ubuntu16.04下安装Docker 

1.1 安装docker:sudo apt-get install docker.io
1.2 检查版本: docker version 当出现client和service表面安装成功
1.3 启动docker:systemctl start docker.service
1.4 更新docker 

  1.需要使用apt-get来升级,借助阿里的docker-ce源
    sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
  2.sudo apt-get update
  3.搜索源
    apt-cache madison docker-ce

  会出现版本,选择一个
  4.sudo apt-get -y install docker-ce=17.09.0~ce-0~ubuntu --allow-unauthenticated
  5.查看是否更新
    sudo docker version

 1.5 设置开机自启动
    sudo systemctl enable docker

  然后再重启:
    systemctl restart docker

2. python库的安装(python2.7)  

库的安装需要加 --user
比如:
  pip install -I --user filelock==3.0.0
或者:
  pip install tensorflow

3.安装Android NDK(r15b, r15c and r16b )

  注:不要下载最新版的,博主下的17b出现问题。

3.1 由于挂载在/opt文件夹下面,需要权限,所以首先进入到管理员状态
  sudo su
3.2 进入到/opt文件下面
  cd opt
3.3 执行下面命令下载(博主采用的是r15c的版本,测试可用)
  wget -q https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip
3.4 在此目录下面进行解压
  unzip -q android-ndk-r15c-linux-x86_64.zip
3.5 导入环境变量(红色版本根据自己下载更改)
  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}
3.6 变量生效:source /etc/profile
3.7 验证是否生效:ndk-build
  注:若出现以下这些表明安装成功。
  Android NDK: Could not find application project directory !  
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.   
  /home/weilong/android/android-ndk-r16b/build/core/build-local.mk:151: *** Android NDK: Aborting . Stop.

4. 在Linux下面安装bazel

4.1安装Jdk8
  sudo apt-get install openjdk-8-jdk
4.2在包资源中增加Bazel的发布源
  4.2.1 echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
  4.2.2 curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
4.3 安装Bazel
  sudo apt-get update && s 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
4.4 更新Bazel
  sudo apt-get upgrade bazel
4.5 导入路径(红色版本号根据自己查看的写)
  查看版本:bazel version
  export BAZEL_VERSION=0.13.1
4.6 创建bazel环境
  创建一个bazel目录: sudo mkdir /bazel
进入到该目录: cd /bazel
下载bazel安装文件: wget https://github.com/bazelbuild/bazel/releases/download/$BAZEL_VERSION/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh
赋予执行权限: chmod +x bazel-*.sh
执行该安装文件: ./bazel-$BAZEL_VERSION-installer-linux-x86_64.sh
进入根目录: cd /
移除该源文件: rm -f /bazel/bazel-$BAZEL_VERSION-installer-linux-x86_64.sh

5. 构建MACE镜像

  MACE提供已安装依赖项的docker镜像以及用于构建镜像的Dockerfiles,您可以直接拉取现有的镜像或从Dockerfiles构建它们。在大多数情况下,镜像可以满足开发人员的基本需求。

 5.1.创建镜像

  MACE镜像已经在docker环境创建好了,有两种创建方式,pull或者build。官方提供的MACE镜像有两种,lite版和full版。官方强烈建议pull来构建镜像到本地,建议读者在docker的学习上花一点时间。

  1.1 lite版本    

# Pull lite edition docker image
docker pull registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev-lite
# Build lite edition docker image
docker build -t registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev-lite ./docker/mace-dev-lite

  1.2 full版本

# Pull full edition docker image
docker pull registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev
# Build full edition docker image
docker build -t registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev ./docker/mace-dev

 5.2 使用镜像

启动docker
2.1 创建一个mace-dev的容器
docker run -it --privileged -d --name mace-dev \
-v /dev/bus/usb:/dev/bus/usb --net=host \
-v /local/path:/container/path \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
registry.cn-hangzhou.aliyuncs.com/xiaomimace/mace-dev
2.2 执行该容器 docker exec -it mace-dev /bin/bash

  本文直接pull的mace-dev版本。如下图所示构建的镜像为mace-dev为13.4GB,并开启了一个容器,ID为12899***。

  至此,MACE环境就搭建起来了,下一节内容为构建一个实例,演示如何通过MACE来转模型文件。

现在开启一个容器,在容器中pull mace项目:

1.sudo docker ps -a  #c查看镜像,会看见一个id
2. sudo docker start id #id为上条命令的id号码
3. sudo docker exec -it id bash #同理id为镜像的id

三、构建并运行实例模型

  我们以mobilenet-v2模型为例。

1. Pull MACE项目

git clone https://github.com/XiaoMi/mace.git

2. pull MACE Model Zoo 项目

git clone https://github.com/XiaoMi/mace-models.git

3. 编译MACE Library(后期发现这一步其实不用,当打开容器时候资源可以通用,在本地的都可以用,模型git到本地即可。这块后期再改)

  Question?如何在文件夹下找到容器中创建的文件?

  Answer!通过查看容器的Id找到位置。

  3.1 进入到mace路径下

3.1.1 首先对docker文件全部解锁,在cd /var/lib下执行命令:chmod -R 777 docker
3.1.2 方法一:通过ID在docker文件下找,
3.1.3 方法二:在docker下面直接搜索mace文件即可,mace文件已经在容器中了。

如上图所示就进入到了容器中的mace路径下,注意该操作得另起一个终端操作。

  3.2 进行编译

bash tools/build-standalone-lib.sh

  如上图所示即编译完成。

4. 模型转换成C++代码,防止反编译有效保护模型。有两种方法

  1. 将模型图转换为代码,将模型权重转换为文件
model_graph_format: code 
model_data_format: file
  2. 将模型图和模型权重都转换为代码
model_graph_format: code
model_data_format: code

  以mobilenet-v2为例子,将mace-models/mobilenet-v2 文件夹下的mobilenet-v2.yml和mobilenet-v2-host.yml都修改为code。

5. 将mobilenet-v2.yml模型转换为MACE格式

在mace路径下:cd /mace
python tools/converter.py convert --config=/var/lib/docker/aufs/diff/b1e110a3c38e93df0e36c475a137d390c6c44dc4299da4895494453d88f21e65/mace-models/
mobilenet-v2/mobilenet-v2.yml

  

  以上图片为转换过程,若出现则表明转换工作完成。

  以上的步骤已经将model.yml文件转换完毕形成库,之后的步骤就是将这些库加载到工程中形成model.apk文件部署在安卓终端中。

  在转换后所生成的库在mace/builds/文件夹下面;

  mace中的android工程路径;/mace/mcae/examples/android/这在后期用Android studio直接加载此工程即可。

  在加载之前我么需要将转换生成的库挂载到工程中。

  在android项目中的macelibrary/src/main/cpp 文件夹下,如下图所示
    -- 新建include/mace/public文件夹
    -- 新建lib文件夹
    -- 新建model文件夹

  1. 将builds/include/mace/public/ 下的mace.h 以及 mace_runtime.h拷贝进去macelibrary/src/main/cpp/include/mace/public中

  2. 将builds/mobilenet-v2/include/mace/public/ 下的mace_engine_factory.h 以及 mobilenet_v2.h拷贝至 macelibrary/src/main/cpp/include/mace/public中

   3. 将builds/mobilenet-v2/model 下的mobilenet-v2.a 拷贝至 macelibrary/src/main/cpp/model中,并修改mobilenet-v2.a 为 mobilenet.a

    4. 将builds/lib下的文件都拷贝至macelibrary/src/main/cpp/lib中,里面有三个文件夹,分别是arm64-v8a,armeabi-v7a和linux-x86-64。

    这三个文件是针对的终端硬件结构也不一致,读者自己百度,当往终端部署时候首先会找v8a的so文件,如果没有则向下兼容找v7a文件。arm是cpu的一种体系结构,x86用于平板或者电脑cpu结构。

    4.1 我们需要将各个版本的下的/cpu_gpu下的文件复制到与此同级别目录,还有个dsp体系结构,本例子暂不介绍。

    4.2 将model下的mobilenet.a文件同样复制到各个体系结构下。如下图所示:

  5. macelibrary/src/main/cpp/include/mace/public下所有.h文件都要被引入,如下图,总共有四个.h文件

    mace.h不需要引入

    mace_runtime需要引入mace.h

    mace_mobilenet.h需要引入mace.h 和mace_runtime.h

    mace_engine_factory.h需要引入mace.h 和mace_runtime.h,同理如下图所示

  至此以上的工作模型经过编译转换,并且将生成的库加载在工程文件中,这个工作已经完成,下一步将在Android studio中加载工程 ,并运行生成apk文件在终端。

  打开Android stdio,在File下找到Project Structure加载NDK路径。

  在Android studio加载在/var/lib/docker/aufs/diff/b1e110a3c38e93df0e36c475a137d390c6c44dc4299da4895494453d88f21e65/mace/mace/examples下的android工程

由于这个测试的app默认是使用mobilenet_v1的模型的,所以我们更改一下代码让他使用mobilenet_v2,修改com.xiaomi.mace.demo.result下的InitData.java文件中的
model = MODELS[0];改为:model = MODELS[];即可

运行后的结果如下图所示,该实例功能是物体实时识别;下篇博文会会针对mobilenet_v2.pb文件分析网络结构。

如果遇到卡退问题,原因是权限要读写外部存储卡,权限不够导致,在客户端apk设置下赋予权限即可。

本文仅用于学习研究,非商业用途,欢迎大家指出错误一起学习,文章内容翻译自 MACE 官方手册,记录本人阅读与开发过程,力求不失原意,但推荐阅读原文。

MACE官方文档:https://media.readthedocs.org/pdf/mace/latest/mace.pdf

小米MACE Github地址:https://github.com/xiaomi/mace

小米MACE安装说明:https://mace.readthedocs.io/en/latest/

  

MACE(1)-----环境搭建的更多相关文章

  1. .NET Core系列 : 1、.NET Core 环境搭建和命令行CLI入门

    2016年6月27日.NET Core & ASP.NET Core 1.0在Redhat峰会上正式发布,社区里涌现了很多文章,我也计划写个系列文章,原因是.NET Core的入门门槛相当高, ...

  2. Azure Service Fabric 开发环境搭建

    微服务体系结构是一种将服务器应用程序构建为一组小型服务的方法,每个服务都按自己的进程运行,并通过 HTTP 和 WebSocket 等协议相互通信.每个微服务都在特定的界定上下文(每服务)中实现特定的 ...

  3. rnandroid环境搭建

    react-native 环境搭建具体步骤这个大家已经玩烂了,这个主要是记录下来自己做win7系统遇到的坑 1.com.android.ddmlib.installexception 遇到这个问题,在 ...

  4. python开发环境搭建

    虽然网上有很多python开发环境搭建的文章,不过重复造轮子还是要的,记录一下过程,方便自己以后配置,也方便正在学习中的同事配置他们的环境. 1.准备好安装包 1)上python官网下载python运 ...

  5. springMVC初探--环境搭建和第一个HelloWorld简单项目

    注:此篇为学习springMVC时,做的笔记整理. MVC框架要做哪些事情? a,将url映射到java类,或者java类的方法上 b,封装用户提交的数据 c,处理请求->调用相关的业务处理—& ...

  6. 【定有惊喜】android程序员如何做自己的API接口?php与android的良好交互(附环境搭建),让前端数据动起来~

    一.写在前面 web开发有前端和后端之分,其实android还是有前端和后端之分.android开发就相当于手机app的前端,一般都是php+android或者jsp+android开发.androi ...

  7. Nexus(一)环境搭建

    昨天,成功搭建了自己的 Maven 环境(详见:Maven(一)环境搭建),今天就来研究和探讨下 Nexus 的搭建! 使用背景: 安装环境:Windows 10 -64位 JDK版本:1.7 Mav ...

  8. 「译」JUnit 5 系列:环境搭建

    原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...

  9. appium+robotframework环境搭建

    appium+robotframework环境搭建步骤(Windows系统的appium自动化测试,只适用于测试安卓机:ios机需要在mac搭建appium环境后测试) 搭建步骤,共分为3部分: 一. ...

随机推荐

  1. Prometheus jvm_exporter监控zookeeper

    Zookeeper Prometheus 监控zookeeper使用jvm_exporter来采集数据,jvm_exporter是一个可以配置抓取和暴露JMX目标的mBeans的收集器. 下载java ...

  2. IDEA下搜狗输入法输入中文时卡着不动的参考解决方法

    在IntelliJ IDEA工具的java编辑窗口,给代码增加注释时发现,输入中文时,搜狗输入法界面不动,一直卡着,如图:  我想输入“根据”两个字,但搜狗输入法界面一直卡着不刷新,导致都不知道自己输 ...

  3. jquery :checked(过滤选择器) 和 空格:checked(后代选择器)【转】

    jquery 过滤选择器 和 后代选择器 <%@ page language="java" contentType="text/html; charset=UTF- ...

  4. 骨骼动画的原理及在Unity中的使用

    制作骨骼动画 我们看看这几步操作后,我们得到了那些数据: 1.每个皮肤顶点的初始世界坐标. 2.每个骨骼关节顶点的初始世界坐标. 3.每个顶点被骨骼顶点的影响信息. 4.骨骼如何移动. 骨骼动画原理 ...

  5. Docker 入门 第三部分: 服务

    目录 Docker 入门 第三部分: 服务 先决条件 介绍 你的第一个 docker-compose.yml 文件 docker-compose.yml 运行你新建的负载均衡应用 扩展应用程序 卸载应 ...

  6. 浅谈分词算法(4)基于字的分词方法(CRF)

    目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...

  7. Git 设置过滤忽略的文件或文件夹(ignore file)

    我们一般向代码仓库提交项目的时候,一般需要忽略编译生成的中间文件以及文件夹的提交,因为它们是无用的,而且也会占用仓库的空间.一般只用提交.pro,.sln,makefile,程序源文件等编译必须用到的 ...

  8. 调用write()写

    一.在POSIX中的定义 #include <unistd.h> ssize_t write(int fd, const void *buf, size_t count); 二.返回值 ( ...

  9. Hadoop mapreduce执行过程涉及api

    资源的申请,分配过程略过,从开始执行开始. mapper阶段: 首先调用默认的PathFilter进行文件过滤,确定哪些输入文件是需要的哪些是不需要的,然后调用inputFormat的getSplit ...

  10. float导致出现大面积空白

    float导致出现大面积空白,解决方法: *{ padding: 0; margin: 0; overflow:hidden; }