Take’s diary

Macとマイコンに関すること--ワクワクの製作日記

ゲーミングパソコンでDigits 実行環境の整備

 以前私のiMac にCaffeをインストールしています。スピードは練習用としてはそこそこだったのですが、すぐにGPUモリーが不足してしまい、サンプルプログラムさえ工夫をしなければ、まともに動かないことが発覚していました。

 ディープラーニング勉強中の身としては、Caffeを簡単に実行できるDigits環境がどうしても欲しくなります。ちょうどTX1ボードが、使っている最中に電源チップから煙が出てきて、電源部がオシャカになったので修理中。確認だけでも1.5か月かかるとか。腹を立ててもしょうがないので、以前Macbook用に買ったSSDも余ってるし、思い切って生命保険を整理見直しして、とりあえず資金を集めゲーミングパソコンを手に入れることにしました。

 個人レベルで中身も弄くり回せて現状現実的でスピードの早いもの。i7 6700K +GTX1080が入ったゲーミングパソコンを物色。結果こんなのを入手。f:id:TAKEsan:20160916225656p:plain「Lev-C017-LCi7-VNS」。驚異の戦闘力だそうです。BTOでCPUをi7 6700Kに変え、メモリを16Gに変更、さらにHDDを追加。3日くらいで到着しました。基本的に市販部品の組み合わせなので、自分で拡張可能です。

 昔買ったPower Macのミニタワーが大きすぎて印象が最悪だったので、BTOゲーミングパソコンとしては一番小さくてGTX1080が動作可能パソコンを選択。

 ケースが小さくなると当然GPUが1つしか刺せませんが、資金はこれ以上一切出せない状況になったので、これで良し。3年間使用したiMacが壊れたら次期ホストマシンにすることにしました。

 単精度浮動小数点演算指標がiMacのGTX675MX=1.152TFlopsに対してGTX1080は8.9TFlopsとのこと。単純に7倍くらいの差があることになります。実際どうなのかはとても興味深いところですが、少なくてもCaffe実行で今使っているiMacの3倍以上になれば、とても快適になるはず。GPUメモリも8G積んでいるので少し大きめの画像学習もなんとかなるでしょう。

 果たしてゲーミングパソコンで実用的なニューラルネットワークが実現可能かどうかが一番のネックですけど...........。

 Webを調べると、ゲーミングパソコンはニュラールネット構築にはあまり勧められないような記事が結構多いので不安ですが、所詮パソコンの内容は同じ。部品の耐久性だけの問題。と割り切ることにしました。

 届いたパソコンに、ほとんど使わなかったintel SSD 480を取り付けて見ました。

  f:id:TAKEsan:20160916225659j:plain    f:id:TAKEsan:20160916225658j:plain

 

f:id:TAKEsan:20160916225657p:plain

           矢印部分が手持ちSSD。取り付けはとっても簡単

 すでに電源コネクタなんかも配置されてて、SATAコネクタも添付されているので。増設はいたって簡単。標準のSSDWindows用に、さらにハードディスクは2分割してWindows10(D)デッキとUbuntu14.04に。そして増設SSDは別のUbuntu14.04だけとし、トリプル起動させるように設定しました(単純にOpencv3.1と2.4を使い分けたいだけです)。

 OSの選択方法が疑問でしたが、パソコン起動時にF11を押して起動ディスクを選択すればOK。スムーズに選択できてます。Ubuntuインストールは Macで慣れてしまっているのでとても簡単でした。

 まず本体の動作スピードですがIntel i7ってとても進歩してます。いつものpythonスピードテスト(この方Shibu's Diary: PyPyよりも5倍高速な最速のPython処理系

が作ったシンプルなプログラムですが、シングルコアのスピード確認方法として重宝してます)

import time

def fib(n):

   if n <= 1: return n

   else: return fib(n-2) + fib(n-1)

def entry_point(argv):

   a = time.time()

   result = fib(36)

   timespan = time.time() - a

   print result

   print timespan

   return 0

def target(*args):

   return entry_point, None

