TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

dlshogiをAWSのNVIDIA A100インスタンスで動かす

AWSのEC2に、NVIDIA A100のインスタンスが追加されたので、dlshogiでどれくらNPSが向上するか測定してみた。

個人としてはAWSを使っていなかったので、AWSのアカウントを作成して、vCPUの上限緩和申請するところから行った。
P4dインスタンスは、vCPUが96なので、上限緩和申請が必要である。
しかし、上限緩和申請をお断りされてしまった。

そこで、知り合いからアカウントをお借りして測定を行うことにした。

環境構築

AMI

AMIは、p4d.24xlargeに対応している「AWS Deep Learning Base AMI (Ubuntu 18.04) Version 31.0」を使用した。

GPUが認識されているか確認
$ nvidia-smi
Sat Nov  7 03:42:57 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.80.02    Driver Version: 450.80.02    CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  A100-SXM4-40GB      On   | 00000000:10:1C.0 Off |                    0 |
| N/A   37C    P0    54W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   1  A100-SXM4-40GB      On   | 00000000:10:1D.0 Off |                    0 |
| N/A   37C    P0    51W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   2  A100-SXM4-40GB      On   | 00000000:20:1C.0 Off |                    0 |
| N/A   37C    P0    54W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   3  A100-SXM4-40GB      On   | 00000000:20:1D.0 Off |                    0 |
| N/A   35C    P0    51W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   4  A100-SXM4-40GB      On   | 00000000:90:1C.0 Off |                    0 |
| N/A   36C    P0    51W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   5  A100-SXM4-40GB      On   | 00000000:90:1D.0 Off |                    0 |
| N/A   36C    P0    54W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   6  A100-SXM4-40GB      On   | 00000000:A0:1C.0 Off |                    0 |
| N/A   38C    P0    56W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+
|   7  A100-SXM4-40GB      On   | 00000000:A0:1D.0 Off |                    0 |
| N/A   36C    P0    51W / 400W |      0MiB / 40537MiB |      0%      Default |
|                               |                      |             Disabled |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
CUDAバージョン変更

まず、デフォルトのCUDAバージョンが10.0になっているため、手順に従い、11.0に変更する。

$ sudo rm /usr/local/cuda
$ sudo ln -s /usr/local/cuda-11.0 /usr/local/cuda

バージョン確認

~$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Wed_Jul_22_19:09:09_PDT_2020
Cuda compilation tools, release 11.0, V11.0.221
Build cuda_11.0_bu.TC445_37.28845127_0
TensorRTインストール

NVIDIAのサイトからTensorRTをダウンロードする。

Ubuntu用に、.debと.tar.gzが用意されているが、.debでインストールする場合、CUDAのパッケージも.debでインストールされていないと、最新バージョンのCUDAをインストールしようとしてインストールが失敗するため、無難に.tar.gzを使用する。

TensorRT 7.2.1 for Ubuntu 18.04 and CUDA 11.1 TAR package
をダウンロードする。

適当なディレクトリに展開する。
以下、ホームディレクトリ(/home/ubuntu/)に展開したものとする。

tar xzf TensorRT-7.2.1.6.Ubuntu-18.04.x86_64-gnu.cuda-11.0.cudnn8.0.tar.gz

環境変数LD_LIBRARY_PATHを設定する。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ubuntu/TensorRT-7.2.1.6/lib
dlshogiのビルド

ソースをGitHubからcloneする。

git clone https://github.com/TadaoYamaoka/DeepLearningShogi.git

Makefileを編集する。

cd cd DeepLearningShogi/usi
vi Makefile

「INCLUDE = 」で始まる行の末尾に「 -I/home/ubuntu/TensorRT-7.2.1.6/include」を追加
「LIB = 」で始まる行の「cuda-10.2」を「cuda-11.0」に変更
「LIB = 」で始まる行の末尾に「 -L/home/ubuntu/TensorRT-7.2.1.6/lib」を追加

ビルドする。

make

ライブラリが正常にロードできるか確認

cd bin
$ ldd usi
        linux-vdso.so.1 (0x00007ffe8f171000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f15512f4000)
        libnvinfer.so.7 => /home/ubuntu/TensorRT-7.2.1.6/lib/libnvinfer.so.7 (0x00007f153552d000)
        libnvonnxparser.so.7 => /home/ubuntu/TensorRT-7.2.1.6/lib/libnvonnxparser.so.7 (0x00007f15350b7000)
        libcudnn.so.8 => /usr/local/cuda/lib64/libcudnn.so.8 (0x00007f1534e8e000)
        libcudart.so.11.0 => /usr/local/cuda/lib64/libcudart.so.11.0 (0x00007f1534c10000)
        libcublas.so.11 => /usr/local/cuda/lib64/libcublas.so.11 (0x00007f152edc0000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f152eba3000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f152e81a000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f152e47c000)
        libmvec.so.1 => /lib/x86_64-linux-gnu/libmvec.so.1 (0x00007f152e252000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f152e03a000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f152dc49000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1552017000)
        libmyelin.so.1 => /home/ubuntu/TensorRT-7.2.1.6/lib/libmyelin.so.1 (0x00007f152d3ca000)
        libnvrtc.so.11.0 => /usr/local/cuda/lib64/libnvrtc.so.11.0 (0x00007f152bbdf000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f152b9d7000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f152b7d3000)
        libnvinfer_plugin.so.7 => /home/ubuntu/TensorRT-7.2.1.6/lib/libnvinfer_plugin.so.7 (0x00007f152a9d6000)
        libcublasLt.so.11 => /usr/local/cuda/lib64/libcublasLt.so.11 (0x00007f151f847000)
