ほとラボ

It works!

機械学習用の GPU マシンを組んだ

4ヶ月前にこんな Qiita を書いた。

qiita.com

しかし自宅に GPU マシンを組んだとしても四六時中計算し続けるわけでもないからもったいないし、ここはクラウドサービスを活用して安く済ませたい。

とは言ったものの普通に学習回すと月1,2万は飛んでいくし、これもう普通に GPU マシン組んだほうが良いのでは、となったのでやっていくことにした。

結論からいうとベアボーンキットを買ってメモリと SSD を挿しただけなので「組んだ」というのはちょっと微妙なんだけども、自作 PC とか全然慣れてないなりにあれこれ悩んだログとして書いておく。

GPU はどれがいいか

Tesla V100 欲しい!

GPU がメインなのでまずは GPU から選ぶ。

候補としてはこのへん。

GPU 種類 価格帯 CUDA コア数 メモリ メモリバス SLI
GTX 1080 Ti 10 万くらい 3584 GDDR5X 11GB 352bit
GTX 1080 8 万くらい 2560 GDDR5X 8GB 256bit
GTX 1070 5 万くらい 1920 GDDR5 8GB 256bit
GTX 1060 4 万くらい 1280 GDDR5 6GB 192bit

GTX 1080 Ti は高いけど手が届かない価格帯ではない。

でも機械学習する場合は計算リソースよりもメモリのほうがすぐキツキツになるので、1080 Ti 買うよりは 1070 を二枚挿して SLI 構成1にしたほうがメモリを増やせて良い。 だたし二枚挿すと消費電力がかなりいくので、あらかじめ容量大きめの電源を買っておく必要がある・・・。

そういう意味だと 1060 は SLI 対応していないので選択肢からは外れる。

まぁ 1070 が無難っぽい。 一枚買っておいて足りなければもう一枚追加すればいい。

マザーボードとかケースとか

休日に秋葉原行ってマザボとかケースとかを見て回った。

え、デカくない?

自作 PC 勢ってみんなあんな巨大なやつ自宅に置いてるの? 正気???

MicroATX サイズのケースでもだいぶデカい。
できれば MiniITX サイズで組みたいけど、それだと GPU 二枚積むのは無理ぽい。

もはや GPU 二枚積めなくていいから Intel NUC くらいコンパクトなやつねーかなー、と無茶なことを考えながらググってたら、ZBOX EN1070K という GPU 積んでるコンパクトなやつを発見した。

GTX 1070 + Core i5 積んでるし、もうこれでええやんけ。

「拡張性ゼロ」という強烈なデメリットがある けど、「コンパクトなやつが欲しい」という欲求の方が勝ったのでこれを購入した。

米 Amazon.com から輸入

日本で買うと ZBOX 単体で18万円くらいで、さらにベアボーンキットなので SSD とメモリを買う必要があって、そうするとどうあがいても20万円は超える。

Amazon.com 見たら $1,100 くらいで売ってたのでこっちから購入。

SSD とメモリも一緒に買って、送料と関税込みでトータル 18万円くらいで済んだ。

ただしアメリカ版を買うと電源プラグがアメリカ仕様 (3ピン) なので注意。2

SSD とメモリ

ZBOX EN1070K は m.2 と SATA の SSD をそれぞれひとつずつ挿せる。

今回はとりあえず m.2 買って OS 入れておいてデータ保存場所が足りなくなったら SATA のやつ買って追加すればいいか、と考えてとりあえず m.2 SSD 250 GB だけ買った。

メモリスロットは DDR4 2400/2133 S.O.DIMM x 2 で、最大 32 GB とのこと。

とりあえず MAX 積んでおくか、という雑な感じで 16GB x 2 を買った。

届いた

ちゃんと届くか不安だったけど、二週間くらいで普通に届いた。

f:id:hoto17296:20171012211941j:plain

テンション上がる。

組み立てる