if __name__ == "__main__":

   import sys

  entry_point(sys.argv)

 

 私自身i7の進化は期待していなかったのですが、想定外でした。確かPi3≒40秒前後、iMac10.8 4.76秒に対して今回のマシンは3.2秒でした。何回実行しても3.2秒前後。(iMacは前にCaffeをインストールした時anaconda環境に変えたので2倍くらい遅かったみたいです。後からPython2.7.12を再インストールしたら4.76秒になりました。anaconda要注意!!2016.9.26 Pi3やTx1はもう一度試してみます。TX1についてはPi3と比較して、クロックスピード分程度の速度差と記憶してます)

 クロックスピードの違いを加味しても、ARM系のCPUとIntel i7では処理スピードに圧倒的な差があることがよくわかります。

 これであれば遅いことで有名なPythonもサクサクのはずです。また、3年前の3.4 GHz Intel Core i7と4.0GHz Intel Corei7 6700Kとではクロックスピード向上程度の進歩がありました。

 CPUスピードアップに伴いLinux環境も非常に良くなって、Pi3やTX1(Pi3より確実に早いが不安定)と比較してサクサク感は、水アメと水の差くらい違います。スピードが極端に上がることで、今まで「おもちゃ」にしか見えなかったフリープログラムのlinuxアプリがOSXWindowsと肩を並べてしまう事が新鮮な驚きでした。

 インストールしたubuntuは、14.04です。16.04もインストールしてみたのですが、OpenCVやCaffeのインストールがどうしてもうまくいかないので止めました。新しいものを使いたいのは山々ですが、いじくりまわすには安定している14.04に軍配が上がります。

最初にCuda8.0rc、Cudnn5.1、グラフィックスドライバをUbuntu環境にインストール。

素人がCaffeを使ってDeepLearningしてみた(導入編) - Qiita

を参考にさせていただきました。

 GTX1080の該当ドライバは、Cuda8.0rc、Cudnn5.1、Nvidia370.28グラフィックドライバです(Nvidia367.44でも可能)。

 準備はCuda8.0rc(本体とパッチプログラム2本) とCudnn5.1をNvideaからダウンロード。

 手順はグラフィックドライバインストール->Cuda->cudnn->グラフィックドライバ重ね書きです。Cudaをインストールすると確実に画面がおかしくなるのでRebootする前にグラフィックドライバを重ね書きしておきます。上記2本のDEPファイルおよびCudnnの解凍済みファイルと、下記赤部分を記入したシェルスクリプトファイルを作って1つのフォルダに入れておくと後々すごく便利。

sudo add-apt-repository ppa:graphics-drivers/ppa

sudo apt-get update

sudo apt-get install nvidia-370

sudo apt-get install mesa-common-dev

