4ヶ月前にこんな Qiita を書いた。
しかし自宅に 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 積んでるコンパクトなやつを発見した。
ZOTAC MAGNUS EN1070K GTX1070搭載ゲーミングミニベアボーン PC3094 ZBOX-EN1070K-J
- 出版社/メーカー: ZOTAC
- 発売日: 2017/06/23
- メディア: Personal Computers
- この商品を含むブログを見る
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 だけ買った。
Samsung SSD 250GB 960 EVO M.2 Type2280 PCIe3.0×4 NVMe1.2 V-NAND搭載 3年保証 日本サムスン正規品 MZ-V6E250B/IT
- 出版社/メーカー: 日本サムスン
- メディア: Personal Computers
- この商品を含むブログを見る
メモリスロットは DDR4 2400/2133 S.O.DIMM x 2 で、最大 32 GB とのこと。
とりあえず MAX 積んでおくか、という雑な感じで 16GB x 2 を買った。
- 出版社/メーカー: Crucial(クルーシャル)
- 発売日: 2015/10/20
- メディア: Personal Computers
- この商品を含むブログを見る
届いた
ちゃんと届くか不安だったけど、二週間くらいで普通に届いた。
テンション上がる。
組み立てる
以下の記事がすげー詳細に書いてあって参考になった。
手の平にハイエンドPCを! 「MAGNUS EN1070 / EN1060」を比較レビュー : 自作とゲームと趣味の日々
最初メモリの取り付け方をミスって起動できなくて焦った。
ちゃんと斜め45度から挿してから倒す、ってやらないとダメなんだな・・・。
Ubuntu 16.04 を入れる
「BIOS はもう古い、時代は UEFI !!!」
みたいなのを耳にしてたので「ちゃんとインストールできるだろうか...」と震えていたけど、普通に minimal の ISO を USB に焼いて挿したらインストールできた。
ちなみにデスクトップ版も試したけど、むしろこっちのほうが面倒だった。
NVIDIA の GPU が載ってると GUI が起動できないので、カーネルオプションで nomodeset
を指定する必要がある。
機械学習するのに GUI は要らないので、何も考えずに minimal をインストールするのがいい。
Wake on LAN の設定をする
機械学習用マシンは常時使っているわけではないので、使ってないときは電源落としておきたい。
自宅に要るときは電源ボタンを押せばいいけど、外出中にリモートで自宅のマシンを起動したいという場合には Wake on LAN を使うとできる。
ZBOX は Wake on LAN に対応していて、UEFI の設定画面から Wake on LAN の設定を切り替えるだけで有効にできた。
あとは電源が落ちている ZBOX に対して Wake on LAN パケットを投げつけると起動してくれるのだけど、VPN 経由でリモートからパケットを投げるときにちょっと苦労した。
学習環境を作る
あとは冒頭の Qiita に書いたのとほとんど同じ。
P2 インスタンスを使っていたときは Tesla K80 だったのでドライバは nvidia-375
を入れたけど、今回は GTX 1070 なので nvidia-367
を入れる、という点だけ違う。
Mackerel で GPU 温度を監視する
コンパクトさが欲しくて ZBOX にしたとはいえ、排熱効率が悪くて GPU 温度が上がりまくったらどうしよう...という不安はある。
なので、とりあえず Mackerel で監視することにした。
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 が遅かったりするんだろうか。
謎だけどまぁ速くなったのでよし。
ベンチマーク回してたときの GPU 温度はこんな感じ。
最大 67℃ だったのでこの程度なら楽勝。
あとは長時間回したときにどこまで上がるかなーというところが気になるけど、未検証。
まとめ
- 機械学習するために自宅に GPU マシンを買った
- ベアボーンキットだと拡張性を失う代わりにコンパクトさを手に入れられる
- GTX 1070 でもなぜか AWS P2 インスタンスの Tesla K80 より学習が速い
自宅に機械学習環境を作りたい人にとって割とアリな選択肢だと思うので、パーツ選びを始める前にこっちも検討してみてはいかが。