ubuntu+docker+nvidia/cudaによるYOLO環境の構築

YOLOを動かすための環境を構築した時のメモです。クラウドの選択肢がありましたが、物理環境での構築になりました。実際にパソコンを組んでから期間が空いたので思い出しながら書いています。

## ハードウェア構成

ハードウェア構成は以下の形で構成しました。GPUは組み立てときに設置せず、OSのインストール・GPUドライバーを入れてからハードウェアに組み込みを行いました。

**マザーボード:**	PRIME H270-PRO
**CPU:**	Core i7 7700K BOX
**GPU:**	ROG STRIX-GTX1070-O8G-GAMING
**メインメモリ:**	Corsair CMK8GX4M2A2666C16 [DDR4 PC4-21300 4GB 2枚組]
**ストレージ:**	ST4000DM004 [4TB SATA600 7200] 
**電源:**	RM650x CP-9020091-JP
**CPUクーラー**	H100i V2 CW-9060025-WW
**LANケーブル** 有線

## Ubuntu 16.04 LTS デスクトップ版のUSBメディアを作成

OSを上記に決定し[この記事](http://chee-s.net/ubuntu%E3%82%92usb%E3%83%A1%E3%83%A2%E3%83%AA%E3%81%8B%E3%82%89%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
)を参考にusbから起動するためのメディアを作成します。

## USBよりOSを起動

BIOSよりUSB起動に設定を行い、Ubuntuを起動・インストールを行います。ウィザードが表示されるため画面に沿ってインストールを行います。

## HDDドライブよりOSを起動

USBよりインストールが完了したら、USBを抜き、BIOSの設定よりHDDより起動を行います。

##  Nvidia-Driverのインストール

[ここ](http://www.nvidia.co.jp/Download/index.aspx?lang=jp)よりドライバーのバージョンを確認します。

<img width="716" alt="c4e4cd843e2c07f86361c8c50b7f8713.png" src="https://qiita-image-store.s3.amazonaws.com/0/35291/1144d790-2197-12f3-d6bf-744a8a396501.png">

<img width="731" alt="46b9de6a8f7f5a53799ec0a41cca7fec.png" src="https://qiita-image-store.s3.amazonaws.com/0/35291/ceb871e3-da55-065b-6b7e-c8027d63a318.png">

**「384.90」**でした。

### Driverのインストール

以下、コマンドでインストールを行います。

```bash
sudo add-apt-repository ppa:xorg-edgers/ppa -y
sudo apt-get update
sudo apt-get install -y nvidia-384
```

### GPUをマザーボードに取り付ける

パソコンの電源を落とし、GPUをマザーボードに設置します。設置が完了したら、起動して、以下コマンドでインストールできているか確認を行います。

```bash
nvidia-smi
```

## SSHの設定を行う

メインパソコンはMacBook Proのため、同一ネットワークから操作するためにSSHサーバを立てます。設定はごく簡単なものだけ行いました。

### SSHサーバのインストール

```bash
sudo apt-get install openssh-server
```

### SSHの設定

```bash
vi /etc/ssh/sshd_config
```

rootログインを禁止

```
PermitRootLogin no
```

再起動

```bash
sudo systemctl restart ssh 
```

### 固定IPの設定

SSHで繋ぐため固定IPを設定します。少しバージョンが古いですが[この記事](http://www.ubuntu-d.com/_install/network_settings.html)を参考に

**ipv4** 192.168.1.200
**ネットマスク** 255.255.255.0
**ゲートウェイ** 192.168.1.1
**DNSサーバ** 192.168.1.1

で設定。
再起動を行う。

## SSH接続確認

Macのターミナルを開き

```bash
ssh user@192.168.1.200
```
<img width="495" alt="ee1d13118cd958550dad3becb3e38fdc.png" src="https://qiita-image-store.s3.amazonaws.com/0/35291/00d2a7fb-2d9d-308a-55eb-0153ccfe3df8.png">

入れました。

## CUIモードでサーバを起動

ググったら以下でいいとのこと。

```bash
sudo systemctl set-default multi-user.target 
```

## Nvidia-Dockerの準備

ホスト環境(Ubuntu)を汚さないために、Nvidia-dockerをインストールします。ホスト側にDriverが必須ですがすでにインストールが完了しているため、Dockerをインストールします。
Dockerは[ここ](https://www.google.co.jp/search?q=ubuntu+docker+install&oq=ubuntu+docker+install+&aqs=chrome..69i57j69i60l3j0l2.2705j0j7&sourceid=chrome&ie=UTF-8)に沿って入れるだけです

手順に沿って進めて行きます。

### Dockerのインストール準備

パッケージの更新

```bash
sudo apt-get update
```

HTTPS経由でのaptを使用するために必要なものをインストール

```bash
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common
```

dockerの公式GPGキーを追加

```bash
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

安定板を入れれるように以下を実行

```bash
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
```

### Dockerのインストール

パッケージを更新

```bash
sudo apt-get update
```

インストール

```bash
sudo apt-get install docker-ce
```

### sudoなしでdockerの実行

```bash
sudo usermod -aG docker user
```

次回ログインした際に有効になるようです。


### Nvidia-Dockerのインストール

Nvidia-Dockerに必要なNvidia-driverとDockerのインストールが完了したので[公式](https://github.com/NVIDIA/nvidia-docker)のインストール手順に沿ってインストールを行います。

```bash
# Install nvidia-docker and nvidia-docker-plugin
wget -P /tmp https://github.com/NVIDIA/nvidia-docker/releases/download/v1.0.1/nvidia-docker_1.0.1-1_amd64.deb
sudo dpkg -i /tmp/nvidia-docker*.deb && rm /tmp/nvidia-docker*.deb

# Test nvidia-smi
nvidia-docker run --rm nvidia/cuda nvidia-smi
```

## YOLO環境の作成

以下コマンドでコンテナを起動

```bash
nvidia-docker run nvidia/cuda:8.0-runtime-ubuntu16.04 bash
```

### YOLOのインストール

こちらも[公式](https://pjreddie.com/darknet/yolo/)サイト通りに作業を進めます。

```bash
cd ~/
git clone https://github.com/pjreddie/darknet
cd darknet
vim Makefile
```

GPUを有効化

```
GPU=1
```

make 

```bash
make
```

### YOLOの動作確認

学習結果をダウンロードし

```bash
wget https://pjreddie.com/media/files/yolo.weights
```

推薦処理の実行

```bash
./darknet detect cfg/yolo.cfg yolo.weights data/dog.jpg
```

結果

```bash
layer     filters    size              input                output
    0 conv     32  3 x 3 / 1   416 x 416 x   3   ->   416 x 416 x  32
    1 max          2 x 2 / 2   416 x 416 x  32   ->   208 x 208 x  32
    .......
   29 conv    425  1 x 1 / 1    13 x  13 x1024   ->    13 x  13 x 425
   30 detection
Loading weights from yolo.weights...Done!
data/dog.jpg: Predicted in 0.016287 seconds.
car: 54%
bicycle: 51%
dog: 56%
```

YOLOを動かす環境が出来上がりました。