o-jill / ruversi

reversi program.
https://o-jill.github.io/ruversi/
1 stars 0 forks source link

学習の高速化(SIMDじゃなくて) #78

Open o-jill opened 1 year ago

o-jill commented 1 year ago

ある局面を学習するためには、forwarding(順伝搬)とbackwarding(逆伝搬)をする必要がある。 これをなんとかして高速に実行する方法を考えたい。

例: w1で順伝搬 逆伝搬でw1を更新、w2になる w2で順伝搬 逆伝搬でw2を更新、w3になる 。。。

o-jill commented 1 year ago
o-jill commented 1 year ago
学習時間の例
real 109m48.141s
user 107m11.096s
sys 2m29.153s

完全にシングルスレッド。 ファイルI/Oはこれ以上減らせない気がするので何かを別スレッドに移す必要あり。

o-jill commented 1 year ago
o-jill commented 1 year ago

案5をやってみた。 1.5s/batchが2.15s/batchになった印象。 問題はStringのコピーか、mpscのやり取りか。 (rfen, score)の配列をGlobalで確保しておけばちょっとは速くなる? 学習中にシャッフルするつもりだったけどそうなっていない可能性あり。。。 → 学習スレッドからの応答を待って対象RFENを送るべし。 それでも大して変わらない気がするので、RFEN配列のGlobal化+mpscはインデックスを配列で渡すのが良いと思われる。 →それでも大して変わらなかった。結構良さげで1.5s/batch : 1.55s/batch。global化でどうか?

o-jill commented 1 year ago

repeat200で20回ずつ計測してみた。ウェルチのt検定。

unit before after p
sec/200repeat 13.3±0.56 12.8±0.40 0.3% < 5%
msec/batch 69.55±1.87 66.22±1.32 0.0% < 5%
o-jill commented 1 year ago
o-jill commented 1 year ago
o-jill commented 1 year ago
o-jill commented 1 year ago
o-jill commented 1 year ago
o-jill commented 1 year ago

backwardは分割できそうな気がしてきたけど、forwardは今まで通り計算しないといけないんじゃないか疑惑。 思ったより高速化しないかも。

o-jill commented 1 year ago

分割するには、 trainer::learn() -> weight::training() -> weight::learnbb() x2 -> weight::forwardv3bb(), weight::backwardv3bb() を分断する必要があるようだ。。。

o-jill commented 1 year ago

とりあえずlearnbb()weight::forwardv3bb()weight::backwardv3bb()を呼んでるだけなので要らないかもしれない。

o-jill commented 1 year ago

スレ分けするならこんな感じかな?コスト(データ渡しなどの時間)に見合わない気がしている。backwardの処理時間が伸びれば効果も出そうだが。。。

o-jill commented 1 year ago

backwardv3bbを二分するのは #82 でやって失敗している模様。

o-jill commented 1 year ago

学習(--learn)と評価(--duel)で、duelを2個同時に実行するのはあまり効果が無さそうに見えている。 学習率ごとにスクリプトを分けて実行するのはどうか? スクリプトAではeta=0.1, 0.05, スクリプトBでは0.01と0.001など。 評価は順番に今まで通りやる。 学習時の並列化があまり効いていない(ほぼシングルスレッド)ので、時間的にはこっちのほうがいいかもしれない。 スクリプトAとBでフォルダを分ける必要があるので注意。途中経過のファイルが上書きされちゃう。 今までのやり方では1,000min(sys60min)ぐらいだった。

o-jill commented 1 year ago

2フォルダ作戦をやってみた。 ついでに仮想環境のCPUの割当がEコアだったので設定を変えてPコアで動くようにした。 400min弱 x 2で終わるようになった。Pコアにした影響もありそうな気がするので一概に2フォルダ分にした影響で半分になったわけではないと思う。 ともかく効果はありそう。

o-jill commented 10 months ago
  • 案9 最後12手分ぐらいを読み切れるので終盤の学習はいらないのではないか? 学習する局面数が減るのは良いことなのか悪いことなのか。

絶対に最終局面は学習しなくてもいい。 昔その判定を入れたけどバグっているようだ。。。 現在midはゼロで運用されていて、すなわち最終局面も学習している模様。

@@ -2281,19 +2281,19 @@ impl Weight {
     /// - `rfen` : RFEN
     /// - `winner` : winner or # of stones.
     /// - `eta` : learning ratio.
     /// - `mid` : last (mid) moves will not be used.
     /// 
     /// # Returns
     /// - OK(()) if succeeded.
     /// - Err(String) if some error happened.
-    pub fn train(&mut self, rfen : &str, winner : i8, eta : f32, mid : i8)
+    pub fn train(&mut self, rfen : &str, winner : i8, eta : f32, mid : u32)
              -> Result<(), String> {
         if cfg!(feature="bitboard") {
             let ban = match bitboard::BitBoard::from(rfen) {
                 Ok(b) => {b},
                 Err(e) => {return Err(e)}
             };
-            if ban.count() > 64 - mid {return Ok(());}
+            if ban.nblank() < mid {return Ok(());}

             self.learnbb(&ban, winner, eta);
o-jill commented 9 months ago

最終10手分は学習しないみたいだけど多分これはあまり良くない。最後の局面は学習不要。< 10じゃなくて< 1かな?

    pub fn learn_stones_para_rfengrp(&mut self) {
...
                // 最後数手は読み切れるので学習しなくて良い
                if bitboard::count_emptycells(&rfen).unwrap() < 10 {
                    continue;
                }
                unsafe {RFENCACHE.push((rfen, score));}
o-jill commented 9 months ago

120 は学習の高速化なのか???

o-jill commented 7 months ago

ミニバッチを取り入れますか? 今はオンライン学習状態だと思っている。(1rfenで1回更新) 例えば、10rfenごとに差分→平均→更新とやってみるとどうなるか? ミニバッチの中では同じ重みを使えば良いのでスレ分けができるのかな?(速くなる?) 10個のバックプロパゲーションした結果(差分でも重みでも)を足して10で割ったものが1ミニバッチの結果?

o-jill commented 7 months ago

多スレ版ミニバッチ案 実は1スレでもLockしないだけと言う説。

lock時に一度にlockしてN個の局面分を書いた方が速そう。10回lockしてると遅そう。そこまで評価関数は大きくないのでスレごとに結果領域を確保して全部終わったら結果をlockして出力が良さそう。

o-jill commented 7 months ago

ミニバッチ学習についてはこちらへ #130

o-jill commented 1 month ago

学習関連はすべて :octocat: o-jill/tigerdenversi へ移行。