ARM64+ubuntu18.04深度學習環境安裝小結
概述
本人斷斷續續花費了兩週時間,在某國產ARM64+linux環境的伺服器上,使用docker容器安裝成功了公司深度學習專案所需的環境。中間過程坎坷,在此結文以記,希望能對他人有所幫助,少踩坑。
目前成功搭建的環境如下:aarch64 docker容器,ubuntu18.04, python2, opencv3.3, dlib19.15, tensorflow1.5, sklearn。
上述元件均是python繫結的版本。
環境描述
硬體環境為國產ARM64多核處理器,記憶體及磁碟均是x84伺服器的水平,所以不像樹莓派一樣需要擔心記憶體或磁碟。作業系統為類linux 64位,可以安裝docker,所以我的環境安裝均在docker容器內進行,沒有在物理機上安裝,也是怕來回安裝搞壞host系統。
我需要的是python的執行環境,由於arm伺服器不普及,所以網上很多安裝c++版本的方法,並不適用我的環境,中間費了我很多時間。由於配置給力,編譯時間上和x86伺服器差別不大,最終使用cpu前向推理的時間,與x86的cpu在同一數量級,完全可以作為生產環境使用。
docker映象
提前有人在物理機上安裝好了docker環境,所以我沒有涉及安裝docker本身的過程,只是涉及選取docker映象的問題。
由於ARM和x86指令集的差異,x86的docker映象不能直接執行在ARM伺服器上,部門之前用於生產的x86 docker映象沒法使用。我自己不是docker專家,沒有從0搭建docker映象的經驗,所以從網上下載現成的基礎映象。
在命令列上搜索arm64映象的方法為:
docker search arm64
也可以把arm64換成其他字元,搜尋想要的映象。可以從搜尋結果中看到已經有很多ARM64的docker映象可選了,完全可以選擇下來然後再安裝自己的東西。
搜尋結果和命令列基本一致,但是可以翻頁,可以用空格隔開多個關鍵字搜尋,還看到每個映象更詳細的資訊,比如tag等資訊。
我最終選擇的版本是arm64v8/ubuntu:18.04。拉取的方法如下:
docker pull arm64v8/ubuntu:18.04
然後用docker images就可以看到拉到本地的映象啦。剛拉下來的映象大小隻有幾百兆,可以run起來以後在裡面安裝自己的環境了,剩下的就是在ubuntu下的操作。
我剛開始用的並不是ubuntu18.04,還試過debian和ubuntu16.04, 但是有環境不相容等各種坑,全部元件安裝成功的就是18.04版本。
使用國內軟體源
ubuntu系統下安裝軟體需要配置好軟體源。由於眾所周知的原因,國內訪問一些境外網站往往連線失敗或者速度很慢,所以需要配置國內的映象源地址。國內中科大和清華的軟體源映象都很快。我使用的是中科大的。
然後更新本地軟體目錄:
apt-get update
各個元件的安裝過程
本節內容記錄最終走通的方法和對應版本,中間無數次失敗的經驗按下不表。
使用apt-get 安裝python、python-dev、python-pip都是小菜一碟,不費口舌了。我選擇的python2.7,其它版本應該與之類似。
dlib
dlib是從原始碼編譯安裝的,在ubuntu16.04和debian上總有問題,最終在ubunut18.04上成功。
準備工作:
apt-get update
apt-get install python
apt-get install python-pip
apt-get install pkg-config
apt-get install libopenblas-dev liblapack-dev
apt-get install cmake
apt-get install libboost-all-dev
在dlib19.15原始碼目錄下,執行python setup.py install
開啟python2, import dlib成功
opencv
opencv選擇的是3.3版本。從原始碼編譯安裝。
編譯技巧是,把’原始碼目錄/modules’下的dnn、highgui和videoio刪掉。這幾個模組總是會找不到標頭檔案和一些連結符號。videoio負責讀取視訊,刪掉後無法從視訊抽幀,剛好專案上用不到,所以對我沒影響。
當然,完全照搬別人的方法可能會失敗。要靈活變通。
我看了好幾個方法,把相關軟體包都安裝上了。我安裝軟體包的命令包括下面這些:
pip install pkg-config
apt-get install libsm6
apt-get install libxrender1
apt-get install libxext-dev
apt-get install build-essential
apt-get install python-dev
apt-get install libgtk2.0-dev
apt-get install libx11-dev
apt-get install libavcodec-dev libavformat-dev libswscale-dev
apt-get install libtbb2 libtbb-dev
apt-get install libjpeg-dev libpng-dev
apt-get install libtiff-dev
apt-get install libdc1394-22-dev
apt install gphoto2 libgphoto2*
apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good
apt-get install libv4l-dev
apt-get install libxvidcore-dev libx264-dev
apt-get install libgtk-3-dev
apt-get install libatlas-base-dev gfortran
apt-get install libxvidcore-dev libx264-dev
pip install -i http://mirrors.aliyun.com/pypi/simple/ numpy --trusted-host mirrors.aliyun.com
上面是準備工作,下面才是正式開始編譯:
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D INSTALL_C_EXAMPLES=OFF -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D PYTHON_EXECUTABLE=/usr/bin/python -D PYTHON_NUMPY_INCLUDE_DIRS=/usr/local/lib/python2.7/dist-packages/numpy/core/include/ ..
(去掉videoio和dnn、highgui)
make -j8
make install
啟動python, import cv2 成功。
當然,如果需要完整版本的python-opencv又不想自己折騰,可以去https://hub.docker.com/搜尋arm64版本的python-opencv映象,那裡有一個別人構建好的完整的版本。
tensorflow
在ubuntu18.04上,1.3版本的有些問題,最終使用1.5版本的執行模型成功。
下載完whl檔案後,安裝命令是:
pip install -i http://mirrors.aliyun.com/pypi/simple/ tensorflow-1.5.0-cp27-none-linux_aarch64.whl --trusted-host mirrors.aliyun.com
這裡之所以把阿里的python源url加進去,是因為安裝過程還需要下載一些依賴包,從國外下載太慢。
其它
為了加速下載,pip安裝時我一般手動指定阿里的python源:
pip install -i http://mirrors.aliyun.com/pypi/simple/ 軟體包名 --trusted-host mirrors.aliyun.com
像sklearn等其它python元件就可以這麼安裝。如果下載的python包包含二進位制檔案不適合arm架構,pip會自動失敗。能成功pip安裝的執行起來就沒問題。
那些年,那些坑
這一小節記錄一下自己採坑的過程。
tensorflow的坑
- 成功結果:ubuntu18.04 + tf1.5
- 失敗的嘗試:ubuntu18.04 + tf1.3, ubuntu16.04 + tf1.5/1.7
剛開始在ubuntu16.04上安裝,tf1.7和tf1.5都依賴於比較新的c++標準庫,現象就是在安裝時沒有報錯,import的時候找不到依賴的庫版本。
。
可是在16.04上死活升不上去,後來換成tf1.3才終於不再報錯。
坑爹的是在ubuntu16.04上dlib總是出錯,不得已換成ubuntu18.04。這會dlib不出錯了,import tensorflow的時候也沒錯誤,但是執行程式時出錯了,錯誤為:
2018-08-09 11:57:54,234 [ERROR] [MainThread] [tf_model_pkg2.py:180] tfSession_exception:No OpKernel was registered to support Op 'Switch' with these attrs. Registered devices: [CPU], Registered kernels:
device='GPU'; T in [DT_STRING]
device='GPU'; T in [DT_BOOL]
device='GPU'; T in [DT_INT32]
device='GPU'; T in [DT_FLOAT]
device='CPU'; T in [DT_FLOAT]
device='CPU'; T in [DT_INT32]
[[Node: Bottleneck/BatchNorm/cond/Switch = Switch[T=DT_BOOL](phase_train, phase_train)]]
在國外某個論壇上有類似的問題,需要改原始碼重新編譯,由於重新編譯也很曲折,我在ubuntu18.04上解除安裝tf1.3, 重灌了tf1.5,才終於解決了問題。
delib的坑
- 成功的結果:ubuntu18.04 + dlib19.15
- 失敗的嘗試:ubuntu16.04 + dlib19.15
一開始在ubuntu16.04上使用pip安裝dlib,安裝可以成功,但是import的時候會報錯:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: /usr/local/lib/python2.7/dist-packages/dlib.so: undefined symbol: cblas_ddot
找不到符號,我以為程式碼編譯就好了,結果還是同樣的問題。懷疑過dlib版本是不是太新了,也懷疑過python版本,一一嘗試都照樣失敗。
我注意到人家執行以下命令是有輸出的:
pkg-config --libs cblas
在我的系統上就報錯找不到cbals.pc。結合cmake時生成的資訊:
-- Searching for BLAS and LAPACK
-- Searching for BLAS and LAPACK
-- Found PkgConfig: /usr/local/bin/pkg-config
-- Checking for module 'cblas'
-- Found cblas, version
-- Checking for module 'lapack'
-- Found lapack, version
-- Found BLAS and LAPACK via pkg-config
.......
-- Looking for cblas_ddot
-- Looking for cblas_ddot - found
-- A library with BLAS API not found. Please specify library location.
-- LAPACK requires BLAS
To compile Boost.Python yourself download boost from boost.org and then go into the boost root folder
-- and run these commands:
-- ./bootstrap.sh --with-libraries=python
-- ./b2
-- sudo ./b2 install
結合上述資訊,我推斷pkg-config在我下載的那個ubuntu16.04上不能正常工作,無法為cmake指令碼找到blas的依賴資訊。個人對pkg-config機制也不熟,只能想辦法繞過去。
因此,放棄ubuntu16.04,換為ubuntu18.04。果然,在ubuntu18.04上只要安裝了openblas,就可以用‘pkg-config –libs cblas’得到相關資訊。
最終,ubuntu18.04 + dlib19.15程式碼編譯安裝成功,import無錯誤,簡單程式測試沒有問題。我想在18.04上應該可以pip安裝dlib,應該也不會出錯,只是我後來沒試。
opencv的坑
- 成功的結果:opencv3.3去掉dnn、highgui和videoio以後編譯安裝成功
- 失敗的結果: opencv全程式碼安裝
為了opencv,從作業系統版本、python版本、opencv版本各個組合都試了,都解決不了問題。
首先,pip能安裝的opencv版本有python3.4的。但是為了使用找到的預編譯的tenorflow,我只能選擇python2.7或者python3.5。
opencv的問題首先變現在編譯時找不到標頭檔案:
fatal error: gst/gst.h: No such file
其實這個標頭檔案在系統下是有的,就是找不著。這個錯誤屬於videoio模組。如果手動把標頭檔案目錄加到CPATH裡面然後export,後面highgui也會報幾個類似的錯誤。若都手動把標頭檔案目錄加到CPATH裡編譯通過,安裝後import v2會報以下錯誤:
undefined symbol: _gst_fraction_type
暫時沒有性子去分析opencv的cmake規則,就只能先刪掉highgui和videoio模組編譯,果然沒有錯誤。dnn之所以被刪掉,是因為cmake的時候會下載一個很大的caffe模型檔案,耽誤時間。
對於ARM64生態的感受
對於Linux+ARM64這個組合來說,已經越來越接近x86了,雖然還有不少的距離。起碼在ARM64+ubuntu之下,apt-get可安裝的東西非常多,arm64的docker映象也很多,github上越來越多的人提供arm 版本的pip安裝包,對於開發者來說,ARM生態從未這麼友好過。
當然差距也很明顯,如果在x86上,上面的事估計半天就搞完了,不用把各個變數的版本換來換去,也不會遇到一個問題找不到幾個帖子分析。
效能
ARM的CPU效能是個要考慮的問題,特別對於深度學習專案來說。簡單測試,同樣的程式碼和模型,在ARM伺服器上單次呼叫時間是x86 cpu的2~3倍。還行吧。
本次環境安裝的不足
第一次在ARM生態上安裝這麼多東西,沒有充分挖掘各個軟體在ARM上的編譯優化選項,目前做的環境版本應該不是最完美的狀態,相信還有很多可優化的空間。起碼ARM的neon優化、opencl加速等課題我還沒探索到,希望後面有機會摸索一下。