sudo apt-get install freeglut3-dev

 これを最初に実行することで、画面解像度やloginできなくなった時、後から簡単に元に戻すことが可能(設定->ソフトウェアとアップグレード->追加のドライバーを開けると確認できます。別の端末からssh接続してsudo apt-get install nvidia-367 --reinstallを実行するだけ

 そうそう。一番最初にsudo apt-get sshsshをインストールしてreboot。他のコンピューターからSSH接続してから、その端末で以下を操作する方法が最良だと思います。

sudo apt-get --purge remove nvidia-*

sudo dpkg -i cuda-repo-ubuntu1604-8-0-rc_8.0.27-1_amd64.deb

sudo apt-get update

sudo apt-get install cuda

sudo apt-get remove --purge -y cuda-repo-ubuntu1604-8-0-rc

sudo dpkg -i cuda-misc-headers-8-0_8.0.27.1-1_amd64.deb

sudo cp cuda/lib64/* /usr/local/cuda/lib64/

sudo cp cuda/include/* /usr/local/cuda/include/

sudo apt-get install nvidia-370 --reinstall

(9/29 追記:Cuda8.0が変更になって、パッチファイルがなくなり1本になりました。上記はubuntu16.04用のCudaを14.04にインストールしちゃってます。グラフィックドライバがおかしくなるのはこのあたりかもしれません。新しいCudaは画面正常!!)

これらが無事インストールできたら

sudo nano ~/.bachrc で最後に以下を追加書き込み。

export PATH=/usr/local/cuda-8.0/bin${PATH:+:${PATH}}

export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

export LD_LIBRARY_PATH=/usr/local/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

export CUDA_HOME=/usr/local/cuda

保存してから、

sudo reboot

 今回の経験上、Nividiaドライバ関連は、runファイルでインストールしない方が画面がおかしくなる等、パニックにならないで済む様です。

 最初はグラフィックスドライバーがインストールされていないので画面が荒いのですが、ここを我慢して上記の通り必要ファイルを全部入れておきます。リブートしてから、画面が詳細モードに変わっていればOK。

 注意しなければならないのは、これらドライバを入れてから  sudo apt-get upgradeすると「cuda8.0ドライバが必要無くなったので sudo apt-get autoremoveして下さい」と出力されことです。が、ほっときましょう。autoremoveを実行してしまうと、せっかくインストールしたCaffeやOpencvが動かなくなります。他のソフトをインストールして不要ファイルが更に溜まって来た時はしょうがないので、autoremoveしてNvidiaドライバ関連を入れ直します(結構めんどくさい。だからシェルスクリプト!!)。どうやらNvidiaの優秀なソフトエンジニアの皆様は最終的に個別OSの実行確認をしていない様です。

次にOPENCV

 OpenGL OPenCL CUDA qt5関連も全部入れてしまいました。これでOpencvのexampleは全て実行可能になります。

 ビルド時一番の注意点はCUDA_ARCH_BINの番号。散々エラーが出て悩みましたが、GTX1080は6.1を指定すれば簡単にインストールできることが分かりました。

 まず依存ファイルインストール。Caffe分も含めて多分これで全部です。python-opencvは故意に外してあります。

sudo apt-get install qt5-qmake

sudo apt-get install qt5-default

sudo apt-get purge python-pip

wget https://bootstrap.pypa.io/get-pip.py

sudo python get-pip.py

sudo add-apt-repository universe

sudo apt-get update

sudo apt-get install cmake git aptitude screen g++ libboost-all-dev \

libgflags-dev libgoogle-glog-dev protobuf-compiler libprotobuf-dev \

bc libblas-dev libatlas-dev libhdf5-dev libleveldb-dev liblmdb-dev \

libsnappy-dev libatlas-base-dev python-numpy libgflags-dev \

libgoogle-glog-dev python-skimage python-protobuf python-pandas 

 

 何でもかんでも入れちゃいます。そしてお好きなバージョンのOpencvをダウンロード。

 解凍してOpencvのフォルダに移動しますが、Opencv3.1.0を入れたい場合は、Cuda8.0を使うためのソース変更が必要です。これで簡単に3.1.0がインストールできます。(2.4.13は修正不要)

nano modules/cudalegacy/src/graphcuts.cpp で45行付近

#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER)

をこれに変える

#if !defined (HAVE_CUDA) || defined (CUDA_DISABLER) || (CUDART_VERSION >= 8000)

だけ。あとは通常どおり

mkdir build

cd build

cmake -DWITH_CUDA=ON -DCUDA_ARCH_BIN=“6.1” -DCUDA_ARCH_PTX="" -DENABLE_FAST_MATH=1 -DCUDA_FAST_MATH=1 -DWITH_CUBLAS=1 -D WITH_OPENCL=ON -D WITH_QT=ON -D WITH_OPENGL=ON -DBUILD_TESTS=OFF -DBUILD_PERF_TESTS=OFF -DBUILD_EXAMPLES=ON -D BUILD_opencv_python2=ON -D PYTHON_EXECUTABLE=$(which python) ..

sudo make -j8

sudo make install

 ワーニングが多少出ますが、すんなりコンパイルできます。ビルド中観察して見てるとOpencv2.4.13の方がNVCCを使う時間が多い様な...。感じ。コンパイルできたら、以下を直すことでopencvを使ったgpuやcコードで書かれたソースが

  g++ 該当ソース.cpp `pkg-config --cflags opencv` `pkg-config --libs opencv`

だけで簡単にコンパイルできます。

----------------------------------------------------

sudo nano /usr/local/lib/pkgconfig/opencv.pc

以下朱書き部を追加

# Package Information for pkg-config

prefix=/usr/local

exec_prefix=${prefix}

libdir=${exec_prefix}/lib

libdir3rd=${exec_prefix}/share/OpenCV/3rdparty/lib

includedir_old=${prefix}/include/opencv

includedir_new=${prefix}/include

Libs: -L${libdir} -L${libdir3rd} -lopencv_shape -lopencv_stitching -lopencv_objdetect -lopencv_superres -lopencv_videostab -lippicv -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs -lopencv_video -lopencv_photo -lopencv_ml -lopencv_imgproc -lopencv_flann -lopencv_core -lopencv_ts

----------------------------------------------------

 opencvのexample実行形式ファイルは、全部build/example に作られるんですね。知らんかった。

 それとpythonopencvライブラリは自動でインストールされたりされなかったりしますがOpencv/build 以下に作られたcv2.soを所定の場所にコピーすれば動きます。特にCaffeではPythonOpencvバージョンを合わせなければならないので注意。コンパイルが無事完了したら強制的に以下を実行して、ビルドされたcv2.soをコピーしてしまいます。

sudo cp ~/opencvフォルダ/build/lib/cv2.so /usr/local/lib/python2.7/dist-packages/

 ちなみにpythonビデオキャプチャープログラムは爆速でした(cv2.4.13=camera.py cv3.1.0=video.py)。

次にCaffeインストール。

これは簡単。Nvidia のCaffeソースをダウンロード。

https://github.com/NVIDIA/caffe

中のMakecaffe.config.example をMakecaffe.configと名前を変えるかコピーして以下の様に直します。

----------------------------------------------------

## Refer to http://caffe.berkeleyvision.org/installation.html

# Contributions simplifying and improving our build system are welcome!

# cuDNN acceleration switch (uncomment to build with cuDNN).

# cuDNN version 4 or higher is required.

USE_CUDNN := 1

# NCCL acceleration switch (uncomment to build with NCCL)

# See https://github.com/NVIDIA/nccl

# USE_NCCL := 1

# CPU-only switch (uncomment to build without GPU support).

# cuDNN version 4 or higher is required.

# CPU_ONLY := 1

# uncomment to disable IO dependencies and corresponding data layers

# USE_OPENCV := 0

# USE_LEVELDB := 0

# USE_LMDB := 0

# uncomment to allow MDB_NOLOCK when reading LMDB files (only if necessary)

#You should not set this flag if you will be reading LMDBs with any

# possibility of simultaneous read and write

# ALLOW_LMDB_NOLOCK := 1

# Uncomment if you're using OpenCV 3

# OPENCV_VERSION := 3

# To customize your choice of compiler, uncomment and set the following.

# N.B. the default for Linux is g++ and the default for OSX is clang++

# CUSTOM_CXX := g++

# CUDA directory contains bin/ and lib/ directories that we need.

CUDA_DIR := /usr/local/cuda

# On Ubuntu 14.04, if cuda tools are installed via

# "sudo apt-get install nvidia-cuda-toolkit" then use this instead:

# CUDA_DIR := /usr

# CUDA architecture setting: going with all of them.

# For CUDA < 6.0, comment the *_50 lines for compatibility.

CUDA_ARCH := -gencode arch=compute_20,code=sm_20 \

 -gencode arch=compute_20,code=sm_21 \

 -gencode arch=compute_30,code=sm_30 \

 -gencode arch=compute_35,code=sm_35 \

  -gencode arch=compute_50,code=sm_50 \

  -gencode arch=compute_50,code=compute_50

# BLAS choice:

# atlas for ATLAS (default)

# mkl for MKL

# open for OpenBlas

BLAS := atlas

# Custom (MKL/ATLAS/OpenBLAS) include and lib directories.

# Leave commented to accept the defaults for your choice of BLAS

# (which should work)!

# BLAS_INCLUDE := /path/to/your/blas

# BLAS_LIB := /path/to/your/blas

# Homebrew puts openblas in a directory that is not on the standard search path

# BLAS_INCLUDE := $(shell brew --prefix openblas)/include

# BLAS_LIB := $(shell brew --prefix openblas)/lib

# This is required only if you will compile the matlab interface.

# MATLAB directory should contain the mex binary in /bin.

# MATLAB_DIR := /usr/local

# MATLAB_DIR := /Applications/MATLAB_R2012b.app

# NOTE: this is required only if you will compile the python interface.

# We need to be able to find Python.h and numpy/arrayobject.h.

PYTHON_INCLUDE := /usr/include/python2.7 \

 /usr/lib/python2.7/dist-packages/numpy/core/include

# Anaconda Python distribution is quite popular. Include path:

# Verify anaconda location, sometimes it's in root.

# ANACONDA_HOME := $(HOME)/anaconda

# PYTHON_INCLUDE := $(ANACONDA_HOME)/include \ # $(ANACONDA_HOME)/include/python2.7 \

# $(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include \

# Uncomment to use Python 3 (default is Python 2)

# PYTHON_LIBRARIES := boost_python3 python3.5m

# PYTHON_INCLUDE := /usr/include/python3.5m \

 /usr/lib/python3.5/dist-packages/numpy/core/include

# We need to be able to find libpythonX.X.so or .dylib.

PYTHON_LIB := /usr/lib

# PYTHON_LIB := $(ANACONDA_HOME)/lib

# Homebrew installs numpy in a non standard path (keg only)

# PYTHON_INCLUDE += $(dir $(shell python -c 'import numpy.core; print(numpy.core.__file__)'))/include

# PYTHON_LIB += $(shell brew --prefix numpy)/lib

# Uncomment to support layers written in Python (will link against Python libs)

WITH_PYTHON_LAYER := 1

# Whatever else you find you need goes here.

INCLUDE_DIRS := $(PYTHON_INCLUDE) /usr/local/include /usr/local/include /usr/include/hdf5/serial

LIBRARY_DIRS := $(PYTHON_LIB) /usr/local/lib /usr/lib /usr/lib /usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/hdf5/serial

# If Homebrew is installed at a non standard location (for example your home directory) and you use it for general dependencies

# INCLUDE_DIRS += $(shell brew --prefix)/include

# LIBRARY_DIRS += $(shell brew --prefix)/lib

# Uncomment to use `pkg-config` to specify OpenCV library paths.

# (Usually not necessary -- OpenCV libraries are normally installed in one of the above $LIBRARY_DIRS.)

# USE_PKG_CONFIG := 1

 BUILD_DIR := build

DISTRIBUTE_DIR := distribute

# Uncomment for debugging. Does not work on OSX due to https://github.com/BVLC/caffe/issues/171

# DEBUG := 1

# The ID of the GPU that 'make runtest' will use to run unit tests.

TEST_GPUID := 0

# enable pretty build (comment to see full commands)

Q ?= @

# shared object suffix name to differentiate branches

LIBRARY_NAME_SUFFIX := -nv

----------------------------------------------------

Opencv3.1.0を使う場合は赤い部分のコメント#を外すだけです。

あとは

make all -j8

make test

make runtest

を実行。RuntestでエラーがなければOK。

Pycaffeのインストールは以前の記事参照 

takesan.hatenablog.com

次にDigits

  Digitsの説明にUbuntuでは apt-get install digits だけでインストール可能と書いてあるのですが、これをインストールするとCudaが7.5が勝手にインストールされて、GTX1080を取り付けたパソコンでは、OpencvもDigitさえもまともに動かなくなります。もしインストールしてしまったら慌てずにremoveして再度上記のCudaドライバー郡を再インストールします。

 そんなわけでGTX1080を使用する場合、Digitsはソースからインストールする必要があります。DigitsではTorch7も使えるのでついでにインストールしてみました。これも簡単。

Digit自体のインストール

https://github.com/NVIDIA/DIGITS/blob/master/docs/BuildDigits.md

Torch7のインストールと設定

https://github.com/NVIDIA/DIGITS/blob/master/docs/BuildTorch.md

最後に

./digits-devserver --config

でDigitsにCaffeとTorchのパスを指定します。

     caffeは~/nvcaffe/ 等

     Torch はパスではなくPを入力すると良いみたい

更に

Digitsフォルダにある実行ファイルでテストをしてエラーがなければ完了。

./digits-test

が、最初はPythoonのライブラリがないと叱られます。表示された該当ファイルを1個 pip でインストールし、再度 ./digits-test

で、少し時間がかかりますが、OK。

Disitsの実行は、./ digits-devserverです。

 Digitsをインストールしたコンピューターがサーバーになっちゃいます。Lanケーブルをつないで、涼しいところにコンピュータを置いておけば、他のコンピュータからDISITSを実行できます。

 Macでは、SSH、サファリ、ForkLiftが実行できれば、CaffeやDISITSが遠隔操作できちゃいます。本来はこんな使い方を想定してるんでしょうね(GPUを2枚以上つけたコンピューターで)Disitの使い勝手は、素晴らしいものでした。

いよいよCaffeの実行スピード。

ここまでが長かった。

 僕のようなCaffe素人がGPUスピード比較する手段は、やっぱりCaffe標準のMnistがどれだけ早いのかですが、

 結果はなんと13秒Macの4.6倍でした。ヒェー!!。終了まであっという間。ちなみにTX1の16倍!!です。

        

                 早っ!!

次にDigitsでMnist。

DIGITS/GettingStarted.md at master · NVIDIA/DIGITS · GitHub

 これはepocを標準の30から12に変えます。こうするとCaffe標準と同等になるとのこと。認識結果も99%なので良しとしますが、この時のスピードは15秒。Web画面なので少しオーバーヘッドがあるようです。それでも早い。

        

 このソフトの良いところは学習結果を試せること。適当な手書きファイルを指定すると学習結果が試せます。学習中でもですよ!!

さらにobject-ditection 学習テスト。

DIGITS/examples/object-detection at master · NVIDIA/DIGITS · GitHub

を参考に設定していきます。これは1248x384のカラー画像6373枚の学習です。

 画像変換に4分弱程度。 実際の学習は、1Epoch 30分強くらいで 30エポック16時間必要。24時間回しっぱなしでは50エポックくらいの学習が可能です。このくらいだと個人レベルでは十分なスピードです。私のiMacGPUフル稼働で実現できるとすれば64時間つまり3日必要!!。CPUオンリーで実行すれば極端な話、まさに天文学的な学習時間になります。GTX1080はやっぱり早い。

 問題はGPU温度。今回のGPUカードはNvidia標準の冷却システムですが、ずっと82度のままで、実行スピードを調節している模様です(DigitsでCPU,GPUの稼働状況がチェックできる)。CPU温度は水冷だけに問題外でした。一応8時間程度の試験をしてみましたが、まったく異常ありませんでした。

 GPUボードについては、さらに冷却能力を上げているものが市販されているので、そちらをチョイスするのがベターかもしれません(今回選択したBTOパソコンでは選択できませんが)。ただ、今までのNvidia新製品発表経緯では1年ごとに処理能力が2倍くらいになってますので、GTX1080の寿命が来る前に差し替えすることになるでしょう。 

 Nvidiaではアーキテクチャのシナリオができていて、小出しに新製品を出しているのでは?って感じがします。

 TITAN X Pscalが発売されたようですが、能力は1080の1.2倍程度。消費電力がUP。メモリーだけは魅力的な12Gです。8GのGTX1080でも今回テストしてみたカラー画像学習をメモリオーバーなく処理できるので、価格差を考慮すると私にとってTITAN X Pascalは将来手に入れてもあまり意味がありません。

 消費電力の比較的少ないGTX1080を積んだパソコンでも学習中は300W超くらいになります。経済的に見て個人レベルでの実行では、パソコンとエアコンの電気代を考えるほうが先です。

 こんな結果になったってことは、ゲーミングパソコンでもなんとかなると思いません?。故障しても自分でパソコンを修理できるのが最大の強みです。と、自己満足して今日の記事はおしまい。

眠いんでおかしなところは後で書き直し。まずは近況まで。