棋譜からの学習時に結構メモリを必要とするのは深刻な課題です。何故なら、メモリの許す限り大きな評価関数(パラメーターの数がたくさん!)にしたいのですが、棋譜からの学習時には、その評価関数のパラメーターのサイズの10倍〜20倍ぐらいのメモリを必要とするからです。
そこで、今回はそれを力技でなんとかする方法を紹介します。
まず、学習時に必要なメモリ、例えば、パラメーターの勾配を記録しておくところはread-modify-writeは不要なので、シリアルにファイルに書き出してしまいます。
例えば、仮想メモリ、address = 0x1234に対して値を+1するという情報を書き出したいのであれば、この仮想メモリに対するメモリブロック(例えば0x0000〜0xffffまでを一つのメモリブロックとして)に対応するファイルにその情報をシリアルに書き出します。
つまり、
0x0000〜0xffff_append.txt
みたいなファイルに対して
0x1234 +1
のようにテキスト形式で書き出してしまいます。
そのあと、学習のphase2(パラメータの更新)のときに、この0x0000〜0xffffまでの前回のメモリ情報を格納したファイル
0x0000〜0xffff.bin
をメモリに丸読みして、
0x0000〜0xffff_append.txt
の内容を反映させ、また
0x0000〜0xffff.bin
に書き戻しておきます。(そのあと0x0000〜0xffffの情報を用いたパラメーターの更新処理を行ないます)
これを仮想メモリを受け持つすべてのファイルに対してこの更新処理を行ないます。
このように、ファイルを使って仮想メモリを実現することで、SSDの容量の半分ぐらいのメモリがあるかのように振る舞うことが出来ます。2TBのSSDが10万円ぐらいで買えますから、1TBのメモリがあるかのように棋譜からの学習を行なうことが出来ます。
オーバーヘッドはありますが、 多少遅くともメモリ不足で学習出来ないよりは断然マシなのでこういうソリューションもありますよ、ということで。(今回の電王トーナメントには間に合わないでしょうけども…)
電王戦が近づいてきてブログも活発ですね
楽しく読ませてもらってます!
ここ最近の記事を見ると、強さを追求するとどうしても巨大な関数とかデータベースが必要なのですかね。(チェスプログラムのwiki眺めた程度の感想ですがw)
個人的には日本人の美意識というか、禅のミニマリズムを感じさせる小型のプログラムも見てみたいなぁと思いまして。
多少ハマってしまう局面の発生は度外視するとして、実用に耐えうるレベルで小型化(スマホやタブレット、モバイルPC向け)することって現時点だとまだ難しそうな雰囲気ですか?
プログラマーの方からすると興味をそそられないのかなぁ。。。
スマホでもミドルレンジのものならメモリ1GBぐらいは載ってますから、評価関数少し調整すれば(去年の電王戦出場の5ソフトは)どのソフトでも動きますね。そしてPonanzaはスマホで動かしても平均的なプロぐらいの強さはあると思いますよ。
最近メモリに関する問題を見るようになってきましたね。
昔は256MBあれば十分だと思ってたものですが。
そこで、以下のようなソリューションがあります。
http://pc.watch.impress.co.jp/docs/column/semicon/20150819_716850.html
SSDより高つくでしょうけど未来にはこういう道もあるということのようです。
ビッグデータが叫ばれてだいぶん立ちますが、そろそろ現実的な解が出始めてきたのでしょうかね。
しかし、将棋ソフト開発でメモリ不足になるとは思いませんでした。
データよりロジックだと思ってたので。
> SSDより高つくでしょうけど未来にはこういう道もあるということのようです。
3D XPointと競合してそうな?DDR4の半分ぐらいの速度でも出れば嬉しいですが…。(3D XPointのほうは1/10ぐらいの速度しか出ないようです..)
3DXPOINTも同類技術かと思います。
速度に関しては、DRAMキャッシュをいくらか積んでいればどうにかなるレベルだと詠みました。
SSHDのような感じですね。
せっかくDIMMソケットに差すのだから速度も重視してほしいのは確かに人情。
ビッグデータがもうちょっとピーキーになったら技術も必需で伸びていくのでしょうかね・・・。
コンピュータ軍人将棋の開発待ってます!!
mmap()を使わないのは何故?
writeがrandom accessになる状況においてはmemory mapped fileのようなものはパフォーマンス的に全く使いものにならないからです。