跳轉到

5.2 AlphaGo 幕後的運算架構與分散式系統(2016)#

一個系統,而不是一個模型#

關於 AlphaGo 最廣為流傳的誤解,是把它想像成一個「巨大的神經網路」。2016 年 3 月在首爾對弈的那套系統,實際上是一個由多個專用元件組成的分散式管線,神經網路只是其中最核心、但也只佔用了一部分時間與資源的環節。公開的架構描述大致是這樣的:主控節點負責維護一棵蒙地卡羅搜尋樹,並行工作節點負責執行評估,評估本身則交給兩張各自分工的網路。

先把結構講清楚,後面所有的效能討論才有意義。

策略網路(policy network) 是一個卷積神經網路。它的輸入是棋盤的數位表示,輸出是一個覆蓋所有可能著法的機率分佈。當人類面對一盤棋時,能在幾秒內排除掉九成以上的離譜著法,剩下的少數再靠直覺排序。策略網路的功能就是把這件事做成可量化的形式。

價值網路(value network) 也是卷積神經網路,但輸出是一個標量:目前盤面下,黑棋的預期勝率。它不需要給出「該下哪裡」,只需要回答「現在誰占優」。這兩張網路在訓練時分開,扮演兩種不同的角色。

蒙地卡洛樹搜尋(MCTS) 則是讓前面兩者發揮作用的外框。搜尋樹由節點構成,每個節點記錄著經過該節點的各種著法及其累計統計量。每一步決策的基本流程是:從根節點出發,依據某些準則向下選擇子節點,直到抵達一個尚未展開的葉節點;在葉節點上進行擴展,也就是把新著法加入候選;接著進行評估,取得一個價值訊號;最後把這個訊號沿路徑向上回傳,更新沿途所有節點的統計量。這個循環重複數百到數千次之後,訪問次數最高的著法就被選出。

網路評估取代 rollout:深度倍增的關鍵#

要理解 2016 年版 AlphaGo 的效能祕訣,必須先理解 2016 年之前圍棋程式是怎麼做的。那時的主流做法是在搜索的末端進行 rollout,也就是用一個隨機策略或輕量啟發式規則把棋局一路下到終局,然後用終局結果回頭更新。因為圍棋分支因子極大,即使只往下隨機走幾十手,末端也早已是毫無意義的混亂局面。

AlphaGo 在 2016 年 3 月的一個關鍵改變,是用網路評估取代了大部分的 rollout。搜索不必再把每個分支真正走到終局,它只要把局面展開到某個深度,然後交給價值網路問一句「這裡誰占優」。這一步帶來的效果,是等效搜索深度成倍增加,而計算成本反而大幅下降。

這是本章最需要被記住的一個因果關係:

\[ \text{等效搜索深度} \approx \frac{\text{單位時間可完成的評估次數}}{\text{每次評估的成本}} \]

在網路評估的架構下,每次評估的成本從「跑完幾十手模擬」降到「一次前向傳播」,前者是把樹往下長,後者是沿著樹讀。當評估變得便宜,搜尋就可以在同一段時間裡探索更多分支,等效深度隨之上升。圍棋這種分支因子極大的遊戲,對這種「深度換廣度」的交換特別敏感。

分散式:為什麼是必須的#

即使把 rollout 換成網路評估,評估本身的成本仍然不低。每一張網路的前向傳播都是一次大規模的矩陣乘法與捲積運算,若用一般 GPU 來做,單次評估的延遲足以讓搜尋完全停滯。於是分散式不是選項,而是前提。

公開的報導與團隊說法提到,2016 年比賽期間,AlphaGo 使用了數百至數千顆 GPU 的分散式架構:其中絕大多數配置在推論階段,負責 policy 與 value 的評估工作,數百顆配置於樹搜尋與樹維護。這些節點透過高速網路互連,共享同一棵搜尋樹的節點統計與通訊佇列,主控節點把待評估的局面批次分派出去,工作節點完成後把結果送回。

架構層次 主要工作 典型負載 對延遲的敏感度
主控節點 樹結構維護、著法分派、節點統計更新 中等 高
搜尋工作節點 選擇、擴展、啟動評估批次 較高 高
推論叢集 policy 與 value 的前向傳播 極高 極高
網路互連 批次傳輸與結果回傳 隨機 極高

分散式的價值可以從一個簡單的量綱來看。若單次網路評估的延遲是 \(\Delta t\) ,而搜尋在每個節點上需要收集多個候選的評估才能有效比較,那麼有效評估吞吐量大致與並行節點數 \(P\) 成正比。分散式把這個 \(P\) 從 1 提升到數百,等於把搜索樹的成長速率提升了好幾個數量級。

