はじめに
ひょんな事からGTX1070Tiのグラフィックカードを入手しました。様々な環境でGPUを使ってみたいため、ESXiでパススルーさせて仮想OS上で扱えるようにしてみます。
動作確認としてChainerをインストールし、簡単ながら、仮想環境のGPU性能と物理環境のGPU性能も比較してみます。
環境
今回の検証環境は以下の通りです。
- ハードウェア
ハードウェア | バージョン等 | 備考 |
---|---|---|
CPU | Intel Core i7-3770 3.40 GHz | |
M/B | ASUS P8B75-M | |
MEM | DDR3-1600 8GB x 4(32GB) | |
GPU | GEFORCE GTX1070Ti | |
NIC | Intel Gigabit CT Desktop Adapter EXPI9301CT | オンボードNIC(realtek)はESXiが認識せず、設定が手間なので手っ取り早くIntel NICを導入 |
- ソフトウェア
ソフトウェア | バージョン等 | 備考 |
---|---|---|
VMware vSphere Hypervisor(ESXi) | 6.7 | |
Ubuntu | 18.04 | 仮想OSとして使用 |
Anaconda3 | 5.2 Python3.6 ver | |
Python | 3.6.5 | Anacondaにて |
CUDA Toolkit | 10.0.130 | |
CuDNN | 7.3.0.29 for CUDA10 | |
CuPy | 4.4.1 | |
Chainer | 4.4.0 |
環境構築の流れ
以下の流れで構築します。
- NICの設置
- UEFI(BIOS)の設定
- ESXiのインストール、ネットワーク設定
- GPUパススルーの設定
- Ubuntuのインストール
- UbuntuでGPUを使用するための設定
- 各種ソフトウェアのインストール
1. NICの設置
ESXiは対応しているNICが限られており、Realtek社などのオンボードNICは対応していないことが多いです。
IntelのオンボードNICなら対応しているかもしれませんが、今回使用するオンボードNICはRealtek社製であり非対応でした。
NICのドライバを入手してESXiのイメージを作り直す方法もありますが手間なので、今回はIntel NICを導入しました。
2. UEFI(BIOS)の設定
GPUパススルーするにはUEFI(BIOS)の以下の設定変更が必要です。
具体的な設定項目は使用するM/Bによって異なるため、詳細は省きます。
- iGPUの無効化 / PCIeグラフィックカードの有効化
- オンボードオーディオの無効化
今回、手間取った点がオンボードオーディオの無効化でした。これも無効にしないと正しくGPUを使用できませんでした。
当然ながら、ディスプレイケーブルはG/B側に接続します。
3. ESXiのインストール、ネットワーク設定
これは通常通りインストールすればOKです。私はブータブルUSBにインストールしています。
インストール完了後、必要に応じてネットワーク設定を行って下さい。
4. GPUパススルーの設定
いよいよGPUパススルーの設定です。ブラウザでESXiにアクセスします。
左ペインの「ホスト」-「管理」を選択し、「ハードウェア」タブの「PCIデバイス」を選択します。
デバイスの一覧が表示されるため、グラフィックカードを探して選択し、「パススルーの切り替え」をクリックします。
切り替え後に再起動します。
私の環境の場合、再起動中に問題が発生しました。
「dma_mapper_iommu loaded successfully」という表示のまま固まってしまいます。
結果的には、このままでもESXiに接続でき仮想マシンもインストールできるのですが解決方法は見つかっていません。他のM/Bならば発生しないかもしれません。
##5. Ubuntuのインストール
これは普通にインストールしてOKです。今回はCPU6コア、メモリ24GBを割り当てています。
仮想マシンの構成パラメータとして、「hypervisor.cpuid.v0=FALSE」を追加しておきます。
なお、この段階では仮想マシンにPCIデバイスのG/Bの割り当ては行っていません。
##6. UbuntuでGPUを使用するための設定
ここからは仮想マシンのUbuntu上での作業になります。
おなじみのapt-get updateなど実行します。適宜再起動しつつ、以下を実施します。
ここではopenssh-serverもインストールし、SSHで接続して作業できるようにしています。
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install openssh-server
$ sudo apt-get install build-essential
GPUを使用するには、デフォルトで使用されているnouveauグラフィックスドライバを無効化しなければなりません。カーネルモジュールとしてnouveauをロードしないように設定します。
"/etc/modprobe.d/blacklist-nouveau.conf"ファイルを作成し、update-initramfsで再構築します。
$ sudo vi /etc/modprobe.d/blacklist-nouveau.conf
# 以下を記述して保存する。
blacklist nouveau
options nouveau modeset=0
$ sudo update-initramfs -u
ここで一度Ubuntuを終了させて、ESXiで仮想マシンの設定を行います。仮想マシンにPCIデバイスのG/Bを追加します。その後、Ubuntuを起動します。
Ubuntu起動後にnouveauが無効になっており、G/Bがデバイスとして認識されていることを確認します。
$ lsmod | grep nouveau
# 何も表示されなければOK
$ lspci | grep -i nvidia
03:00.0 VGA compatible controller: NVIDIA Corporation GP104 (rev a1)
#7. 各種ソフトウェアのインストール
ここからAnaconda3、CUDA Toolkit、CuDNN、CuPy、Chainerをインストールします。
- Anaconda3のインストール
通常通りインストールします。
$ wget https://repo.anaconda.com/archive/Anaconda3-5.2.0-Linux-x86_64.sh
$ sudo bash Anaconda3-5.2.0-Linux-x86_64.sh
$ python -V
Python 3.6.5 :: Anaconda, Inc.
- CUDA Toolkitのインストール
これも特に問題なくインストール出来ると思います。CUDAのインストール時にGPUのデバイスドライバもインストールしてくれます。
$ wget https://developer.nvidia.com/compute/cuda/10.0/Prod/local_installers/cuda_10.0.130_410.48_linux
$ sudo bash cuda_10.0.130_410.48_linux
環境変数として以下を~/.bashrcに追加しておきます。
export PATH=$PATH:/usr/local/cuda-10.0/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda-10.0/lib64
再起動後、デバイスドライバが登録されているか確認します。
$ nvidia-smi
Wed Sep 26 13:16:34 2018
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 410.48 Driver Version: 410.48 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 GeForce GTX 107... Off | 00000000:03:00.0 Off | N/A |
| 0% 53C P8 13W / 180W | 0MiB / 8119MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
- CuDNNのインストール
これも問題なくインストールできると思います。
$ tar xvzf cudnn-10.0-linux-x64-v7.3.0.29.tgz
$ sudo cp cuda/include/cudnn.h /usr/local/cuda-10.0/include
$ sudo cp cuda/lib64/libcudnn* /usr/local/cuda-10.0/lib64
$ sudo chmod a+r /usr/local/cuda-10.0/include/cudnn.h /usr/local/cuda-10.0/lib64/libcudnn*
- CuPy, Chainerのインストール
これもpipのおなじみの手順でインストールできると思います。Chainerのサンプルを使用するためダウンロードして解凍します。
$ python -m pip install -U pip
$ pip install cupy
$ pip install chainer
$ wget https://github.com/chainer/chainer/archive/v4.4.0.tar.gz
$ tar xvzf v4.4.0.tar.gz
GPUでMNISTを実行してみる
Chainerのサンプルのmnistを実行してみます。
$ python train_mnist.py -g 0 --noplot
GPU: 0
# unit: 1000
# Minibatch-size: 100
# epoch: 20
epoch main/loss validation/main/loss main/accuracy validation/main/accuracy elapsed_time
1 0.192528 0.095931 0.941617 0.9697 3.5658
2 0.0734889 0.0736662 0.976632 0.9775 6.15579
3 0.0492194 0.0798578 0.984015 0.9751 8.7438
4 0.0358381 0.0711196 0.988299 0.9808 11.3176
5 0.0291727 0.0790036 0.990415 0.9788 13.8838
6 0.0249285 0.0648517 0.992448 0.9828 16.4479
7 0.0177988 0.0665626 0.994365 0.9812 19.0179
8 0.0204571 0.0933524 0.993382 0.9786 21.6026
9 0.0137231 0.0830202 0.995382 0.9826 24.2013
10 0.0179817 0.079697 0.994182 0.9797 26.7915
11 0.0129556 0.0820209 0.995815 0.9821 29.3783
12 0.0125504 0.0999209 0.996032 0.9796 31.9766
13 0.012244 0.0870966 0.995949 0.9825 34.5637
14 0.00928367 0.0855221 0.997249 0.982 37.1542
15 0.0101715 0.11876 0.996765 0.9779 39.7451
16 0.0112296 0.108288 0.996732 0.9809 42.3315
17 0.013817 0.0989172 0.996016 0.9817 44.9493
18 0.00567857 0.0943258 0.998149 0.9818 47.5357
19 0.00869481 0.120587 0.997432 0.9804 50.1249
20 0.0106723 0.103008 0.997016 0.983 52.7213
で、仮想環境ではなく、同一のハードウェア構成の物理環境にUbuntuをインストールして同じようにmnistを実行してみると以下のようになりました。
epoch main/loss validation/main/loss main/accuracy validation/main/accuracy elapsed_time
1 0.190415 0.0903942 0.943167 0.9721 2.67092
2 0.0746116 0.0807735 0.976516 0.9726 5.08526
3 0.0492081 0.0701688 0.984416 0.9778 7.49376
4 0.0348724 0.0922888 0.988465 0.9734 9.91205
5 0.0306512 0.0677831 0.989832 0.9814 12.3288
6 0.0238598 0.0793712 0.992032 0.9781 14.748
7 0.0199106 0.0958048 0.993465 0.9771 17.1625
8 0.0194361 0.104865 0.993632 0.9772 19.5808
9 0.0169871 0.103223 0.994765 0.9781 21.9916
10 0.0141968 0.0858889 0.995565 0.978 24.4067
11 0.0161239 0.102017 0.994415 0.9784 26.8181
12 0.0116298 0.0891281 0.996165 0.9806 29.2339
13 0.0124855 0.0925222 0.995999 0.9813 31.6487
14 0.00826959 0.0935222 0.997332 0.9825 34.0658
15 0.016028 0.0884019 0.995482 0.9828 36.4816
16 0.00984132 0.0873142 0.996866 0.9837 38.8963
17 0.00607726 0.0908004 0.998116 0.9841 41.3141
18 0.0122555 0.0953374 0.996732 0.9832 43.7299
19 0.00827334 0.0978206 0.997582 0.9824 46.148
20 0.0105671 0.0836676 0.996965 0.9834 48.568
環境 | 経過時間 |
---|---|
仮想環境 | 52.7213秒 |
物理環境 | 48.568秒 |
GPUパススルーした仮想環境よりも物理環境の方がさすがに速いです。
それでもGPUを使って様々な環境で実験したい場合には、ESXiによる仮想化は有用かと思います。