将棋AI界に激震が走った。finny tablesという発明が将棋AIに持ち込まれた。詳しいことは下記のページを見てほしい。
NNUE performance improvements
https://asteri.sm/files/2024-06-01-nnue#bucket-accumulator-caching-or-finny-tables
finnyは意味のある英単語ではなく、発明者の名前に由来するようである。技術的には、Accumulator Cachesと呼ばれる。
本記事では、finny tablesが何なのか簡単に解説し、これがどれだけ大きなインパクトがあるのかを説明する。
まず、現在将棋AIの評価関数と言えば、NNUEである。
このアーキテクチャの解説は、下記のWCSC28の時のPR文章に詳しい。(PDF注意)
https://www.apply.computer-shogi.org/wcsc28/appeal/the_end_of_genesis_T.N.K.evolution_turbo_type_D/nnue.pdf
現在は、これがチェスのAIであるStockfishに取り込まれ、そしてStockfishの開発チームによって、より洗練された形になり、SFNN(StockfishNNUE)という形で、やねうら王に逆輸入されている。詳しくは、Stockfishの下記のドキュメントに詳細の解説がある。
Stockfish Docs — NNUE
https://official-stockfish.github.io/docs/nnue-pytorch-wiki/docs/nnue.html
しかし、本質的には、冒頭のNNUEのアーキテクチャとさほど変わらない。そこで、冒頭のNNUEのアーキテクチャを、finny tablesの説明のために大幅に簡略化した図を用意した。

左端の水色で書かれたところが入力で、右端の紫で書かれたところが出力である。
入力として、KPを入力して、出力として評価値が出てくる。
halfKPと書かれているが、今回は「half」の部分に関する説明は、本題と関係ないので割愛する。KPだと思ってほしい。
KPとは、K(玉の位置)とP(各駒種類×盤上・手駒)の組み合わせだ。125388種類ある。これを入力する。しかし、将棋の駒は平手だと40枚しかない。入力は、(ベクトルで言うと)125388次元あるものの、その(玉を除いた)38枚の駒に対応する要素のところだけが1になり、残りは0である。非常に疎な二値ベクトル(sparse binary vector)である。だから、この38枚分だけしか計算しなくて良い。残りは0なのであるから。
それで、赤で囲った部分は、FT(feature transformer)と呼ばれる。入力特徴量を変換する部分だ。緑色で書いたように「全結合」である。1024(これはFT層の出力ユニット数)と書いてあるが、これは最新版の水匠(水匠11Plus)の評価関数アーキテクチャがこうなっているという数字で、その時々で変わる。
NNUEの最大の特徴でもあるが、FTは差分更新(incremental update)が可能である。このことをまず説明する。
探索中に1手進めるときに、動いた駒に関してだけ入力特徴量を変更すればいい。歩を86から85に移動させたなら、入力特徴量のうち、86の歩を削除(1から0にもどす)して、85に歩を追加(0から1に変更)すればいい。つまり、歩が86から85に移動した場合、FT層は、(1024回の減算と1024回の加算で)2048回の加減算で更新ができるということである。(駒を捕獲した場合、その駒を手駒に移動させる必要があるので、さらに2048回の加減算が必要。)
また、FT層以降は差分計算不可能なので愚直に 1024×8,8×64,64×1回の積和計算が発生する。
前置きが長くなった。
それで問題なのは、入力特徴量が、KPということである。K(玉)とP(玉以外の駒)との組み合わせであるために、K(玉)が移動になったときは、例えば、「78の玉と86の歩 の組み合わせ」であったものが、「88の玉と86の歩 の組み合わせ」というように、すべての入力特徴が変化した扱いになってしまうのである。
ということは、このときだけ直前局面からの通常の差分更新が使えず、通常の1駒移動では2個の入力特徴を更新すれば済むのに対し、玉が動いた場合は38個分を計算する必要があるため、おおよそ19倍のコストがかかる。これを「全計算」と呼ぶ。
この問題は、NNUEに限らず、Kが絡む特徴量を入力特徴量として用いる評価関数すべてにおいて関係してくる。古き時代にあった三駒関係(KPPTなどと呼ばれる)でも同様である。
この「全計算」を避けられるかどうかが長年の課題だった。
全計算をしたくないので、halfKPを入力特徴量にせず、Kを含めたPだけを入力特徴量にするというアーキテクチャもあった。(NNUE KPアーキテクチャと呼ばれる)
しかし、halfKPを入力特徴量にする場合に比べて、R50~100ぐらい弱くなる。そのため、主流にはならなかった。
それで、今回、将棋AIに持ち込まれたfinny tablesは、この全計算を避けるためのアイデアである。
探索中に表れた81マスそれぞれのKに対応するFTの状態をcache(保存)しておく。
Kが移動したとき、そのKに対応してcacheされている過去の局面と現在局面を比較し、両局面で異なっている入力特徴の差分だけ計算してFT層の出力を用意する。そうすると全計算よりは軽くて済む。
これにより劇的に高速化された。NNUEの推論部は30%~50%ぐらい高速化され、NPS(1秒間の探索局面数)も15%程度高速化された。
これだけ高速化されるならば、FT層の1024の部分をもっと大きくして評価の精度を上げたほうが良いだろう。
いままで最適だと思われていたアーキテクチャが突然最適ではなくなった。大事件である。学習やりなおし、最適アーキテクチャの再検討が突然始まった。
また従来、全計算が重すぎるからと切り捨てられたアーキテクチャが復活する可能性も出てきた。
そして、将棋AI以外のAIでも、NNUEのような差分更新型評価関数では、この技法が使える可能性が出てきた。
このため、将棋AI界隈、その周辺界隈では、いまお祭り騒ぎになっている。