SPSAにまつわる小話

今年の将棋AI界隈に起きた大きな革命としてSPSAの導入が挙げられる。

SPSAの手法については、以下の記事に簡単な説明がある。

SPSA、探索パラメーターの自動調整手法について

この手法を私が知ったのは、KaggleのチェスAIのコンペに参加したのがきっかけである。

Kaggleで高額賞金のChess AIのコンペが始まる

上のコンペは、チェスAIで競うのだが、メモリ制限がめちゃめちゃに厳しく、結局、古いバージョンのStockfishをいかに省メモリで動かすか、また省メモリで動かしつついかに強くできるか(なるべく新しいStockfishの改良をとりこめるか)という勝負であったと言っても過言ではなかった。

しかし、そのように部分的にStockfishの様々なcommitを取り込むと、探索の枝刈りなどのパラメーター(いわゆるハイパーパラメーター)が最適値からは外れていくので、自分で調整し直す必要がある。

その調整には、StockfishではSPSAが使われており、SPSAを実施してくれるfishtestというフレームワークが使用される。

https://github.com/official-stockfish/fishtest

このfishtest、サーバーに設置して、各自がworkerとなるマシンを(サーバーに対して)提供し、サーバー側はそれらのマシンを使ってA/Bテストやら、SPSAやらを行うのである。

コンペの終盤ぐらいになって、氷彗の作者の大森さんも誘ってチームに参加してもらうことになったが、大森さんも、このときにfishtest(SPSA)の洗礼を受けるわけである。

しかし、fishtestは、Windows環境でストレートに動かなかったり、GitHubのアカウントとの連携が必要であったりと、なかなかに使いづらいところがあった。

そのため、fishtestは、チームのメンバーから(特に私から)はすこぶる不評であった。

チームメンバーであるQhapaqさんは、「このコンペ終わったら今年(2025年)は、将棋AI用にこれを移植したいですね」などと言っていたが、私は、「こんなもんぐらい自作したほうがいいんじゃないっすか?」とfishtestの移植には極めて否定的であった。

私がfishtestに否定的であったのは、自作しても簡単だし、色々改良したいところがあったからである。

たとえば、SPSAでは、少しパラメーターを変異させて基準ソフトと2回対局させる。1回目に変異させる方向と2回目に変異させる方向は真逆にしておく。

こうして1回目と2回目とで、どちらが優れていそうかを知りたい。

このとき、2回とも引き分けだとか、2回ともプレイヤー1が勝ちだとか、2回ともプレイヤー2が勝ちだとかだと、どちらに変異させたほうが良いのか優劣がつかない。(ゆえに、このときパラメーターの変動をさせられない。)

まあ、引き分けはそんなに起きるわけではないので、いまないものとして考える。

そうすると、「2回ともプレイヤー1が勝ち」と「2回ともプレイヤー2が勝ち」というパターンが起こらないでほしいわけだ。

対局したときに、プレイヤー1がプレイヤー2に勝つ確率をpとする。

2回ともプレイヤー1が勝つ確率

$$ P_1 = p^2 $$

2回ともプレイヤー2が勝つ確率

$$ P_2 = (1-p)^2 $$

「2回ともプレイヤー1が勝ち」もしくは「2回ともプレイヤー2が勝ち」との確率は、この合計だから、

$$ P = P_1 + P_2 = p^2 + (1-p)^2 $$

これが最小となるpを求めたい。

$$ \frac{dP}{dp} = 4p – 2 , これが0となるのは、p=0.5のとき。$$

よって、Pが最小となるのは、p=0.5のとき。

ということで、プレイヤー1とプレイヤー2が同じ強さのときに、パラメーターの変動が起きる確率が最大となる。

だから、つねにプレイヤー1(パラメーターを調整している思考エンジン)とプレイヤー2(基準となる思考エンジン)が同じぐらいの強さになるように自動的にSPSAフレームワークがプレイヤー2の探索ノード数を調整してほしいわけである。

しかし、このようなことをfishtestはしてくれないので、自作したほうがいいなぁと思ったわけである。

そんなことを考えながらも、私はマシンの提供以外はあまりチームに貢献できずに、コンペを終えた。我々のチームは8位に入賞し、見事Kaggle金メダルを獲得した。ひとえにたぬきの開発者の野田さん(nodchip)のおかげである。

そうして、しばらくSPSAのことは忘れていたのだが、今年の夏に氷彗と水匠のエキシビションマッチ(YouTubeで行われた81番勝負)で、水匠がぼこぼこにされているのを自宅のPCで見ながら、これはやねうら王を大改修せねばなるまいと思った。これが後に言う「やねうら王2025年夏の大改修」である。

そのときにSPSAフレームワークを私は1日足らずで書いた。ここで、速くコードが書けたことを自慢したいわけではなく、対局フレームワーク自体は私はPythonですでに書いてあったので、それを少し改造するだけで書けたから1日足らずで済んだということである。だから、この結果から見ても私はfishtestを将棋用に移植しなくて良かったと思うわけである。

また、そのあと、氷彗の大森さんも氷彗にSPSAを導入された。(詳しいことは聞いていないので、SPSAフレームワークを自作されたのか何なのかは知らない)

そうして、今月開催された第6回世界将棋AI電竜戦の決勝では、1位が氷彗チーム、2位が私(やねうらお)が率いる水匠Concertoチームとなった。

第6回世界将棋AI電竜戦参戦記

Kaggleのコンペで同じ釜の飯を食った門下生たちが、時を経て、今度は大舞台で刃を交える。

結果は1位と2位。

少年漫画なら最終回にこそふさわしい胸熱展開だ。こんなドラマみたいな展開、現実であるんやなと思った。

そんなわけで、個人的には、今年の将棋AI界の三大ニュースには是非SPSAを入れていただきたい。

SPSAにまつわる小話」への3件のフィードバック

  1. 「「プレイヤー1が1回勝ってプレイヤー2が1回勝つ」というパターンだけが起こらないでほしい」というのは分かったのですが、その続きで

    「プレイヤー1が1回勝ってプレイヤー2が1回勝つ」確率は、この合計だから、
    P=P1+P2=2p(1−p)
    これが最大となるpを求めたい。

    となっているのは矛盾していませんか?Pは小さくしたいのではないですか?

    • この記事、本日オンラインで会議中に暇だったからこそこそ書いてたので、数式のところが盛大に間違っておりました。そのあと自ら間違いに気づいて修正致しました。
      (25日の23時には修正済み。ブラウザでリロードしないと古い記事が見えているかも…)

      いずれにせよ、御指摘、ありがとうございます。

      • 夕方ごろに後で読もうとタブで開いたままにしてたので、修正前の文章を読んでいました。

        コメント送信後、少ししてからリロードしたら、かなりの量の修正が入っていて「こんな遅い時間なのに、やねさん、すげぇ!(感嘆)」と思ってましたw

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です