ディープラーニング用に自作PCを作る

自作PCの備忘録を残します．

最終的に，Ubuntuをインストールしてdockerでディープラーニング環境を作るところまでを記します．

# 目次

1. 自作PCの作り方を調べる
2. PCを組み立てる
3. 環境構築

# 1. 自作PCの作り方を調べる

- 以下のサイト様を参考にさせていただきました．
    - [自作PC予算別まとめ](https://artjuku.com/pc-make/)
    - [ディープラーニング用PCの作り方](https://souzouno-yakata.com/2019/02/17/38080/)

用途に応じてスペックを決めるのが良いようです．

- 前処理を頻繁に実行するので，CPUのコア数は多めに
- GPUを増設したくなったときのために，大きめの電源とケースにしておく

検討した結果，次のような構成にしました．

### 作ったもの

**CPU**　[Core i7-9700K](https://www.amazon.co.jp/%E3%82%A4%E3%83%B3%E3%83%86%E3%83%AB-Corei7-9700K-INTEL300%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-Chipset%E3%83%9E%E3%82%B6%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E5%AF%BE%E5%BF%9C-BX80684I79700K%E3%80%90BOX%E3%80%91/dp/B07HHN6KBZ)　45,000円
**GPU**　[GeForce RTX2080Ti 11GB GamingPro OC](https://www.dospara.co.jp/5shopping/detail_parts.php?bg=1&ic=455951&lf=0)　89,000円（中古）
**マザーボード**　[ASUS PRIME Z390-A](https://www.amazon.co.jp/Intel-LGA1151-%E3%83%9E%E3%82%B6%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89-PRIME-Z390/dp/B07HCY7K9L)　22,000円
**メモリ**　[Kingston FURY RGB（DDR4 2666MHz 16GBx2）](https://www.amazon.co.jp/gp/product/B07WHF2RQ2/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)　20,000円
**ケース**　[O11 DYNAMIC WHITE](https://www.amazon.co.jp/DYNAMIC%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-ATX%E5%AF%BE%E5%BF%9CPC%E3%82%B1%E3%83%BC%E3%82%B9-%E5%BC%B7%E5%8C%96%E3%82%AC%E3%83%A9%E3%82%B9%E3%83%91%E3%83%8D%E3%83%AB-DYNAMIC-%E6%97%A5%E6%9C%AC%E6%AD%A3%E8%A6%8F%E4%BB%A3%E7%90%86%E5%BA%97%E5%93%81/dp/B07C88K4KP/ref=sr_1_8?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=126X9EAEQS38A&keywords=pc%E3%82%B1%E3%83%BC%E3%82%B9%2Be-atx&qid=1572082964&s=computers&sprefix=PC%E3%82%B1%E3%83%BC%E3%82%B9%2Be%2Ccomputers%2C234&sr=1-8&th=1)　14,000円
**電源**　[Corsair HX1000i](https://www.amazon.co.jp/Corsair-HX1000i-80PLUS-PLATINUM-CP-9020074-JP/dp/B00NV3NN1G/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=Corsair+HX1000i&linkCode=sl2&linkId=7e74aeede033623f3854a6a093ea43d9&qid=1572077086&sr=8-1)　25,000円
**SSD**　[Intel SSD 660P](https://www.amazon.co.jp/dp/B07GCL6BR4/ref=as_li_ss_tl?ie=UTF8&linkCode=ll1&tag=jisakuhibi0b-22&linkId=fd963ff0cd812b7122e38e558af646c5&language=ja_JP&th=1)　13,000円
**HDD**　[SEAGATE ST6000DM003](https://kakaku.com/item/K0001026181/)　11,000円
**簡易水冷ファン**　[Novonest CC240RGB]
(https://www.amazon.co.jp/gp/product/B07JFVV9VB/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)　7,000円
**無線LANカード**　[Ziyituod ZYT-WIE9260](https://www.amazon.co.jp/gp/product/B07T42NH34/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)　4,000円
**ケースファン**　[Ubanner RB001](https://www.amazon.co.jp/gp/product/B07GFBR8M5/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1)　4,500円

**合計**　254,500円

※最後のケースファンはLEDで楽しむためのものなので，特に必要ありません．

下調べをあまりせず「えいや！」で買ってしまいましたが，後述のように**もっと調べるべきでした**．

### その他買ったもの

**RGBファンのコントローラ**　[Fractal Design Adjust R1](https://www.amazon.co.jp/gp/product/B07PFMY9KV/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1)　3,000円

これは，アドレサブルRGBという規格に対応していないマザーボードを買ったにも関わらず，アドレサブルRGBの簡易水冷ファンを買ったせいで買う羽目になったものです．（同じ失敗をしないようご注意を…）

**熱伝導グリス**　[ThermalGrizzly](https://www.amazon.co.jp/gp/product/B011F7W3LU/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&psc=1)　750円

### 検討したこと・反省点

- コア数だけ見ると[Xeon](https://kakaku.com/pc/cpu/itemlist.aspx?pdf_ma=39&pdf_se=5)や[Threadripper](https://kakaku.com/pc/cpu_amd/itemlist.aspx?pdf_Spec101=73)もあるようですが，とても手が出ませんでした．

- [Intel 9900k](https://www.amazon.co.jp/INTEL-%E3%82%A4%E3%83%B3%E3%83%86%E3%83%AB-Corei9-9900K-INTEL300%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BAChipset%E3%83%9E%E3%82%B6%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E5%AF%BE%E5%BF%9C-BX80684I99900K%E3%80%90BOX%E3%80%91/dp/B005404P9I)や[Ryzen 3900K](https://www.amazon.co.jp/AMD-Ryzen-3900X-105W%E3%80%90%E5%9B%BD%E5%86%85%E6%AD%A3%E8%A6%8F%E4%BB%A3%E7%90%86%E5%BA%97%E5%93%81%E3%80%91-100-100000023BOX/dp/B07SXMZLP9/ref=as_li_ss_tl?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=3900x&qid=1562932114&s=gateway&sr=8-1&linkCode=sl1&tag=artjuku-22&linkId=302a03c426c499b28724f235b7624370&language=ja_JP)も検討しましたが，価格や冷却を考慮する必要がありそうでしたので，楽そうなCore i7にしました．

- [**GPUを中古で買うのは推奨されていない**](https://g-pc.info/archives/1452/)ので，新品を買うべきでした…．多少のリスクは受け入れつつ，人柱になったつもりで使い続けてみます．

- GPUは上を見れば[Titan RTX](https://www.amazon.co.jp/nVidia-900-1G150-2500-000-Titan-Graphics-Card/dp/B07L8YGDL5), [Tesla V100](https://kakaku.com/item/K0001083015/)などありますが，高額だし私には使い切れる気がしません．

- 正直，ディープラーニングを回すだけなら**もっと安く作れたはず**です．
    - 簡易水冷をやめて[空冷](https://www.amazon.co.jp/%E3%82%B5%E3%82%A4%E3%82%BA-%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%ABCPU%E3%82%AF%E3%83%BC%E3%83%A9%E3%83%BC-%E8%99%8E%E5%BE%B9-Mark-II/dp/B072PWL5YF)にする
    - メモリを[普通の（光らない）もの](https://www.amazon.co.jp/2666Mhz-PC4-21300-8GBx2%E6%9E%9A%EF%BC%8816GBkit%EF%BC%89%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%97%E7%94%A8-%E6%97%A5%E6%9C%AC%E5%9B%BD%E5%86%85%E7%84%A1%E6%9C%9F%E9%99%90%E4%BF%9D%E8%A8%BC-%E6%B0%B8%E4%B9%85%E4%BF%9D%E8%A8%BC%EF%BC%89%E6%AD%A3%E8%A6%8F%E5%93%81/dp/B07HK1HWJK/ref=as_li_ss_tl?_encoding=UTF8&refRID=KVWRMB527B7G73Z9PMSZ&linkCode=sl1&tag=artjuku-22&linkId=4a3b17eeb2d258052d4b015fc5764f39&language=ja_JP&th=1)にする
    - CPU, GPUをコスパのよいものにする
    - GPU1枚を前提にして，電源やケースを小さめのものにする
    - SSDの容量を減らす

等々，色々無駄が省けそうです．

# 2. PCを組み立てる

マザーボードの説明書を熟読しつつ，[こちら](https://www.zoa.co.jp/pickup/detail/jisakupctsukurikata/)を参考に組み立てました．

1. CPUをマザボに取り付け
2. CPUクーラー（今回は簡易水冷）をマザボに取り付け
3. メモリの取り付け
4. SSDの取り付け
5. 電源を繋いで動作確認
6. ケースにマザボを取り付け
7. ケースに水冷ファンを取り付け
8. 電源の取り付け
9. HDDの取り付け
10. GPUの取り付け
11. 無線LANカードの取り付け
12. ケースファンの取り付け
13. 配線
14. 電源を入れて動作確認（CPU温度やファン回転数が正常値に収まることを確認）
15. **綺麗なLEDに満足してビール飲んで寝る**

<img width="400" alt="pc_image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193401/a3f2c333-3e7b-18cc-6e7e-870f9047561b.jpeg">

# 3. 環境構築

### 3.1 Ubuntu 18.04.4 LTSをインストール

- [こちら](https://linuxfan.info/ubuntu-18-04-install-guide)を参考にインストールしました．

- 最初，モニタをグラボの端子に接続させてUbuntuを起動させると[画面がフリーズしてしまいました](https://qiita.com/k_ikasumipowder/items/5e88ec45f958c35e05ed#deep-learning-%E7%92%B0%E5%A2%83%E3%81%AE%E6%A7%8B%E7%AF%89)．

- なので，最初はマザボの端子に繋いでおくか，[nouveauを無効化](https://qiita.com/k_ikasumipowder/items/5e88ec45f958c35e05ed#nouveau%E3%81%AE%E7%84%A1%E5%8A%B9%E5%8C%96)させておきます．

### 3.2 グラフィックドライバのインストール

Ubuntuを日本語でインストールした場合は，ドキュメントなどの日本語を英語に直しておきます．

```bash:terminal
LANG=C xdg-user-dirs-gtk-update
```

パッケージを更新

```bash:terminal
sudo apt-get update
sudo apt-get upgrade
```

[NVIDIAドライバダウンロード](https://www.nvidia.co.jp/Download/index.aspx?lang=jp)から対応するドライバを選択してダウンロード

```bash:ダウンロードしたファイルの実行に必要なものをインストール
sudo apt-get install build-essential
```

ドライバのインストール中にグラフィックドライバが落ちることがあるので，念のため`Ctrl+Alt+F1`でCUIに切り替えます．(`Ctrl+Alt+F2`などで切り替わる場合もあるようです．それでもダメならファンクションキーを3~12に変えてみる)
この時, **--no-opengl-files**, **--no-libglx-indirect**, **--dkms**を指定します
`--noうんたら`の指定が足りないとログインループにハマったり，`--dkms`が足りないと再起動するたびにnvidia driverが無効になったりします．

```bash:ダウンロードしたファイルを実行
chmod +x ./NVIDIA-Linux-x86_64-440.31.run
sudo ./NVIDIA-Linux-x86_64-440.31.run --no-opengl-files --no-libglx-indirect --dkms
```

```bash:再起動
reboot
```

（モニタをマザボに接続している場合は，グラボの端子に繋ぎ変える．）

```bash:ドライバの動作確認
nvidia-smi
```

GPUの情報が表示されれば完了

### 3.3 dockerインストール

[公式](https://docs.docker.com/install/linux/docker-ce/ubuntu/)にしたがってインストール．2019年11月4日時点では以下のコマンドを実行しました．

```bash
sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
```

[sudoなしでdockerコマンドを実行する設定](https://qiita.com/DQNEO/items/da5df074c48b012152ee)もしておきます．

```bash
sudo groupadd docker
sudo gpasswd -a $USER docker
sudo service docker restart
reboot
```

### 3.4 nvidia-dockerインストール

[NVIDIA Container Toolkit](https://github.com/NVIDIA/nvidia-docker)にしたがってインストール．

```bash
distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list

sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit
sudo systemctl restart docker
```

以下のコマンドでGPUの情報が見えたら成功です．

```bash
docker run --gpus all --rm nvidia/cuda nvidia-smi
```


### 3.5 dockerイメージで動作確認

[tensorflow公式のdocker image](https://hub.docker.com/r/tensorflow/tensorflow/tags?page=1&name=1.14.0)を動かしてみます．

```bash
docker pull tensorflow/tensorflow:1.14.0-gpu-py3-jupyter
docker run --gpus all -it --rm -v $(realpath ~/notebooks):/tf/notebooks -p 8888:8888 tensorflow/tensorflow:1.14.0-gpu-py3-jupyter
```

jupyterが起動したらブラウザで`localhost:8888`に接続

tensorflowからGPUが見えているか確認します

```python
from tensorflow.python.client import device_lib
print(device_lib.list_local_devices()) 
```

以下のようにGPUが見えていれば成功です．

```bash:output
[name: "/device:CPU:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 14740279898702566726
, name: "/device:XLA_GPU:0"
device_type: "XLA_GPU"
memory_limit: 17179869184
locality {
}
incarnation: 10721268506091676345
physical_device_desc: "device: XLA_GPU device"
, name: "/device:XLA_CPU:0"
device_type: "XLA_CPU"
memory_limit: 17179869184
locality {
}
incarnation: 16980550380766421160
physical_device_desc: "device: XLA_CPU device"
, name: "/device:GPU:0"
device_type: "GPU"
memory_limit: 10512030106
locality {
  bus_id: 1
  links {
  }
}
incarnation: 10531017116676756003
physical_device_desc: "device: 0, name: GeForce RTX 2080 Ti, pci bus id: 0000:01:00.0, compute capability: 7.5"
]
```

### 3.6 MNIST

いよいよディープが回せます！

簡単なCNNでMNISTを回してみます．

```python
!pip install keras

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, MaxPooling2D, Conv2D
from keras.callbacks import TensorBoard

(X_train,y_train), (X_test, y_test) = mnist.load_data()

X_train = X_train.reshape(60000,28,28,1).astype('float32')
X_test = X_test.reshape(10000,28,28,1).astype('float32')

X_train /= 255
X_test /= 255

n_classes = 10
y_train = keras.utils.to_categorical(y_train, n_classes)
y_test = keras.utils.to_categorical(y_test, n_classes)

model = Sequential()
model.add(Conv2D(32, kernel_size=(3,3), activation='relu', input_shape=(28,28,1)) )
model.add(Conv2D(64, kernel_size=(3,3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.5))
model.add(Flatten())          
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

import time
start = time.time()

model.fit(X_train, y_train, batch_size=128, epochs=15, verbose=1,
          validation_data=(X_test,y_test))

elapsed_time = time.time() - start
print ("elapsed_time:{0}".format(elapsed_time) + "[sec]")
```

```python:output
elapsed_time:65.47733306884766[sec]
```

Google ColaboratoryのGPUはランダムに割り当てられるのですが，P100を引いたときは62秒でした．

20万以上使ったPCが，無料のColaboratoryに負けてしまうのは悲しい気もしますが，時間制限もありませんし，レスポンスも早く，好きに拡張できるのは大きなメリットになりそうです．