dlshogiのインストールとモデルのトレーニングの実施

将棋AIを学習するにあたって、「強い将棋ソフトの創りかた・Pythonで実装するディープラーニング将棋AI」（以下テキスト）を参考にさせて頂いた。
このテキストの７章を、自分のPCのWSL2環境で再現してみる。

# ソースコードからビルドする。

WSL2の環境は、新規インストールをして、必要なNVIDIAのソフトウェア（CUDA Toolkit, cuDNN, TensorRT)をインストールした状態になっている。

## ビルド環境のダウンロード
テキストでは、dlshogiのバージョンは、0.1.1になっているが、最新版を利用する。

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


## ビルドに必要なモジュールを追加
Cythonを使って、C++で書かれている部分があるので、それをインストールする。

```
$ pip install cython
```

## ビルド

```
$ cd DeepLearningShogi
$ pip install -e .
```

以下、カレントディレクトリは、DeepLearningShogiとする。

これで、pythonのdlshogiモジュールがインストールされる。


# 棋譜データのダウンロード

テキストのGitHubリポジトリから、train.ipynbをGoogle Colabで開く。
ここで、GitHubのリポジトリURLを敢えて省略するが、再現したい方はテキストをぜひ購入してほしい。
また、Google Colabのアカウントも必要。

train.ipynbの中に、Googleドライブの共有リンクが指定されているので、そこから.hcpeファイルをダウンロードする。(dlshogi_with_gct-001.hcpe 等)

log, modelのフォルダはダウンロードの必要は無いが、作っておく。
```
$ mkdir log
$ mkdir model
$ mkdir data
```
./data にダウンロードした棋譜ファイルを保存する。

# トレーニングのためのシェルスクリプトを入手
テキストではトレーニングはGoogle Colabを使って行う前提で書かれており、そのためのスクリプトがシェルで書かれている。
そのスクリプトは、dlshogiには含まれておらず、先ほど開いたtrain.ipynbに入っているので、それをコピペして、train.shとしてカレントディレクトリに保存する。

ファイルは、改行コードはLFで、エンコードはUTF-8にすることに注意。

# トレーニングの実行

## 必要なモジュールをインストール

実行には、PyTorchとSciPyが必要

```
$ pip install torch torchaudio torchvision
$ pip install scipy
```

## ソースコードの修正
そのまま実行すると、
```
  hcpe3_prepare_evalfix()にて
　 __hcpe3_prepare_evalfix(ndeval.data, ndresult.data)の呼び出しで、
　TypeError: expected bytes, memoryview found
```
のような実行時エラーとなるため、以下のように修正。

```
./dlshogi/cppshogi.pyx: 56
def hcpe3_prepare_evalfix(str filepath):
        cdef size_t size = __load_evalfix(filepath.encode(locale.getpreferredencoding()))
        cdef np.ndarray ndeval = np.empty(size, np.int32)
        cdef np.ndarray ndresult = np.empty(size, np.float32)
        cdef char *p_eval = <char*> ndeval.data
        cdef char *p_result = <char*> ndresult.data
        #__hcpe3_prepare_evalfix(ndeval.data, ndresult.data)
        __hcpe3_prepare_evalfix(p_eval,p_result)
        return ndeval, ndresult
```

念のため、再度インストールしなおしておく。


```
$ pip install -e .
```

## トレーニング実行

ローカルのGPUを使用することになるので、それに応じたパラメータを設定する。
自分の環境は、RTX 4060 Ti (16G)なので、テキストに書かれている、K80以外という設定で問題ない。
AMPを有効
バッチサイズは4096
メモリの使用量が11GB程度なので、バッチサイズはもう少し大きく出来るかも。

まずは、とりあえず、試験的に1 epochのみ実行してみる。

```
$ ./train.sh 1 --lr 0.01 --batchsize 1024 --eval_interval 100
```
これで、問題なければ、modelにファイルが作成され、logにログファイルが作成される。
次に、本番実行であるが、 --use_ampオプションを使って続けようとすると以下のようなエラーが出る。これは、modelファイルを削除すればよい。
```
Traceback (most recent call last):
  File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/mnt/d/dlshogi/DeepLearningShogi/dlshogi/train.py", line 363, in <module>
    main(*sys.argv[1:])
  File "/mnt/d/dlshogi/DeepLearningShogi/dlshogi/train.py", line 130, in main
    scaler.load_state_dict(checkpoint['scaler'])
  File "/home/okuno/.local/lib/python3.10/site-packages/torch/cuda/amp/grad_scaler.py", line 632, in load_state_dict
    raise RuntimeError(
RuntimeError: The source state dict is empty, possibly because it was saved from a disabled instance of GradScaler.
```


```
rm -f ./model/*
$ ./train.sh 72 --lr 0.04 --batchsize 4096 --use_amp
```

自分の環境では、トレーニングに二日近く掛かった。

以上