TadaoYamaokaの開発日記

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

麻雀AIを深層強化学習で作る その9(自己対局)

前回は、牌譜の記録/再生処理を実装した。
今回は、自己対局で牌譜を生成する処理を実装する。

処理方式

強化学習アルゴリズムにPPOを使用予定で、PPOはオンポリシーのアルゴリズムのため、

  1. 現在のモデルで牌譜生成
  2. 現在のモデルで生成した牌譜でモデルを学習
  3. モデルのバージョン更新

というサイクルをシーケンシャルに繰り返す。

プログラム構成

プログラムは、牌譜を生成するActorと、モデルを学習するLearnerで構成する。
Actorは、処理速度を考慮して、C++で実装する。
Learnerは、PyTorchで学習を行うのでPythonで実装する。

Actorは複数プロセスで分散して実行できるようにする。

ActorとLearnerの同期

一定数の牌譜が溜まったら、Actorは生成を停止し、Learnerが学習を開始して、モデル更新後、Actorを再開するという処理の流れを、ActorとLearnerを同期させて行う必要がある。

プロセス間の連携をMySQLやRedisなどのデータベース経由して行う方法も考えたが、構成をシンプルにするため、ファイルで連携する方式とする。

それぞれのActorとLearnerをできるだけ独立して動作させるために、以下のような処理方式とする。

  1. 各サイクルごとにイテレーション番号をディレクトリ名としてディレクトリを作成する
  2. ディレクトリ内に、モデルを配置する
  3. ディレクトリ内にstartファイルを配置する
  4. Actorは、ディレクトリにstartファイルが存在したら、モデルを読み込み処理を開始する
  5. Actorは、定期的に牌譜をディレクトリに出力する
  6. Learnerは、ディレクトリを監視し、一定数の牌譜が溜まったら、stopファイルを配置し、学習を開始する(監視中に牌譜の前処理を行っておく)。
  7. Actorは、ディレクトリにstopファイルが存在したら、処理を停止する。
  8. Learnerは、学習が完了したら、次のイテレーションディレクトリを作成し、モデルを配置し、startファイルを配置する。

このようにすることで、各ActorとLearnerは、ディレクトリ内のファイルを確認するだけで、それぞれ独立して処理できる。

Actorの実装

前述した通りActorは、C++で実装する。
推論ライブラリには、TensorRTを使用する。

並列処理

1プロセスが1GPUを使用するようにして、プロセス内では2つ以上のスレッドで、ゲームの進行とGPU推論を行い、1つのスレッドがGPUで推論中に別スレッドがゲームの進行を行うようにしてGPUの利用効率を上げる。
各スレッドでは、複数のゲームを並列で実行し、複数のゲームのエージェントのアクションをバッチで推論する。
麻雀は4人対戦のため、各ゲームには4つのエージェントが存在する。
副露では、最大3人が同時に行動するため、バッチサイズは、最大で並列ゲーム数×3になる。

まとめ

自己対局で牌譜を生成する処理を実装した。
分散環境で、できるだけActorとLearnerが独立して処理できるシンプルな方式を検討した。
次は、学習の処理を実装したい。