Amazon EC2にディープラニング系将棋ソフトのdlshogiをインストールしてみた

Amazon EC2のGPU系インスタンスにディープラーニング系将棋ソフトのdlshogiをインストールしてみた
2021.10.15

最近はdlshogiやPALなど深層強化学習ベースの将棋ソフトの躍進が目覚ましく、使ってみたい人も多いかと思います。

ただし、性能を引き出すには、そもそもちゃんとしたGPUが必要だったり、NVIDIA 系の依存ライブラリのために、インストールも煩雑です。

今回は、Amazon EC2のGPU系インスタンスに、ディープラーニング系のコミコミのAMI(コンピュータのテンプレート)を使って、なるだけ省エネで dlshogi をインストールする方法を紹介します。

前提

NVIDIA A100を8基搭載した EC2のGPU系最強インスタンスタイプ P4d は Linux 系 OS にしか対応していないことから、ターゲット OS も Linux とし、コマンドラインで usi インターフェースを動作確認できるところまでをゴールとします。

なお、 dlshogi 将棋の作者が 1年ほど前の EC2 P4d リリース直後に、EC2 向けのインストール手順をまとめてくださっています。 本記事はバージョン・手順を現状に合わせただけです。

dlshogiをAWSのNVIDIA A100インスタンスで動かす - TadaoYamaokaの日記

また、Windows に dlshogi をインストールしたい場合、次の動画を参照ください。

環境

AWS の基本的な使い方を知っている前提で、以下の環境にインストールします。

  • インスタンスタイプ p3.2xlarge (Tesla V100/GPU 1基)
  • AWS Deep Learning Base AMI (Ubuntu 18.04) Version 50.0
  • NVIDIA CUDA 11.0
  • TensorRT-7.2.3.4
  • dlshogi : 2021/10/14 時点の master ブランチ最新

1. AMI の選択

EC2インスタンス起動ウィザードの AMI 選択画面で「Deep Learning AMI」で検索し、オペレーティング・システムを「Ubuntu」でフィルターします。

  • Version 50.0(あるいはより新しいバージョン)
  • OS : Ubuntu 18.04

のAMIを選択してください。

2. インスタンスタイプの選択

GPU系インスタンスタイプを選択してください。

EC2系最強 GPU インスタンスタイプを利用したい場合は、 A100 x 8基搭載の P4.24xlarge を選択してください。

動作確認に時間がかかることを想定し、利用費抑制の観点から、今回はP系の1世代前の P3 インスタンスを利用しました。 P4 や G4 のような他のGPU系インスタンスタイプでも、同じ手順で動作するはずです。

参考までに、P3/P4/G4 それぞれのインスタンスファミリーの最小スペックでの、東京リージョンでのオンデマンドの時間単価を記載します。

インスタンスタイプ 時間単価
p4d.24xlarge $44.92215
p3.2xlarge $4.194
g4dn.xlarge $0.71

3. EC2 を起動

その後は、通常の手順で EC2 インスタンスを起動してください。

後に、 NVidia TensorRT SDK のファイル転送が発生します。

SCP 用にセキュリティグループで SSH ポートをあけておきましょう。

4. CUDA のバージョン変更

AWS Deep Learning Base AMIでは、複数の NVIDIA CUDAバージョンがインストールされています。

デフォルト(/usr/local/cuda)は 10.0 です。

~$ ls -l /usr/local/
total 60
drwxr-xr-x  3 root root 4096 Oct  6 16:42 bin
lrwxrwxrwx  1 root root   20 Oct  5 22:32 cuda -> /usr/local/cuda-10.0
drwxr-xr-x 18 root root 4096 Oct  5 22:33 cuda-10.0
drwxr-xr-x 19 root root 4096 Oct  5 22:28 cuda-10.1
drwxr-xr-x 20 root root 4096 Oct  5 22:30 cuda-10.2
drwxr-xr-x 25 root root 4096 Oct  5 22:26 cuda-11.0
drwxr-xr-x 19 root root 4096 Oct  5 22:21 cuda-11.1
drwxr-xr-x  3 root root 4096 Oct  5 22:34 dcgm
drwxr-xr-x  3 root root 4096 Oct  5 21:23 etc
drwxr-xr-x  2 root root 4096 Feb 24  2021 games
drwxr-xr-x  3 root root 4096 Oct  5 22:37 include
drwxr-xr-x  4 root root 4096 Oct  5 21:23 init
drwxr-xr-x  6 root root 4096 Oct  5 22:37 lib
lrwxrwxrwx  1 root root    9 Feb 24  2021 man -> share/man
drwxr-xr-x  2 root root 4096 Feb 24  2021 sbin
drwxr-xr-x 12 root root 4096 Oct  5 22:37 share
drwxr-xr-x  2 root root 4096 Feb 24  2021 src

