MACE(1)-----環境搭建

學習MACE也有一個月了,將其劃分三步來學習。本文是MACE學習的第一步即MACE環境的搭建。以後還有兩步mace的編譯和mace工程化。html

  MACE(2)-----模型編譯:http://www.javashuo.com/article/p-edzhmnkd-cu.htmljava

  MACE(3)-----工程化:http://www.javashuo.com/article/p-qdlrywha-dx.htmlpython

文章內容翻譯自 MACE 官方手冊,記錄本人閱讀與開發過程,力求不失原意,但推薦閱讀原文。linux

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

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

  小米MACE安裝說明:https://mace.readthedocs.io/en/latest/github

  

MACE

目錄

  介紹

  環境搭建

  實例運行

1、簡介(Introduction)

  MACE(移動AI計算引擎)小米開發的一款針對移動異構計算平臺優化的深度學習推理框架MACE覆蓋了常見的移動端計算設備(CPU,GPU和DSP),而且提供了完整的工具鏈和文檔,幫助用戶將深度學習模型部署到手機,平板電腦,我的電腦和物聯網設備。MACE已經在小米內部普遍使用而且被充分驗證具備業界領先的性能和穩定性。算法

框架(Architecture)docker

  上圖描述了MACE的基本框架。ubuntu

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轉換生成庫文件。最終進入第四步按需求去調用這些庫文件便可。

2、環境搭建

  環境要求:本文基於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

3、構建並運行實例模型

  咱們以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[ 1];便可

 運行後的結果以下圖所示,該實例功能是物體實時識別;下篇博文會會針對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/

相關文章
相關標籤/搜索