[開源] 一個分散式中國象棋 Alpha zero

icybee發表於2019-02-27

先上程式碼 github,這個專案現在仍然在積極開發和維護的階段,通過這個專案你可以組建自己的叢集並且訓練自己的中國象棋 alpha go:

icyChessZero

中國有 13+億人,中國象棋的受眾也很廣,但是有關中國象棋 alpha go/zero 方面的開源專案其實並不多,國內有名的更是幾根手指都能數過來,而且在內容上高度相似,都是使用 alpha zero 的網路 + alpha go 的訓練方式,列舉兩個相對突出一些的:

  • 佳佳 zero: 是一個團隊在維護,把 Leela Zero(一個國際象棋 alpha zero 專案) 遷移來做中國象棋的專案,目前就 elo 分來說是最強的,有那麼一丟丟商業化趨勢
  • cczero: 幾乎只有一個人在維護程式碼,同樣是一個民間自發組成,維護的中國象棋專案,目標是最強開源專案

這兩個專案都是比較棒的,那麼為什麼我還要自己寫一個呢?這就要從更早說起了
早在 alpha go 出來之後,alpha zero 出來之前,我就有要用神經網路來做中國象棋的想法,不過那個時候其實大家都不太知道怎麼做這個東西,畢竟象棋和圍棋很不一樣,我當時寫了一個比較幼稚的網路,希望單純通過一個網路,不加任何類似蒙特卡洛的演算法來通過預測人類落子規律的方法來,畢竟在圍棋中一個單純的策略網路就可以達到業餘幾段的棋力水平,我追求的也並不是天下第一,業餘幾段對於我來說,很 ok。

當時寫爬蟲爬了很多國內比賽棋譜,包括了很多我們耳熟能詳的象棋大師的比賽,然後開始自己訓練一個網路來預測人類的落子:

這個是我當時實現的那個很 naive 的網路程式碼:

icyElephant

圖 1. 兩個網路分別負責選子和落子

我當時的方法是使用 2 個網路來預測人類的一步,一個叫做 select 網路(圖 1 中的網路 1 )負責預測人類會移動哪個子,另一個叫 move 網路,負責預測移動的子落子點在哪裡,對比 alpha zero 的方法,alpha zero 使用一個網路就完成了兩個工作:

圖 2. Alpha zero 方法,一個網路預測選子和移動子的笛卡爾積

從直覺上來說,似乎先預測選子,再預測落子的網路邏輯更符合人類的思考過程,然而這兩個網路,在實際使用真實對局資料訓練時準確率相差非常小:

[開源] 一個分散式中國象棋 Alpha zero

並且我當時的方法( select-move 網路)不適合用在蒙特卡洛樹搜尋中預測每個走法的概率,所以後來在寫 icyChessZero 的時候也是用了 alpha zero 的策略網路的形式。在訓練完這個網路之後,我發現,雖然象棋走法預測的準確率也不算很低,但是單純和這個預測走子的網路對弈,我發現這個網路雖然開局有模有樣,但是一旦到了中局和殘局,網路經常作出匪夷所思的送子行為,這個現象我認為是因為圍棋和象棋的差異性造成的,由於圍棋的局勢更適合直接從棋盤評估(所謂的“勢”),而象棋則更多涉及邏輯推理。

到這一步為止,其實還是有很多專案都可以做到,比如說之前知乎有一篇系列文章:

ENG Bo:28 天自制你的 AlphaGo

叫 28 天自制 alpha go 的文章(雖然這個系列文章後來太監了,作者賣燈去了,估計是因為算力不夠),但是再往下做的話,其實是有一定門檻的,使用蒙特卡洛樹進行子對弈,並且進行神經網路的增強學習訓練,需要巨大的算力,這個門檻,其他的開源專案一般是通過眾籌訓練的方式解決的,比如 cczero 和佳佳 zero,但是有越過這個門檻的,也就有沒越過這個門檻的,比如之前知乎上的另一個專案:

程世東:AlphaZero 實踐——中國象棋(附論文翻譯)

這個專案就因為訓練增強學習所需要的巨量資源所限制,雖然程式碼寫出來了,但是因為算力不夠,作者在燒了幾百美元之後只能作罷。

那麼我是怎麼面對這個問題的呢?我利用了我在校生的身份,把手深到了我能夠到的每一臺 gpu 機器,求爺爺告奶奶的搞到了四五臺機器,組了一個叢集,雖然仍然算力不夠,但是至少可以開始訓練了。