シンボリックリンクの向き先を CUDA 11.0 に変更します。

~$ sudo ln -sfn /usr/local/cuda-11.1 /usr/local/cuda

バージョンを確認します。

$ readlink /usr/local/cuda
/usr/local/cuda-11.0

$ 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

$ nvidia-smi
Thu Oct 14 21:15:55 2021
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.142.00   Driver Version: 450.142.00   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  Tesla V100-SXM2...  On   | 00000000:00:1E.0 Off |                    0 |
| N/A   38C    P0    24W / 300W |      0MiB / 16160MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+

4. NVIDIA TensorRT SDK のダウンロード

dlshogi を実行するには、ソース本体のほか

  • CUDA(関連ツール含む)
  • NVIDIA TensorRT SDK

が必要です。

Deep Learning AMI には CUDA の複数のバージョンがインストールされているため、NVIDIA TensorRT SDK だけを手動インストールします。

NVIDIA TensorRT SDK をダウンロードするには、NVIDIA 開発者向けサイトにユーザー登録&認証している必要があります。

次の URL からユーザー登録してください。

https://developer.nvidia.com/

次に、次の URL から TensorRT をダウンロードしてください。

https://developer.nvidia.com/nvidia-tensorrt-download

今回は、環境が

  • OS : Ubuntu 18.04
  • CUDA : 11.0

のため、 「TensorRT 7.2.3 for Ubuntu 18.04 and CUDA 11.0 TAR package」をダウンロードします。

このSDKをEC2インスタンスに SCP 転送して展開し、 LD_LIBRARY_PATH に追加します。

~$ tar zxfv TensorRT-7.2.3.4.Ubuntu-18.04.x86_64-gnu.cuda-11.0.cudnn8.1.tar.gz
...
TensorRT-7.2.3.4/data/int8_api/
TensorRT-7.2.3.4/data/int8_api/airliner.ppm
TensorRT-7.2.3.4/data/int8_api/reference_labels.txt
TensorRT-7.2.3.4/data/int8_api/resnet50_per_tensor_dynamic_range.txt
TensorRT-7.2.3.4/data/int8_api/README.md

~$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/ubuntu/TensorRT-7.2.3.4/lib

5. dlshogi のビルド

最後に dlshogi のビルドです

ソースコードは GitHub 管理されているため、 clone します。

$ git clone https://github.com/TadaoYamaoka/DeepLearningShogi.git
Cloning into 'DeepLearningShogi'...
remote: Enumerating objects: 7516, done.
remote: Counting objects: 100% (1655/1655), done.
remote: Compressing objects: 100% (636/636), done.
remote: Total 7516 (delta 1200), reused 1455 (delta 1019), pack-reused 5861
Receiving objects: 100% (7516/7516), 2.71 MiB | 22.93 MiB/s, done.
Resolving deltas: 100% (5688/5688), done.

$ cd DeepLearningShogi/usi

Make ファイル内に TensorRT へのパスを追記します。

  • INCLUDE に -I/home/ubuntu/TensorRT-7.2.3.4/include を追記
  • LIB に -L/home/ubuntu/TensorRT-7.2.3.4/lib を追記

差分を確認します。

~/DeepLearningShogi/usi$ git diff
diff --git a/usi/Makefile b/usi/Makefile
index 15850aa..321b960 100644
--- a/usi/Makefile
+++ b/usi/Makefile
@@ -2,8 +2,8 @@
 MATE_SEARCH_DEPTH = 5
 CFLAGS = -std=c++17 -Wextra -Ofast -MMD -MP -fopenmp -DPV_MATE_SEARCH -DWIN_TYPE_DOUBLE -DMATE_SEARCH_DEPTH=$(MATE_SEARCH_DEPTH) -DTHREAD_POOL -DNDEBUG -DHAVE_SSE4 -DHAVE_SSE42 -DHAVE_BMI2 -msse4.2 -mbmi2 -DHAVE_AVX2 -mavx2
 LDFLAGS = -lpthread -lnvinfer -lnvparsers -lnvonnxparser -lcudart -flto
-INCLUDE = -I../usi -I../cppshogi -I../cppshogi -I/usr/local/cuda/include
-LIB = -L/usr/local/cuda/lib64
+INCLUDE = -I../usi -I../cppshogi -I../cppshogi -I/usr/local/cuda/include -I/home/ubuntu/TensorRT-7.2.3.4/include
+LIB = -L/usr/local/cuda/lib64 -L/home/ubuntu/TensorRT-7.2.3.4/lib

 target = bin/usi
 target_make_book = bin/make_book

make でビルドします。

bin/usi というバイナリーが作成されます。

~/DeepLearningShogi/usi$ make
...
~/DeepLearningShogi/usi$ ls bin/
usi

