MXNet的原始碼編譯過程總結
目的:理解深度學習主流框架的設計思路,從原始碼級別進行向上研究
過程:從虛擬機器開始,在Windows7+VMWare11+CentOS-6.6-x86_64,升級GCC,安裝openblas,opencv,升級python,安裝python依賴包,替換libstdc++
測試驗證image-classification]# python train_mnist.py
經驗:深度學習框架屬於C++層面的一個東西,一定要有耐心,不放棄;跟折騰Hadoop不是一個檔次的東西。
運氣:在2011年折騰Hadoop時,用個也是centos,一個好的os,一個新的開始。加油
第一步:準備VM
在windows下安裝好VM ware worksataion 11,通過CentOS-6.6-x86_64-bin-DVD1.iso來進行預設安裝。
該過程屬於準備過程,不重點講述,前提時該種模式下只能夠用CPU,不支援GPU.
確保yum能夠正常執行
第二步:升級GCC
安裝MXNet必須進行保證C++11能夠支援,首先需要升級GCC,從4.7升級4.8.4至少才行;我驗證的是直接升級到GCC6.3.0
操作步驟如下:
2.1下載相關的gcc-6.3.0.tar.bz2
wget https://mirrors.tuna.tsinghua.edu.cn/gnu/gcc/gcc-6.3.0/gcc-6.3.0.tar.bz2
tar-jxvf
gcc-6.3.0.tar.bz2
2.2 檢查依賴包
./contrib/download_prerequisites
預設檢查會要求必須安裝mpc,gmp,mpfr,isl
而這些基礎庫的包的版本都比較低,如果直接下載後,基本安裝都會失敗
終極解決方式,修改contrib/download_prerequisites
#MPFR=mpfr-2.4.2
MPFR=mpfr-3.1.5
#GMP=gmp-4.3.2
GMP=gmp-6.1.0
#MPC=mpc-0.8.1
MPC=mpc-1.0.3
通過修改預設的下載地址,指向國內地址
下載地址修改為down_url=https://mirrors.tuna.tsinghua.edu.cn/gnu/
isl選擇 0.18版本,下載地址:http://isl.gforge.inria.fr
保證下載完畢後,可以檢查下gcc-6.3.0下面的相關的目錄gmp,mpc,mpfr,isl的目錄情況如下:
gmp -> gmp-6.1.0
isl -> isl-0.18
mpc -> mpc-1.0.3
mpfr -> mpfr-3.1.5
注意:不需要單獨對gmp,mpc,mpfr,isl進行編譯,在編譯gcc時會自動編譯相關的依賴包。
2.3準備編譯gcc
新建目錄mkdir gcc-build-6.3.0
cd gcc-build-6.3.0
..
/gcc-6
.3.0
/configure
--
enable
-checking=release
--
enable
-languages=c,c++
--disable-multilib
檢查通過後,就會在gcc-build-6.3.0生成相關的config.status和config.log
裡面有非常完善的配置資訊
2.4 編譯
上面步驟正常的話,直接通過make -j4來編譯,-j是指定同時可運用的任務個數,跟虛擬機器的CPU核數對應即可。
如果順利的話,編譯成功;可以慶祝一下;
然後make install對gcc進行安裝。
安裝成功後,可以切換到gcc-6.3.0的目錄下,驗證下版本
[[email protected] bin]# ./x86_64-pc-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=./x86_64-pc-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/6.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-6.3.0/configure --enable-checking=release --enable-languages=c,c++ --disable-multilib
Thread model: posix
gcc version 6.3.0 (GCC)
2.5替換系統的GCC
先執行updatedb
再執行
[[email protected] bin]# update-alternatives --install /usr/bin/gcc gcc /usr/local/bin/x86_64-pc-linux-gnu-gcc 50
再次切換到新的視窗直接驗證gcc -v[[email protected]
contrib]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/6.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-6.3.0/configure --enable-checking=release --enable-languages=c,c++ --disable-multilib
Thread model: posix
gcc version 6.3.0 (GCC)
完成了GCC的升級後,長征才剛剛開始。
第三步:編譯MXNet
想編譯MXNet還需要好幾個步驟
3.1 安裝GIT
通過yum install git
下載mxnet的原始碼
git clone --recursive https://github.com/dmlc/mxnet 下載原始碼後,將make/config.mk複製到上一級目錄下 cp make/config.mk ../3.2 安裝openblas
根據mxnet的編譯設定,可以選擇blas,cblas,openblas
我的環境驗證,還是通過openblas來完成
openblas的安裝注意點:
make –j4 會報錯,採用如下的方式 make NO_LAPACKE=1 NO_SHARED=1 NO_AVX2=1 編譯完成後,可以使用make install make PREFIX=/use/local/opt/openblas install在mxnet的config.mk檔案裡面,需要修改:
# the additional link flags you want to add
ADD_LDFLAGS = '-L/usr/local/opt/openblas/lib'
# the additional compile flags you want to add
ADD_CFLAGS = '-I/usr/local/opt/openblas/include'
修改配置USE_BLAS為openblas,之前的atlas不靠譜
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S), Darwin)
USE_BLAS = apple
else
USE_BLAS = openblas
endif
3.3安裝opencv
先下載opencv的包,編譯通過cmake
cmake CMakeLists.txt -DENABLE_PRECOMPILED_HEADERS=OFF 再執行make -j2
在opencv編譯的過程出現編譯錯誤:
•make[2]:*** [modules/contrib/CMakeFiles/opencv_contrib.dir/src/chamfermatching.cpp.o]Error 1 •make[1]:*** [modules/contrib/CMakeFiles/opencv_contrib.dir/all]Error 2 則修改目錄opencv/modules/contrib/CMakeFiles/opencv_contrib.dir下的flags.make將裡面的-Werror=address遮蔽掉
然後編譯通過
說明:MXNet的編譯也可以不需要opencv可以在config.mk中配置
第四步:驗證框架
在MXNet編譯完成後,需要驗證python的例項,接下來還有一些坑
4.1升級python2.6.6到python2.7.8
注意python2.7.8安裝後,會導致yum不可用,還需要修改yum的配置值執行python2.6
4.2安裝mxnet的python庫
在mxnet/python下面執行
python setup.py instll
會出現一系列錯誤,第一個就是缺少setuptools,可以從如下地址下載
同樣的方式還需要下載安裝 Graphviz,安裝graphviz-0.7.1.zip 下載安裝requests-2.18.1.tar.gz 依賴certifi-2017.4.17.tar.gz,urllib3,idna,chardet,requests-2.18.1完畢,然後安裝mxnet 提示缺少numpy,下載numpy待上述的包都安裝完畢後
python setup.py install完成了,原則上,就要成功了;但是,在執行
mxnet/example/image-classification的
python train_mnist.py時仍然有一個錯誤
•OSError: /usr/lib64/libstdc++.so.6:version `CXXABI_1.3.7' not found (required by /home/mxnet/mxnet/python/mxnet/../../lib/libmxnet.so) 4.3 解決libstdc++的問題從上一步的坑來看,屬於gcc的新版本所編譯的libstdc++的包沒有更新到位
首先檢查:
•[[email protected]]$ strings /usr/lib64/libstdc++.so.6| grep CXXABI •CXXABI •CXXABI_1.3 •CXXABI_1.3.1 •CXXABI_1.3.2 •CXXABI_1.3.3 •缺少錯誤提示的: CXXABI_1.3.7 •關注libstdc++.so.6 目前的版本的確沒有支援到CXXABI的1.3.7經過一番周折,可以冷靜的看下
•GCC版本4.6.7 •libstdc++ 【libstdc++.so.6,libstdc++.so.6.0.13】 •GCC版本6.3.0 •libstdc++【6.0.22】 •libstdc++.so.6-> libstdc++.so.6.0.22 兩個版本的libstdc++.so.6的子版本是不一致的,最新的是6.0.22,之前的是6.0.13解決方法,先找到gcc6.3.0的libstdc++的新包的位置
gcc-build-6.3.0/x86_64-pc-linux-gnu/libstdc++-v3/src/.libs該目錄下面具有libstdc++.so.6.0.22
實施過程:
•$cp /usr/local/lib64/libstdc++.so.6.0.22/usr/lib64 •$rm -rf /usr/lib64/libstdc++.so.6 •$ln -s /usr/lib64/libstdc++.so.6.0.22/usr/lib64/libstdc++.so.6 •$strings /usr/lib64/libstdc++.so.6| grep GLIBC •$strings /usr/lib64/libstdc++.so.6| grep CXXABI驗證效果:
strings/usr/lib64/libstdc++.so.6| grep GLIBC
strings/usr/lib64/libstdc++.so.6| grep CXXABI
能夠看到最新的CXXABI的1.3.7版本
4.4驗證例項
python train_mnist.py
•[[email protected]]# python train_mnist.py •INFO:root:start witharguments Namespace(batch_size=64, disp_batches=100,gpus=None,kv_store='device',load_epoch=None,lr=0.05,lr_factor=0.1,lr_step_epochs='10',model_prefix=None,mom=0.9, monitor=0, network='mlp', num_classes=10, num_epochs=20, num_examples=60000,num_layers=None,optimizer='sgd', test_io=0, top_k=0, wd=0.0001) •DEBUG:urllib3.connectionpool:Startingnew HTTP connection (1): yann.lecun.com •DEBUG:urllib3.connectionpool:http://yann.lecun.com:80"GET /exdb/mnist/train-labels-idx1-ubyte.gzHTTP/1.1" 200 28881 •DEBUG:urllib3.connectionpool:Startingnew HTTP connection (1): yann.lecun.com •DEBUG:urllib3.connectionpool:http://yann.lecun.com:80"GET /exdb/mnist/train-images-idx3-ubyte.gzHTTP/1.1" 200 9912422 ...INFO:root:Epoch[18]Time cost=68.180
INFO:root:Epoch[18]Validation-accuracy=0.983181
INFO:root:Epoch[19]Batch [100] Speed: 886.52 samples/sec accuracy=0.999381
INFO:root:Epoch[19]Batch [200] Speed: 906.23 samples/sec accuracy=0.999844
INFO:root:Epoch[19]Batch [300] Speed: 898.08 samples/sec accuracy=0.999687
INFO:root:Epoch[19]Batch [400] Speed: 895.47 samples/sec accuracy=0.999687
INFO:root:Epoch[19]Batch [500] Speed: 902.25 samples/sec accuracy=0.999687
INFO:root:Epoch[19]Batch [600] Speed: 889.98 samples/sec accuracy=0.999844
INFO:root:Epoch[19]Batch [700] Speed: 894.61 samples/sec accuracy=0.999687
INFO:root:Epoch[19]Batch [800] Speed: 891.82 samples/sec accuracy=0.999844
INFO:root:Epoch[19]Batch [900] Speed: 891.19 samples/sec accuracy=1.000000
INFO:root:Epoch[19]Train-accuracy=0.999578
INFO:root:Epoch[19]Time cost=67.026
INFO:root:Epoch[19]Validation-accuracy=0.983380
ps:OS、GCC、Python、編譯屬於基礎功,堅持努力