Ubuntu 18.04(Corei7-7700,GTX1050)へのCUDA、TensorFlowインストール方法

自作のPCにUbuntu18.04とTensorFlowをインストールした内容を紹介します。
#■PCの構成とセットアップ
構成は以下の通りです。
- MB：Asrock Fatal1ty Z270 Gaming-ITX/ac
　　グラフィック出力：HDMI,DisplayPort(２台の4Kのモニターに対応）
　　Tunderbolt 3 ( (USB Type-C)、Ultra M.2(PCIe Gen3 x 4)
- CPU：Intel Corei7-7700、メモリ：DDR4 8GBx2
- SSD：M.2 2280 512GB HDD：STA3 2TB
- VGA: GTX1050Ti 4GB(CUDA用GPU）
##　BIOS更新・設定
モニターはMB（マザーボード）のグラフィック出力に接続します。
PC起動後、表示がなければGPUのVGAカードの端子にディスプレイを接続しBios設定画面で、PriorityVideoに設定します。PC再起動時にモニターをマザーボードに接続し直します。
　BIOSはASROCKのホームページから最新安定版のBIOSをダウンロードし、BIOS更新しました。
#■Ubuntu18.04のインストール
Ubuntu18.04のデスクトップ版ISOファイルをダウンロードして、ImageWriterでUSBメモリに書き込みます。
　このUSBメモリを組み立てたPCに挿入して、Ubuntu18.04のインストールを始めます。
　HDDは外しておきます。PC起動後の画面で、「Try Ubuntu without installing」を選択し、SSDをインストール対象して設定します。ディスクのパーティションの設定で１２８MBのUFIパーティション、その他をext4のファイルタイプ、[/」をマウントに設定しました。
　その後、デスクトップにあるubuntuインストールコマンドを起動します。起動後は、画面指示に従いインストールします。
　インストールが完了してPCが再起動後、sudo apt update, sudo apt upgradeでOSを最新にしておきます。
#■CUDA10のインストール
aptのリポジトリにcudaドライバを追加し、インストールします。
<Pre>
	$ sudo apt-key adv --fetch-keys http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub
	$ wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-repo-ubuntu1804_10.0.130-1_amd64.deb
	$ sudo dpkg -i cuda-repo-ubuntu1804_10.0.130-1_amd64.deb

        $ sudo apt update
        $ sudo apt install cuda cuda-drivers
</Pre>
以下の内容を.bashrcに追加します。
<Pre>
	export PATH="/usr/local/cuda/bin:$PATH"
	export LD_LIBRARY_PATH="/usr/local/cuda/lib64:$LD_LIBRARY_PATH"
	$ source ~/.bashrc　#設定を反映させます。
</Pre>
PCを再起動します。起動が始まらない場合、リセットボタンを押します。

PCが起動後、GPUの動作を確認します。
	```$ nvidia-smi```
Driver versionの内容が表示されれば正常にインストールされています。
Memory-Usageには使用されているメモリ量が表示されます。

#■グラフィック表示をインテルGPUに切り替え
PC内部のビデオデータの流れは表示用の画像はGPUからマザーボードのグラフィック出力されているようです。そのため、表示にはintel graphics機能を使うよう/etc/X11/xorg.confを次の内容で作成します。
この内容は[Configuring iGPU for xserver and nvidia GPU for CUDA work (kubuntu 18.04, cuda-9.2)](https://askubuntu.com/questions/1061551/configuring-igpu-for-xserver-and-nvidia-gpu-for-cuda-work-kubuntu-18-04-cuda-9)を参照しました。
<Pre>
	Section    "Device"
	   	   Identifier      "intel"
	   	   Driver          "intel"
		   BusId           "PCI:0:2:0"
	EndSection
	Section "Screen"
	   	   Identifier      "intel"
	   	   Device          "intel"
	EndSection
</Pre>
次に、nvidia-settingsを起動してで次の設定をします。
　　PRIME PROFILEで、「intel」を選択します。
　　設定終了後、PCを再起動します。
５分程度、待って、起動が始まらない場合、リセットを押します。
PCが起動後、nvidiaの状態を次のコマンドで確認します。		
	```$ nvidia-smi```
　　Memory-Usageのメモリ使用が０となっています。nvidiaのドライバーが組み込まれていません。
GUIのnvidia-settingsは、今後、起動しなくなるためこのコマンドでGPUの状態を把握するようにします。
#■pyenvとvirtualenvのインストール
　TensorFlowの各バージョンに対応するため、pyenvとvirtualenvを使用しています。
##　pyenvのインストール
<Pre>
	$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
	　ダウンロード後、.bashrcへ以下の内容を追加します。		
	 echo 'export PYENV_ROOT="$HOME/.pyenv"'	
	 echo 'export PATH="$PYENV_ROOT/bin:$PATH"'	
	 echo 'eval "$(pyenv init -)"'		
</Pre>
##　virtualenvインストール
<Pre>	
	$ sudo pip install virtualenv
	$ sudo pip install virtualenvwrapper	
		
	.bashrcに以下の内容を追加します。
	export WORKON_HOME=$HOME/.virtualenvs	
	export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
	次のコマンドを実行します。
	$ source .bashrc	
	$ source /usr/local/bin/virtualenvwrapper.sh
</Pre>		
##　仮想環境の作成
<Pre>	
	$ mkvirtualenv edward1
	$ mkvirtualenv tf_1.12GPU	
</Pre>		
##　仮想環境の切り替え
　実際の切替は以下のようにします。
<Pre>
　終了時
	$ deactivate
　仮想環境切り替え時
	$ workon  #仮想環境のリスト表示します。
	$ workon tf_1.12GPU #仮想環境tf_1.12GPUに切り替えます
</Pre>

#■TensorFlowのソースインストールとコンパイル
TensorFlowのソースをダウンロード後、ソースのバージョンを指定します。
<Pre>
	$ git clone https://github.com/tensorflow/tensorflow.git
	$ cd tensorflow	
	# git checkout r1.12 #	git checkout branch_name ?# r1.9, r1.10, etc.　ソースのバージョンを変更
</Pre>
##　NCCL 2.3.5のインストール
nvidiaの開発者ホームページのNCCLより、ログインしてダウンロードします。
<Pre>
	sudo dpkg -i nccl-repo-ubuntu1804-2.3.5-ga-cuda10.0_1-1_amd64.deb
	sudo apt update
	sudo apt install libnccl2 libnccl-dev
</Pre>

##　追加ライブラリィのインストール
　ソースコンパイル時にライブラリ依存性があるlibcuptiをインストールします。	
<Pre>
	$ sudo apt-get install libcupti-dev
	$ echo 'export LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
	$ source .bashrc
</Pre>
		
##　Tensorflowに依存性があるpipパッケージをインストール
　pipを用いて追加インストールします。
<Pre>
	$ sudo apt-get install python3-dev python3-pip
	$ sudo pip3 install -U pip #pip自身の更新
	$ sudo pip3 install numpy wheel mock keras_applications keras_preprocessing
	　
	　＜補足＞
	　インストールしたラパッケージの更新をステップ確認するため次のパッケージをインストールします。
	$ sudo pip3 install pip-review #
	　pipでパッケージの更新時に、OSがインストールしたライブラリと競合して更新ができない場合、次のコマンドを実行します。
	$ sudo pip3 install -I ..
	上記コマンドを実行してもエラーで更新できない場合、libやdevを含むパッケージを探しインストールします。
</Pre>

##　cuDNN のインストール			
　aptのリポジトリにcudaドライバを追加し、インストールします。
<Pre>
	$ echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 /" | sudo tee /etc/apt/sources.list.d/nvidia-ml.list		
	$ sudo apt update		
	$ sudo apt install libcudnn7-dev		
</Pre>
　　　　　CuDNNが動作しているか、テスト用のサンプルコードで確認します。
　　　　　開発者のページからCode Smples and User Guide for Ubuntu 18.04をダウンロードします。
<Pre>
			$ cp -r /usr/src/cudnn_samples_v7/ $HOME
			$ cd $HOME/cudnn_samples_v7/mnistCUDNN
			$ make clean && make
			$ ./mnistCUDNN
			"Test passed"という文字が出力されていれば、正常にインストールされたことになります。
</Pre>

##　bazelのインストール
　これはmakeに相当するものです。
<Pre>
	$ sudo apt-get install openjdk-8-jdk
	$ echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
	$ curl https://bazel.build/bazel-release.pub.gpg | sudo apt-key add -
	$ sudo apt-get update && sudo apt-get install bazel
</Pre>


##　tensorflowのビルド
<Pre>
	$ cd tensorflow	
	$ ./configure	
	コマンドラインの質問に答えます。選択の中で大文字がデフォルトです。ディフォルトから変更した項目は以下です。
　　　　Please specify the location of python. [Default is /usr/bin/python]: /usr/bin/python3
　　　　Do you wish to build TensorFlow with CUDA support? [y/N]: Y
　　　　Please specify the location where CUDA 10.0 toolkit is installed. Refer to README.md for more details. [Default is /usr/local/cuda]: /usr/local/cuda
　　　　Please specify the cuDNN version you want to use. [Leave empty to default to cuDNN 7.0]: 7.3.1
　　　　Please specify the location where cuDNN 7 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:/usr/local/cuda/lib64 
　　　　Please specify the NCCL version you want to use. [Leave empty to default to NCCL 1.3]: 2.３
　　　　Please specify the location where NCCL 2 library is installed. Refer to README.md for more details. [Default is /usr/local/cuda]:/usr/local/cuda/targets/x86_64-linux
</Pre>
　実際のビルドは以下のコマンドを実行します。
<Pre>
	$ bazel build --config=opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
</Pre>
　ビルドの時間は１時間１５分程度かかりました。この時間はスレッド数が多いCPUでは時間が短くなります。
	tensorflowインストール用のパッケージを作成します。
<Pre>
	$ bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
</Pre>
	仮想環境tf_1.12GPUに切り替えます。
<Pre>
	$ workon tf_1.12GPU 
</Pre>
　	切り替えた仮想環境内ではnumpyなど必要なパッケージはpipでインストールします。
　	この時、インストールは仮想環境のみ使えるようsudo pipではなくpip　パッケージ名とします。
	次のコマンドで、先ほど作成したtensorflowパッケージをインストールします。
<Pre>
	$ pip install --upgrade /tmp/tensorflow_pkg/tensorflow-*.whl
</Pre>
##　tensorflowの動作テスト
　python3を起動させ、以下のプログラムで、”Hello, TensorFlow!”が出力されれば正常です。
<Pre>
	$ python3
	>>> import tensorflow as tf
	>>> hello = tf.constant('Hello, TensorFlow!')
	>>> sess = tf.Session()
	>>> print(sess.run(hello))
</Pre>
##　Tensorflowベンチマーク
　tensorflowのチュートリアルにあるmnist_deep.pyを次のように実行させます。

<Pre>
　	$time python3 mnist_deep.py</Pre>

この実行の経過時間は１３４秒でした。これはAWSのｇ３インスタンス程度、ｐ３インスタンスの２倍の時間でした。
GPUをGTX1080Tiにすれば実行時間は1/2～1/3になると思われます。