usiコマンド実行

適当なディレクトリにモデルファイルを用意する。
以下では、/home/ubuntu/model_rl_val_wideresnet10_selfplay_424.onnxにあるモデルファイルを使用する。

cd bin
./usi
setoption name DNN_Model value /home/ubuntu/model_rl_val_wideresnet10_selfplay_424.onnx
setoption name UCT_Threads value 3
setoption name UCT_Threads2 value 3
setoption name UCT_Threads3 value 3
setoption name UCT_Threads4 value 3
setoption name UCT_Threads5 value 3
setoption name UCT_Threads6 value 3
setoption name UCT_Threads7 value 3
setoption name UCT_Threads8 value 3
isready

TensorRTによる最適化に数分かかる。
数分後、以下のように表示される。

(略)
----------------------------------------------------------------
Input filename:   /home/ubuntu/model_rl_val_wideresnet10_selfplay_424.onnx
ONNX IR version:  0.0.6
Opset version:    9
Producer name:    pytorch
Producer version: 1.6
Domain:
Model version:    0
Doc string:
----------------------------------------------------------------
info nps 4 time 204003 nodes 900 hashfull 0 score cp 93 depth 8 pv 7g7f 3c3d 2g2f 8c8d 2f2e 4a3b 2e2d 2c2d
All Playouts       :      900
Pre Simulated      :        0
Thinking Time      :  204.003 sec
Winning Percentage :  52.5785%
Playout Speed      :        4 PO/sec
readyok

初期局面を探索する。

position startpos
go byoyomi 5000

以下のように表示される。

info nps 351568 time 4516 nodes 1587682 hashfull 158 score cp 97 depth 50 pv 7g7f 8c8d 2g2f 8d8e 8h7g 3c3d 7i6h 4c4d 2f2e 2b3c 6i7h 4a3b 3i4h 3a4b 5g5f 4b4c 6g6f 5c5d 6h6g 6a5b 4i5h 7a6b 3g3f 7c7d 2i3g 8a7c 4g4f 6c6d 4h4g 6b6c 2h2i 8b8a 9g9f 9c9d 1g1f 1c1d 7g6h 3c4b 5i6i 5a4a 3f3e 3d3e 4f4e 4d4e 6h3e 6d6e 6f6e 4c3d 3e4d 4b3c
bestmove 7g7f

初期局面で、約35万NPSがでている。
V100×8の環境では、初期局面で約25万NPSである。

NPS測定

floodgateからサンプリングした100局面で、NPSを測定した(測定用スクリプト)。
比較のためにV100×8の結果も載せている。

$ python3 benchmark.py --gpus 8 --threads 3 --engine /home/ubuntu/DeepLearningShogi/usi/bin/usi --model /home/ubuntu/model_rl_val_wideresnet10_selfplay_424.onnx
平均 中央値 最小値 最大値
A100 272,388 267,825 158,001 369,383
V100 219,281 219,567 137,441 276,373
A100/V100 1.24 1.22 1.15 1.34

V100と比較すると、NPSが平均で1.25倍になっている。

カタログスペックでは、TensorCoreの性能は、

V100 125 TFLOPS
A100 312 TFLOPS
A100/V100 2.496

なので、もっと性能がでても良さそうである。

推論速度比較

純粋に、GPUに推論の速度を比較してみた(測定コード)。
floodgateからサンプリングした10万局面をバッチサイズ128で推論した際の時間を比較する。

$ ./test model_rl_val_wideresnet10_selfplay_424.onnx floodgate.hcpe 100000 7 128
A100 1442 ms
V100 2554 ms
A100/V100 1.77

推論速度のみであれば、1.77倍となった。
すべてのGPU演算でTensorCoreを使用しているわけではないので、これくらいで妥当なのかもしれない。

探索時のNPSの比がこれより下がっているのは、探索にボトルネックがあるので、まだ改良の余地があるかもしれない。

まとめ

AWSのA100インスタンスで、dlshogiの探索速度がどれだけ上がるか測定を行った。
結果、V100と比較してNPSが平均1.25倍になることがわかった。


再来週の電竜戦には、A100インスタンスを借りて参加するかもしれません。