更細緻的問題在於:分散式節點之間必須就「誰更新了哪個節點的統計量」達成一致。早期版本的做法相當保守,是讓工作節點只做評估、節點更新則集中交由主控節點處理,透過批次回傳來降低一致性協定的複雜度。這種設計的代價是主控節點成了瓶頸,收益是實作簡單且不易出錯。在對局這種「必須在固定時間內給出答案」的場景裡,可預測性往往比理論效率更重要。

節點之間如何對話#

分散式系統真正的難題從來不是「把工作分出去」,而是「分出去之後怎麼把答案收齊」。AlphaGo 的搜尋是帶有依賴關係的:某個節點的評估必須等它所有前驅路徑的資訊都更新完,才知道下一步該往哪裡展開。這種依賴讓它無法像影像分類那樣把樣本完全打散、一次餵給整個叢集。

因此實作上採用的是批次並行的折衷。一次迭代裡,主控節點沿著樹收集出一批可以同時評估的葉節點,把這些局面的特徵打包成一個大批次送到推論叢集。這個批次的規模必須足夠大,才能讓加速器的矩陣運算效率跑滿;但也不能太大,否則第一個結果要等整批回來才會被使用,尾端延遲會吃掉整體吞吐。

更麻煩的是記憶體。圍棋的特徵表示不是原始的 \(19 \times 19\) 棋盤,而是多個經過卷積層處理的特徵平面,每個平面覆蓋整個棋盤,且攜帶歷史資訊的通道。一次大批次評估意味著同時在記憶體中存放數百到數千份這樣的高維張量。谷歌的 TPU 恰好就是為這種「大量中等規模矩陣、同時並行」的工作負載設計的,它的大容量片上記憶體讓整個批次可以一次載入而不必反覆往返主記憶體。這是演算法與硬體在細節層面咬合的一個典型例子。

此外,Google 資料中心內部的高頻寬、低延遲互連網路,是讓分散式樹搜尋得以成立的基礎設施。一般的區域網路延遲在毫秒量級,對單次推理尚可,對於數百個節點之間密集的樹通訊就完全不足。團隊能夠使用 Google 自建的叢集與網路基礎設施,而不是採購一般商用產品,這一點本身就是這場對決不可複製的原因之一。

每一局的算力帳#

要為 2016 年的對局算出一個能量級的估算,可以從搜尋預算反推。若單手要進行數百到數千次評估,每一局約兩百手,則整場對局的總評估次數落在數萬到數十萬的量級。若再加上自我對弈訓練所耗費的運算,總量還會再翻上一到兩個數量級。

這裡必須謹慎表述。媒體報導中出現過諸如「單局消耗數萬顆晶片運行數小時」這類說法,數字彼此間的定義並不一致:有人把「晶片小時」當作單局用量,有人把它當作整場賽事的訓練總量。比較穩妥的說法是:比賽期間使用數百至數千顆 GPU 的分散式架構,單手的評估次數在數百到數千之間,整場對局的運算用量達到數萬至數十萬的晶片運行小時量級。

層次 典型數量級 備註
單手搜尋模擬次數 數百至數千 依局面複雜度與時間預算浮動
單局總著法數 約 200 至 250 手 視棋局長短
單局總評估次數 數萬至數十萬 為上兩項的乘積
比賽硬體規模 數百至數千顆 GPU 分散式推論與搜尋並行
單局運算用量 數萬至數十萬晶片小時 報導口徑不一,應視為量級估計

演算法與硬體的共演化#

AlphaGo 的歷史地位,有一個面向常常被忽略:它不是一個純粹的演算法突破,而是一個演算法與硬體共同設計的產物。在同樣的網路架構下,如果只有幾十顆 GPU,AlphaGo 的棋力會顯著低於人類頂尖棋手;同樣的硬體規模,如果沒有網路評估取代 rollout,搜尋深度不足以支撐這種棋力。兩者缺一不可。

也正因為每一手的時間預算固定,「算力直接換算棋力」的關係才會如此陡峭。時間預算越長,模擬次數越多,搜尋樹越深,棋力越高,而這種提升在頂端棋力區間裡依然可見——這與深藍時代「只要多算一步就能贏」的直覺式想像不同。圍棋的搜索在頂端區間裡不會自然飽和,因為分支因子的膨脹速度遠快於深度的邊際收益,因此每一次計算資源的投入都仍在換取實質的棋力。這個特性,直到 AlphaGo Zero 出現、強化學習把「算力」從「對局時的推理」轉移到「訓練時的自我對弈」之後,才被徹底改寫。

