サーバーレス将棋 AI ☖

いま将棋界では、良くも悪くも AI の話題が事欠きません。AI は日進月歩で強くなっており、トップレベルの AI は既にプロ棋士と互角以上に戦えるという見方が強いようです。
今回はオープンソースで公開されている将棋 AI  [「技巧」](https://github.com/gikou-official/Gikou) を、API Gateway + Lambda で Web API 化しました。
技巧は 2016 年の世界コンピュータ将棋選手権で準優勝した将棋ソフトで、GPL ライセンスで公開されています。

# API

```
GET https://17xn1ovxga.execute-api.ap-northeast-1.amazonaws.com/production/gikou?byoyomi={探索時間 (ms)}&position={局面の SFEN 表記}
```

パラメータ:

```
position: 局面の SFEN 表記 (AI 用の局面フォーマット)
byoyomi: 探索時間 (ms)
```

# DEMO

執筆時点での昨日 (2016/12/1) から行われている [『第29期竜王戦七番勝負 第５局 渡辺明竜王(後手) 対 丸山忠久九段(先手)』](http://live.shogi.or.jp/ryuou/kifu/29/ryuou201612010101.html) の封じ手予想をしてみます。

![局面](https://s3-ap-northeast-1.amazonaws.com/naoys.public/%E7%AC%AC%EF%BC%92%EF%BC%99%E6%9C%9F%E7%AB%9C%E7%8E%8B%E6%88%A6%E4%B8%83%E7%95%AA%E5%8B%9D%E8%B2%A0%E3%80%80%E7%AC%AC%EF%BC%95%E5%B1%80_%E6%A8%AA%E6%AD%A9%E5%8F%96%E3%82%8A%E2%96%B3%EF%BC%93%E4%B8%89%E8%A7%92%E5%9E%8B.png)

この局面で後手の渡辺竜王が封じ手をしました。後手は画面上から下に向かって攻める側です。どんな手が予想できるでしょうか。ちなみに解説棋士の予想は「△４四角、△５四歩、△１五角あたり」だそうです。

この局面を AI 用の表記、SFEN 表記 (詳しくは [USIプロトコル](http://www.geocities.jp/shogidokoro/usi.html) を参照) で表すと、

```
sfen lr5nl/2g1kg1s1/p1npppbpp/2ps5/8P/2P3R2/PP1PPPP1N/1SGB1S3/LN1KG3L w 2Pp 1
```

となります。探索時間 10 秒 (= 10000ms) で API に問い合わせてみましょう。

https://17xn1ovxga.execute-api.ap-northeast-1.amazonaws.com/production/gikou?byoyomi=10000&position=sfen%20lr5nl/2g1kg1s1/p1npppbpp/2ps5/8P/2P3R2/PP1PPPP1N/1SGB1S3/LN1KG3L%20w%202Pp%201

10 秒くらいで結果が返ってきます。

```
{
  "request": {
    "byoyomi": "10000",
    "position": "sfen lr5nl/2g1kg1s1/p1npppbpp/2ps5/8P/2P3R2/PP1PPPP1N/1SGB1S3/LN1KG3L w 2Pp 1"
  },
  "bestmove": "3c1e",
  "bestpv": {
    "pv": [
      "3c1e",
      "6g6f",
      "1e2d",
      "8i7g",
      "P*3e",
      "3f2f",
      "2d1e",
      "2f2h",
      "3e3f",
      "3g3f",
      "1e3c",
      "5g5f",
      "3c6f",
      "P*6e",
      "7c6e",
      "7g6e",
      "6d6e",
      "8h7g",
      "6f4d"
    ],
    "raw_string": "info depth 19 seldepth 24 time 9903 nodes 3415330 nps 344878 hashfull 31 score cp 23 multipv 1 pv 3c1e 6g6f 1e2d 8i7g P*3e 3f2f 2d1e 2f2h 3e3f 3g3f 1e3c 5g5f 3c6f P*6e 7c6e 7g6e 6d6e 8h7g 6f4d",
    "depth": 19,
    "seldepth": 24,
    "time": 9903,
    "nodes": 3415330,
    "nps": 344878,
    "hashfull": 31,
    "score_cp": 23,
    "multipv": 1
  },
  ...
```

### 「△１五角」

AI の選んだ手は `"bestmove": "3c1e"` で表されています。3c の角 (右から 3 列目、上から 3 行目の角) を 1e (右から 1 列目、上から 5 行目) に移動する、「△１五角」が AI の選んだ手です。

![△１五角](https://s3-ap-northeast-1.amazonaws.com/naoys.public/%E7%AC%AC%EF%BC%92%EF%BC%99%E6%9C%9F%E7%AB%9C%E7%8E%8B%E6%88%A6%E4%B8%83%E7%95%AA%E5%8B%9D%E8%B2%A0%E3%80%80%E7%AC%AC%EF%BC%95%E5%B1%80_%E6%A8%AA%E6%AD%A9%E5%8F%96%E3%82%8A%E2%96%B3%EF%BC%93%E4%B8%89%E8%A7%92%E5%9E%8B+2.png)

### ひとにらみ 300 万手

`"depth": 19` と出ているとおり、19 手先まで探索できたようです。「△１五角」以降の読み筋は `"bestpv"` で表されています。△１五角▲６六歩△２四角▲７七桂△３五歩▲２六飛△１五角▲２八飛△３六歩▲同歩△３三角▲５六歩…と続きます。

`"nodes": 3415330` は探索した局面数です。コンピュータは全探索なので人間と比べる意味はありませんが、10 秒で 300 万局面読めるというのは恐ろしいです。

### 評価値

`"score_cp": 23` は先手から見た局面の評価値で、歩 1 枚の価値を 100 とした値です。評価値 23 なので、 AI は歩 1 枚分の優劣もついていない互角の局面と評価しているようです。

### 答え合わせ

この記事は予約投稿なので、既に実際に指された手が [中継されているはず](http://live.shogi.or.jp/ryuou/kifu/29/ryuou201612010101.html) です。当たってるかな？

(2016/12/02 追記) [竜王戦中継plus | 封じ手開封](http://kifulog.shogi.or.jp/ryuou/2016/12/post-91fc.html)
実際の封じ手は「△５四歩」でした。対局室の雰囲気はいつ見てもカッコイイですね。 今回は 10 秒の探索でしたが、探索時間を長くしたり実行環境を変えることでまた別の結果が出るかもしれません。

# アーキテクチャ

API のアーキテクチャは下図のような感じです。

![アーキテクチャ](https://s3-ap-northeast-1.amazonaws.com/naoys.public/serverless.png)

要点は、AI を Lambda で動かすために静的ビルドをすること、Lambda の容量制限を回避するために S3 を利用することです。

### 静的ビルド

バイナリを Lambda で実行するには、静的にビルドされている必要があります。技巧のコンパイルオプションを変更して、AI の依存ライブラリを静的に解決できるようにしました。

https://github.com/na-o-ys/gikou-docker/tree/master/builder

このバイナリを Alpine Linux にパッケージングした Docker イメージも公開しています。

https://hub.docker.com/r/naoys/gikou/

### Lambda

https://github.com/na-o-ys/serverless-shogi

技巧の実行に必要な学習済み評価関数バイナリは 250 MB あるので、Lambda に含めることができません (50 MB 制限)。そこで、Lambda の実行時に S3 から取ってくる形にしました。S3 から Lambda の稼働コンテナにファイルをダウンロードするのに、3 ~ 5 秒のオーバヘッドがあります。
ただし、Lambda は間隔が開かなければコンテナが再利用されるので、その場合はこのオーバヘッドはありません。

# 今後の展望

今回は Lambda + API Gateway を利用して将棋 AI のサーバーレス API を作りました。Lambda の利点として、待機コストがかからないこと、タスクの同時実行が可能なことがあります。個人でも低ランニングコストでサーバサイドで動かせるっていうのは大きいです。今後は React なんかで良い感じの Web GUI を作って、プロの棋譜中継や [将棋ウォーズ](https://shogiwars.heroz.jp/) の棋譜を解析・結果表示できるようにしようと目論んでいます。