以下の記事がすげー詳細に書いてあって参考になった。

手の平にハイエンドPCを! 「MAGNUS EN1070 / EN1060」を比較レビュー : 自作とゲームと趣味の日々

最初メモリの取り付け方をミスって起動できなくて焦った。

ちゃんと斜め45度から挿してから倒す、ってやらないとダメなんだな・・・。

Ubuntu 16.04 を入れる

「BIOS はもう古い、時代は UEFI !!!」

みたいなのを耳にしてたので「ちゃんとインストールできるだろうか...」と震えていたけど、普通に minimal の ISO を USB に焼いて挿したらインストールできた。

ちなみにデスクトップ版も試したけど、むしろこっちのほうが面倒だった。 NVIDIA の GPU が載ってると GUI が起動できないので、カーネルオプションで nomodeset を指定する必要がある。

qiita.com

機械学習するのに GUI は要らないので、何も考えずに minimal をインストールするのがいい。

Wake on LAN の設定をする

機械学習用マシンは常時使っているわけではないので、使ってないときは電源落としておきたい。

自宅に要るときは電源ボタンを押せばいいけど、外出中にリモートで自宅のマシンを起動したいという場合には Wake on LAN を使うとできる。

ZBOX は Wake on LAN に対応していて、UEFI の設定画面から Wake on LAN の設定を切り替えるだけで有効にできた。

あとは電源が落ちている ZBOX に対して Wake on LAN パケットを投げつけると起動してくれるのだけど、VPN 経由でリモートからパケットを投げるときにちょっと苦労した。

qiita.com

学習環境を作る

あとは冒頭の Qiita に書いたのとほとんど同じ。

qiita.com

P2 インスタンスを使っていたときは Tesla K80 だったのでドライバは nvidia-375 を入れたけど、今回は GTX 1070 なので nvidia-367 を入れる、という点だけ違う。

Mackerel で GPU 温度を監視する

コンパクトさが欲しくて ZBOX にしたとはいえ、排熱効率が悪くて GPU 温度が上がりまくったらどうしよう...という不安はある。

なので、とりあえず Mackerel で監視することにした。

mackerel.io

GPU の温度を Mackerel に飛ばすのどうやってやるんだろう、と思ったら公式のプラグインに NVIDIA GPU を監視するやつがあったので楽勝だった。

mackerel-agent-plugins/mackerel-plugin-nvidia-smi · GitHub

あとは、Mackerel の監視設定で GPU 温度が一定以上になったら自宅の Slack に通知が飛ぶようにする。

雑にググったところ 80℃ くらいまでは問題ないっぽいことがわかったので

  • 80℃ で Warning
  • 100℃ で Critical

に設定してみた。

これで一安心。

ベンチマーク

Qiita の記事と同じく、NVIDIA Docker のコンテナ上で Keras の MNIST CNN のサンプルを実行した。