~/DeepLearningShogi/usi$ ldd bin/usi
        linux-vdso.so.1 (0x00007fff86a8b000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1f8799e000)
        libnvinfer.so.7 => /home/ubuntu/TensorRT-7.2.3.4/lib/libnvinfer.so.7 (0x00007f1f61f3b000)
        libnvonnxparser.so.7 => /home/ubuntu/TensorRT-7.2.3.4/lib/libnvonnxparser.so.7 (0x00007f1f61ac5000)
        libcudart.so.11.0 => /usr/local/cuda/lib64/libcudart.so.11.0 (0x00007f1f61840000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1f614b7000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1f61119000)
        libmvec.so.1 => /lib/x86_64-linux-gnu/libmvec.so.1 (0x00007f1f60eef000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1f60cd7000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1f608e6000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1f88915000)
        libcudnn.so.8 => /usr/local/cuda/lib64/libcudnn.so.8 (0x00007f1f606bd000)
        libmyelin.so.1 => /home/ubuntu/TensorRT-7.2.3.4/lib/libmyelin.so.1 (0x00007f1f5fe3d000)
        libnvrtc.so.11.1 => /usr/local/cuda/lib64/libnvrtc.so.11.1 (0x00007f1f5dc72000)
        librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f1f5da6a000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1f5d866000)
        libnvinfer_plugin.so.7 => /home/ubuntu/TensorRT-7.2.3.4/lib/libnvinfer_plugin.so.7 (0x00007f1f5c60b000)
        libcublas.so.11 => /usr/local/cuda/lib64/libcublas.so.11 (0x00007f1f541ef000)
        libcublasLt.so.11 => /usr/local/cuda/lib64/libcublasLt.so.11 (0x00007f1f461fb000)
  • CUDA 11.0
  • TensorRT-7.2.3.4

などとリンクされていることがわかります。

6. モデルのダウンロード

最後に、モデルをダウンロードします。

今回は第2回世界将棋AI電竜戦エキシビジョンバージョン 向けでリリースされているモデル(model-dr2_exhi.zip)を次リリースから取得しました。

https://github.com/TadaoYamaoka/DeepLearningShogi/releases/tag/dr2_exhi

モデルファイルを使用するにはライセンスに同意が必要です。

次の URL から、ライセンスに同意し、zip ファイルのパスワードを取得してください。

https://tadaoyamaoka.hatenablog.com/entry/2021/08/17/000710

7. USI プロトコルで実行

dlshogi は、エンジンとユーザーインターフェースを USI プロトコルで通信します。

ShogiGUI などから盤面をポチポチしている場合は USI を意識する必要はありませんが、今回はコマンドラインからの操作となるため、USI プロトコルで直接通信します。

./usi で USI モードに入り、 setoption からの3行を入力してください。

~/DeepLearningShogi/usi/bin$ ./usi

setoption name DNN_Model value /home/ubuntu/model-dr2_exhi.onnx
setoption name UCT_Threads value 3
isready

UCT_Threads は GPU1枚当たりの探索のスレッド数です。 p3.2xlarge は GPU が1枚なので、一つだけ指定します。

細かなオプションは 次の ページの 「エンジン設定」のセクションをご確認さい。

https://github.com/TadaoYamaoka/DeepLearningShogi/releases/tag/wcwc31

isready を入力後、 readyok という応答が来るまでしばらく待ちましょう。

setoption name DNN_Model value /home/ubuntu/model-dr2_exhi.onnx
setoption name UCT_Threads value 3
isready
info string C_init=127
info string C_base=27126
info string C_fpu_reduction=31
info string C_init_root=112
info string C_base_root=33311
info string Softmax_Temperature=140
----------------------------------------------------------------
Input filename:   /home/ubuntu/model-dr2_exhi.onnx
ONNX IR version:  0.0.6
Opset version:    9
Producer name:    pytorch
Producer version: 1.9
Domain:
Model version:    0
Doc string:
----------------------------------------------------------------
info nps 0 time 216990 nodes 14 hashfull 0 score cp 134 depth 2 pv 1g1f 1c1d
readyok

対局直後の盤面(startpos)で、5秒(=5000ミリ秒)検討させるため、次の2行を入力します。

position startpos
go byoyomi 5000

検討内容が標準出力されます。