想要從根本上解決這個問題,只能用巨量的算力,但是我們也能通過一些提高效率的方法來緩解一些這個問題,一些常用的方法比如:

  1. 使用 c/c++ 加速程式碼
  2. 使用多程式同時跑多個網路的前向
  3. 使用協程來將多個前向組成 batch,提高 gpu 利用效率
  4. 使用協程 /多程式的蒙特卡洛樹演算法,提速蒙特卡洛樹的搜尋速度
  5. 使用多臺機器分散式跑棋譜,利用更多 gpu

除了 C/C++加速的方法我還沒有使用,其他的方法我都使用了,細節參考:

深入理解 alpha go 的方法並應用到中國象棋

在實現了使用蒙特卡洛樹搜尋走子的功能之後,我讓監督學習的網路 和 監督學習+蒙特卡洛樹的兩種演算法進行了對戰,結果如下:

[開源] 一個分散式中國象棋 Alpha zero

在 29 盤對局中,蒙特卡洛樹一盤都沒有輸,平的 5 局都是超出當時的步數限制( 100 步,為了節省時間)判和的,判和時無一例外都是 mcts 優勢。這明確證明蒙特卡洛樹能夠有效提升 policy 網路的棋力。

這個專案原理簡單,但是實現起來全是邏輯,我從三月(存疑)開始寫,一直沒時間寫,斷斷續續的寫,5 月跑了幾天,出了一些 bug,後來一堆事情又湧上來,這專案就又擱置了起來,到 7,8 月,我意外的發現終於又有一些時間了,於是終於,我完成了我的中國象棋 alpha go zero 的第一版。

然後開始了漫長的訓練過程,由於我的算力非常有限,到目前為止也只是一個 4,5 臺 gpu server 的叢集在訓練這個版本的 alpha zero,我一開始的評估結果是以實驗室的資源大概至少 10 年能跑出來吧,後來隨著計算越來越精確,我發現在短短一年,甚至半年之內完成訓練是很有可能的(我的目標只是達到中上人類水平,由於收到算力和時間的限制),但是一臺機器肯定不夠,需要有很多機器,於是我寫了分散式版本,甚至花了一週時間重構了很多程式碼,這次重構以後一些 bug 莫名其妙的消失了,elo 曲線總算開始正常上升。

[開源] 一個分散式中國象棋 Alpha zero
[開源] 一個分散式中國象棋 Alpha zero

ps 一句:如果你在北郵有閒置的 GPU 伺服器的許可權,又有意願加入叢集一起訓練,希望能夠聯絡我

我認為,並不是只有訓練出一個最強的網路才是有價值的(當然如果有資源能夠訓練最強的我也不介意 [手動捂臉] ),探究在這個訓練過程中的優化點,考究 alpha zero 這個強化學習過程中是否有不合理的地方,這些都是有價值的。

這次開源的程式碼同時包含了叢集 master 和 slave 的程式碼,一個組建叢集的 minimal sample 我已經上傳到了 google drive:

colab.research.google.com/drive/1sC-g…

這個 minimal sample 可以直接用 google colab (免費)執行,只要把這個檔案存到自己的 google drive 之後用 colab 開啟就行(注意開啟 gpu 加速):

[開源] 一個分散式中國象棋 Alpha zero

在 google colab 中執行這個 minimal sample 的所有程式碼,應該能夠看到類似下面的結果,說明一個隨機的權重已經被初始化並且用於蒙特卡洛樹的子對弈:

[開源] 一個分散式中國象棋 Alpha zero

根據其他專案的進度和情況,想要達到我的小目標應該需要 4000 ~ 5000 elo 的分數,現在這個專案已經達到了 700elo 左右的分數,所以達到目標並不是不可能的。

另外這個專案參考了很多同類專案的實現,比如:

zhuanlan.zhihu.com/p/34433581

cczero.org/

github.com/junxiaosong…

寫這個專案的目的也是希望在探索的路上多走一條道,多一個人。

最後給其他對 alpha zero 演算法感興趣的人一點建議:

如果沒有足夠算力的話,沒事不要碰象棋,圍棋這種複雜遊戲,可以從五子棋這種簡單遊戲入手訓練,五子棋這種簡單遊戲對算力的門檻要求會低很多。

另外,如果想探討一些技術問題可以站內私聊,評論,或者通過 icybee@yeah.net 聯絡我

相關文章