root@(container):/# python3 mnist_cnn.py
Using TensorFlow backend.
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz
11255808/11490434 [============================>.] - ETA: 0sx_train shape: (60000, 28, 28, 1)
60000 train samples
10000 test samples
Train on 60000 samples, validate on 10000 samples
Epoch 1/12
2017-10-09 09:23:35.248521: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.1 instructions, but these are available on your machine and could speed up CPU computations.
2017-10-09 09:23:35.248540: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
2017-10-09 09:23:35.248546: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
2017-10-09 09:23:35.248565: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX2 instructions, but these are available on your machine and could speed up CPU computations.
2017-10-09 09:23:35.248570: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use FMA instructions, but these are available on your machine and could speed up CPU computations.
2017-10-09 09:23:35.405920: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:893] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
2017-10-09 09:23:35.406452: I tensorflow/core/common_runtime/gpu/gpu_device.cc:955] Found device 0 with properties:
name: GeForce GTX 1070
major: 6 minor: 1 memoryClockRate (GHz) 1.645
pciBusID 0000:01:00.0
Total memory: 7.92GiB
Free memory: 7.83GiB
2017-10-09 09:23:35.406466: I tensorflow/core/common_runtime/gpu/gpu_device.cc:976] DMA: 0
2017-10-09 09:23:35.406471: I tensorflow/core/common_runtime/gpu/gpu_device.cc:986] 0:   Y
2017-10-09 09:23:35.406477: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1045] Creating TensorFlow device (/gpu:0) -> (device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0)
60000/60000 [==============================] - 7s - loss: 0.3325 - acc: 0.9000 - val_loss: 0.0779 - val_acc: 0.9755
Epoch 2/12
60000/60000 [==============================] - 5s - loss: 0.1147 - acc: 0.9661 - val_loss: 0.0542 - val_acc: 0.9830
Epoch 3/12
60000/60000 [==============================] - 5s - loss: 0.0872 - acc: 0.9741 - val_loss: 0.0433 - val_acc: 0.9858
Epoch 4/12
60000/60000 [==============================] - 5s - loss: 0.0742 - acc: 0.9778 - val_loss: 0.0383 - val_acc: 0.9870
Epoch 5/12
60000/60000 [==============================] - 5s - loss: 0.0628 - acc: 0.9814 - val_loss: 0.0361 - val_acc: 0.9878
Epoch 6/12
60000/60000 [==============================] - 5s - loss: 0.0585 - acc: 0.9828 - val_loss: 0.0352 - val_acc: 0.9882
Epoch 7/12
60000/60000 [==============================] - 5s - loss: 0.0517 - acc: 0.9847 - val_loss: 0.0355 - val_acc: 0.9883
Epoch 8/12
60000/60000 [==============================] - 5s - loss: 0.0480 - acc: 0.9855 - val_loss: 0.0312 - val_acc: 0.9892
Epoch 9/12
60000/60000 [==============================] - 5s - loss: 0.0432 - acc: 0.9871 - val_loss: 0.0314 - val_acc: 0.9901
Epoch 10/12
60000/60000 [==============================] - 5s - loss: 0.0423 - acc: 0.9872 - val_loss: 0.0323 - val_acc: 0.9893
Epoch 11/12
60000/60000 [==============================] - 5s - loss: 0.0390 - acc: 0.9880 - val_loss: 0.0284 - val_acc: 0.9905
Epoch 12/12
60000/60000 [==============================] - 5s - loss: 0.0398 - acc: 0.9883 - val_loss: 0.0294 - val_acc: 0.9900
Test loss: 0.0294402698388
Test accuracy: 0.99

あれっ AWS P2 インスタンスより速くない???

P2 インスタンスだと 1 epoch あたり 9 秒だったのが 5 秒で終わる。

Tesla K80 のほうが良い GPU なのになぜ・・・?
クラウドサーバだと GPU との I/O が遅かったりするんだろうか。

謎だけどまぁ速くなったのでよし。

f:id:hoto17296:20171014132309p:plain

ベンチマーク回してたときの GPU 温度はこんな感じ。
最大 67℃ だったのでこの程度なら楽勝。

あとは長時間回したときにどこまで上がるかなーというところが気になるけど、未検証。

まとめ

  • 機械学習するために自宅に GPU マシンを買った
  • ベアボーンキットだと拡張性を失う代わりにコンパクトさを手に入れられる
  • GTX 1070 でもなぜか AWS P2 インスタンスの Tesla K80 より学習が速い

自宅に機械学習環境を作りたい人にとって割とアリな選択肢だと思うので、パーツ選びを始める前にこっちも検討してみてはいかが。


  1. 複数枚の GPU を繋げられるやつ。SLI ブリッジと SLI 対応のマザーボードを使う必要がある。

  2. 我が家は電源タップが3ピン対応だったので特に問題はなかった。愛三電機の電源タップは良いぞ。