info nps 19121 time 511 nodes 9771 hashfull 0 score cp 123 depth 13 pv 2g2f 3c3d 7g7f 4c4d 3i4h 3a4b 2f2e 2b3c 5i6h 4b4c 6h7h 4a3b 1g1f
info nps 20041 time 1024 nodes 20523 hashfull 2 score cp 157 depth 14 pv 2g2f 3c3d 7g7f 4c4d 3i4h 3a4b 2f2e 2b3c 5i6h 4b4c 4i5h 4a3b 3g3f 1c1d
info nps 20361 time 1536 nodes 31275 hashfull 3 score cp 168 depth 14 pv 2g2f 3c3d 7g7f 4c4d 3i4h 3a4b 2f2e 2b3c 5i6h 4b4c 4i5h 4a3b 3g3f 1c1d
info nps 20500 time 2050 nodes 42027 hashfull 4 score cp 176 depth 14 pv 2g2f 3c3d 7g7f 4c4d 3i4h 3a4b 2f2e 2b3c 5i6h 4b4c 4i5h 4a3b 3g3f 1c1d
info nps 20576 time 2565 nodes 52778 hashfull 5 score cp 180 depth 14 pv 2g2f 3c3d 7g7f 4c4d 3i4h 3a4b 2f2e 2b3c 5i6h 4b4c 4i5h 4a3b 3g3f 1c1d
info nps 20640 time 3078 nodes 63530 hashfull 6 score cp 184 depth 27 pv 2g2f 3c3d 7g7f 8c8d 2f2e 8d8e 6i7h 8e8f 8g8f 8b8f 2e2d 2c2d 2h2d 4a3b 2d3d 2b3c 5i5h 5a5b 3g3f 8f7f 8h7g 7c7d 2i3g 8a7c 3g4e 3c7g+ P*2b
info nps 20679 time 3592 nodes 74282 hashfull 7 score cp 185 depth 28 pv 2g2f 3c3d 7g7f 8c8d 2f2e 8d8e 6i7h 8e8f 8g8f 8b8f 2e2d 2c2d 2h2d 4a3b 2d3d 2b3c 5i5h 5a5b 3g3f 8f7f 8h7g 7f7d 3d7d 7c7d P*2h P*8b 7i6h P*2b
info nps 20709 time 4106 nodes 85034 hashfull 8 score cp 187 depth 29 pv 2g2f 3c3d 7g7f 8c8d 2f2e 8d8e 6i7h 8e8f 8g8f 8b8f 2e2d 2c2d 2h2d 4a3b 2d3d 2b3c 5i5h 5a5b 3g3f 8f7f 8h7g 7f7d 3d7d 7c7d P*2h 3a4b R*8c R*8b P*7b
info nps 20737 time 4619 nodes 95785 hashfull 9 score cp 188 depth 30 pv 2g2f 3c3d 7g7f 8c8d 2f2e 8d8e 6i7h 8e8f 8g8f 8b8f 2e2d 2c2d 2h2d 4a3b 2d3d 2b3c 5i5h 5a5b 3g3f 8f7f 8h7g 7c7d 2i3g 8a7c 3g4e 3c7g+ 7h7g 7f7e P*2b P*2c
info nps 20703 time 5016 nodes 103849 hashfull 10 score cp 192 depth 30 pv 2g2f 3c3d 7g7f 8c8d 2f2e 8d8e 6i7h 8e8f 8g8f 8b8f 2e2d 2c2d 2h2d 4a3b 2d3d 2b3c5i5h 5a5b 3g3f 8f7f 8h7g 7f7d 3d7d 7c7d P*2h P*8b 7i6h 3a4b 7h7i P*2b
bestmove 2g2f

最後の行の bestmove 2g2f が最善手です。

独特の 符合 ですが、 2g2f は 初期盤面で 2七の駒を2六に動かすことを表し、 2六歩 のことです。

ソフトくんは振り飛車がお嫌いのようです。

初手から進んだ局面で検討したいときは、moves で駒の動きを指定します。

position startpos moves 7g7f 3c3d 2g2f 4c4d 2f2e
go byoyomi 5000

8. NPSの計測

dlshogi のコードベースには、様々な 局面で NPS(局面を読むスピード;node per second)を計測するためのスクリプト(dlshogi/utils/benchmark.py)が含まれています。

Python用将棋ライブラリの cshogi に依存しているため、インストールします。

$ sudo python3 -mpip install -U cshogi

usi バイナリーとモデルのパスを指定して、実行しましょう。

~/DeepLearningShogi/usi/bin$ cd ~/DeepLearningShogi/dlshogi/utils

~/DeepLearningShogi/dlshogi/utils$python3 benchmark.py \
  --gpus 1 --threads 3 \
  /home/ubuntu/DeepLearningShogi/usi/bin/usi \
  /home/ubuntu/model-dr2_exhi.onnx
...

9. AMI 化

dlshogi をインストールした EC2 インスタンスを AMI 化すると、横展開したり、スポットインスタンスの利用がかんたんになります。

インスタンスを選択後、「アクション→イメージ→イメージの作成」から AMI を作成してください。

最後に

dlshogi を Amazon EC2 の GPU 系インスタンスタイプにインストールする方法を紹介しました。

先人のおかげで、最低限の AWS/Linux 操作ができれば、導入はそれほど難しくありません。

手入力で USI プロトコルと通信するのは手間なため、GUI を用意するなり、プログラムから通信するなり、工夫してください。

それでは。

参考