這意味著第 10 章要處理的問題,在 2016 年 3 月就已經埋下伏筆:Google 的 TPU 是為深度學習的矩陣運算量身設計的加速器,它擅長的正是 policy 與 value 網路所需的密集矩陣乘法;而分散式集群的存在,讓蒙地卡羅搜尋那種「需要大量彼此獨立的評估」的演算法得以真正發揮。演算法提出需求,硬體滿足需求,硬體的限制又反過來塑造演算法下一階段的設計方向——這正是「共演化」三個字的實際含義。

為什麼第一局會輸#

回到那個最尷尬的問題:擁有數百顆 GPU 的系統,為什麼會在第一局裡下出可以從網路上直接抄來的定式?

答案有兩層。第一層是規則層面的:AlphaGo 的自我對弈訓練並不是無限制的,它在訓練中大量使用人類棋譜作為初始先驗,而團隊在比賽時才刻意關掉了直接的定式查詢功能,關得不徹底。第二層是架構層面的:在分散式架構中,各個工作節點各自持有網路模型副本,模型更新時需要在數百個節點之間同步。若同步策略是「各自為政、定期平均」,那麼不同節點可能在不同時間點持有略有差異的模型副本,這會讓搜索樹的行為出現不穩定。

這兩點合起來解釋了一個看似違反直覺的現象:算力更強的系統,在第一局反而顯得更像一台死記硬背的機器。第二局之後團隊重新調整了硬體與軟體的設定,AlphaGo 才真正開始以自己的方式下棋。整場五局三勝,本質上也是系統從「拼接人類知識」過渡到「形成自身判斷」的實時過程記錄。

從一台機器到一片機房#

最後值得記錄的,是「單機」與「機房」在概念上的跳躍。過去六十年裡,棋類程式始終被視為一台機器與一個人之間的對局,深藍是專用晶片加上主機,而圍棋引擎是家用電腦加上多執行緒。AlphaGo 把這個關係改寫了:對弈的主體不再是「一個程式」,而是「一個佔滿整間機房的分散式系統」,而所謂「AlphaGo 下出的一手棋」,其實是一個分散式決策過程在數百毫秒內收斂出的結果。

這個改變的意義超出圍棋本身。如果一個領域的問題可以被拆解成「大量彼此獨立的局部評估」,那麼它的計算需求就不再受單機極限約束,而可以用增加硬體的方式線性擴充。這個思路正是後來大規模語言模型訓練、以及 AlphaFold 的大規模搜尋所遵循的路徑。2016 年那場對局真正展示的,是「用一個系統的設計,把一個被認為不可解的問題變成可解」的能力。

為什麼分散式在圍棋上特別難#

圍棋的搜尋與西洋棋的搜尋,在分散式層面有一個本質差異:西洋棋的分支因子小得多,樹淺而窄,評估需求也低;圍棋的樹深而寬,每一個節點都必須展開數百個候選著法。這意味著圍棋的搜尋不只需要更多算力來做更多次評估,更需要算力來做候選著法的生成與排序——也就是 policy 網路的前向傳播本身,成了分散式系統中佔比最大的工作負擔。

這解釋了一個細節:分散式架構裡,負責推論的節點數遠多於負責樹搜尋的節點數。搜尋節點做的是輕量的節點統計維護與批次調度,重的工作——把數百個候選著法的特徵算出來並排序——則整批交給推論叢集。整個系統的速度,最終由這個批次處理的吞吐量決定。

硬體不是配角#

歷史學家常把 2016 年 3 月 9 日至 13 日的這五天,敘述為一個關於「直覺」與「人類尊嚴」的戲劇。但從工程史的角度看,那五天更像是一場系統整合的現場演示:把卷積網路、強化學習、蒙地卡羅樹搜尋、分散式通訊與專用加速器,五個各自成熟的技術縫合成一個能贏棋的整體,並且在公開的、不可重來的條件下完成驗證。

這種整合的難度,遠高於任何單一組件的研發。policy 網路要能覆蓋圍棋的分支因子,value 網路要能壓縮終局的不確定性,搜尋要在有限的時間預算內把兩者結合,硬體要在數百個節點上以可接受的延遲完成批次評估。任一環節的延遲惡化,都會讓整棵樹的生長停滯。

這也是為什麼 DeepMind 後來把 AlphaGo 的架構經驗整批搬到其他領域的原因。蛋白質摺疊用上了同一套「搜尋加學習加硬體」的骨架,只不過評估函數換成了物理能量的計算,而運算需求更高,於是必須換上更強的加速器。同一副骨架,在圍棋上叫 AlphaGo,在生物學上後來叫 AlphaFold。