学会下棋
一位国际象棋神童读过的手册、三种古老的棋类和一台笔记本电脑:用 Rust 重建博弈 AI 背后的思想,让它在我手机的浏览器里运行,并加以测量。
| 阅读时长 | 20 分钟 |
|---|---|
| 发布于 | |
| 主题 | 游戏 AI, 机器学习, 强化学习, 游戏, Rust, WebAssembly, 技术史, 国际象棋, 将棋, 围棋 |

简而言之
读 The Infinity Machine 时,我惊讶地发现,少年 Demis Hassabis 读过的那本国际象棋手册里讲的三个部分,至今仍是一个国际象棋程序的全部,只是评估函数如今是学出来的。 国际象棋、将棋和围棋勾勒出博弈 AI 的历史:经典方法在国际象棋上行得通,在将棋上捉襟见肘(NNUE 网络正是在将棋里发明的),在围棋上则彻底失效,除非由神经网络来引导搜索。 我用 Rust 为这三种棋各写了一个引擎,编译成 WebAssembly,让它们能在我的手机上离线对弈,因为搜索内部的网络必须是小巧的、手写的算术。 在相同搜索深度下,我通过自我对弈训练的网络胜过了手写的国际象棋评估函数,但在相同用时下只打成平手,因为它评估每个局面的成本更高。 这一个月给我留下的问题比开始时更好;我正在为每一次运行(包括失败的)记一本笔记,它也许会发展成一个系列。
这个月我在读 The Infinity Machine,这是 Sebastian Mallaby 为 Demis Hassabis 写的传记。Hassabis 是来自北伦敦的国际象棋神童,创立了 DeepMind,也就是 AlphaGo 和 AlphaFold 背后的那家实验室。我拿起这本书,是因为我想了解我们如今身处其中的这种 AI 的早期缔造者之一,而讲述者曾与他相处了三十个小时;也因为几乎所有让我感兴趣的东西,游戏、模拟、机器能独自学会什么这个问题,都贯穿在他的故事里。读到一百页左右,有一个场景让我一直放不下。
那是 1988 年,Hassabis 十二岁。他用下棋赢来的奖金买了一台 Commodore Amiga 500,又在查令十字街上的大书店 Foyles 里找到一本薄薄的平装书:David Levy 的 The Chess Computer Handbook。他一口气读完了。Levy 讲解了一个国际象棋程序如何由三个部分构成。棋盘必须变成数字。需要一个函数来审视局面,判断谁占优。还需要一个搜索来尝试各种走法,以及对这些走法的应着,再到对应着的应着,并剪掉明显糟糕的分支,因为这棵树生长的速度比任何计算机能跟上的都快。Hassabis 试着把它做出来,发现 Amiga 根本跑不动国际象棋,于是改写了一个黑白棋程序,赢了他五岁的弟弟。
读到这里我放下了书,一部分是因为我在那个男孩身上隐约看到了自己,另一部分是因为我意识到了两件事。第一,这三个部分至今仍是一个国际象棋程序的全部。三十八年后,世界上最强的引擎依然是:数字化的棋盘、一个评估函数,以及一个带剪枝的树搜索;变化在于,评估函数如今是由机器学出来的,而不是由人写出来的,而机器是通过与自己对弈学会它的。第二,我桌上那台笔记本电脑的内存是那台 Amiga 的三万倍,而我从未亲手构建过这三个部分。
所以这个月我动手了。我用 Rust 写了三个棋类引擎,分别对应国际象棋、日本将棋和围棋,把它们编译成 WebAssembly,让它们能在我手机的浏览器里对弈,还搭建了一个训练循环,目标是让其中一个变得比我手工所能做到的更强。应用在 kishi.raskell.io,代码在 GitHub 上。这篇文章讲的是:为什么是这三种棋,为什么用这些工具,以及当书里的思想遇上一台普通机器时发生了什么。
这本书、这个人和这家实验室
Mallaby 本行并不是科技作者。他曾任《金融时报》特约编辑,两次入围普利策奖决选,现为外交关系委员会高级研究员;他此前的书都与钱有关:写对冲基金的《富可敌国》,写 Alan Greenspan 的 The Man Who Knew,写风险投资的 The Power Law。事实证明这正是合适的背景。The Infinity Machine 既是一部传记,也是一部公司史,建立在与 Hassabis 约三十小时的谈话和对他身边一百多人的访谈之上;它认真追问一个人为什么要去构建一项自己都认为危险的技术,就像认真追问如何构建一样。这本书今年早些时候出版。我读得很慢,AlphaGo 那几章还在后面,我发现自己并不介意,因为我宁愿在自己那个版本跑起来之后再去读它们。
如果你不关注这个领域:Hassabis 是这个领域如今视为元老的人物,年仅五十岁。他 1976 年生于芬奇利,母亲是新加坡华人,父亲是希腊族塞浦路斯人;十三岁时成为国际象棋大师,是世界上同龄棋手中排名第二的。十六岁时,他在游戏工作室 Bullfrog 参与编写了 Theme Park,这款游戏卖出了数百万份。他在剑桥读计算机科学,自己经营了一家游戏工作室七年,然后回到大学攻读神经科学博士,因为他认为,要造出一台智能机器,唯一的路是先理解现存的唯一实例。2010 年,在罗素广场的一间阁楼里,他与 Shane Legg 和 Mustafa Suleyman 创立了 DeepMind;那时,这个领域里几乎没有人相信他们设想的东西是可能的。第一笔真正的资金来自 Peter Thiel 的一支基金,其合伙人给这门科学打了 A+,给商业模式打了 F。
DeepMind 的构想是人工智能领域的曼哈顿计划,而它的方法正是把这本书与这篇文章联系起来的东西。它押注的是把 2010 年时都不受青睐的两个分支结合起来:深度学习,即 Geoffrey Hinton 捍卫了四分之一个世纪的多层神经网络;以及强化学习,即程序从自身行动的后果中学习,而不是从标注好的样本中学习;再在其上加入神经科学的思想。试验场是游戏,因为游戏有可以完整写下的规则,也有可以直接从棋盘上读出的分数。2013 年展示的第一个成果,是一个只凭像素就学会玩 Atari 游戏的智能体。Google 在 2014 年收购了这家公司。2016 年 AlphaGo 在首尔击败李世石;2017 年,它的继任者 AlphaZero 仅凭规则和与自己的对局,用同一个算法学会了国际象棋、将棋和围棋,并在每一种棋上都击败了当时最强的程序。这正是本文的三种棋,顺序也一样,而自我对弈就是我搭建的那个循环。随后是 2020 年的 AlphaFold,然后是两亿个蛋白质的预测结构,再然后是 2024 年的诺贝尔化学奖。就连公司名字都是一个三重致敬:致敬深度学习,致敬 Deep Blue,也致敬 Deep Thought,即《银河系漫游指南》里那台被要求给出终极答案的计算机。
我为什么读它?一部分是显而易见的原因:我的工作就是做 AI 平台,想从内部了解这场革命的缔造者之一的故事,而这本书恰恰提供了这些,甚至更多。一部分是因为那些相似之处,它们一次次让我猝不及防:一个把模拟偷偷塞进主题公园的游戏设计师,一个路过棋盘就忍不住想赢一局的竞争者,一个把世界看作信息、把心智看作构建现实而非记录现实之物的人。我在其中认出的部分,多到让我有些不自在。还有一部分是因为那份信念。Hassabis 在几乎没有人相信人工智能的时候就相信它,这种信念被书中坦率地称为近乎宗教,而他是对的。故事里贯穿着一条超人类主义的线索,从他在 Bullfrog 时读的 Iain Banks 小说,到 DeepMind 找到第一位投资人的奇点峰会,而他对这种思想的加州版本始终保持着一种冷淡的英式距离。我自己也有一条这样的线索,角度不同,来路也不同,那是另一篇文章的题目。在这里只需说一句:我读这本书时并不是一个怀疑论者。
在开头那些篇章里,比神童故事更吸引我的,是游戏如何一再成为入口。Hassabis 通过国际象棋学会了编程。他的第一个智能程序下的是黑白棋。在剑桥,他跟一位教授学了围棋,又把将棋下到了英国排名的顶端。他的朋友 David Silver,后来领导了 AlphaGo 的工作,是在他们的游戏公司倒闭后,在法国南部读了一本强化学习教科书,才走进这个领域的。Mallaby 把这条线追溯到 Claude Shannon 1950 年关于编程让计算机下国际象棋的论文,而 Levy 的手册正是把这篇论文介绍给了那个十二岁的少年。Shannon 写道,国际象棋程序本身没有实际意义,但掌握一种棋类或许可以成为「攻克其他性质相似、意义更重大的问题的楔子」。这句话已有七十六年历史,至今仍是我所知道的、为花一个月研究棋类辩护的最好的一句话。
我自己的棋
我自己的国际象棋故事要小得多。我十几岁出头加入了一家国际象棋俱乐部,参加地区比赛,在其中几场里成绩不错:远不至于让一位国际象棋专栏作家穿过大厅去找我父亲谈话(Hassabis 六岁时就有人这样做过),如果不是这本书把我们俩放进了同一家书店,我也绝不会把自己和他的经历写进同一段。但这项游戏一直留在了我身边。有人邀我下棋,我从不推辞;最近一次是今年在旧金山的联合广场,对手是一位同事兼朋友。我对那种棋子高及膝盖的大型户外棋盘情有独钟,我喜欢的有两处,一处在卢塞恩,一处就在巴塞尔的莱茵河畔。坐火车时,我用手机在 lichess 上下棋。我也比预想中更享受这项游戏在 2020 年代意外获得的第二次生命:一部讲述虚构神童的电视剧让人们纷纷去买棋盘,特级大师们变成了主播,观众多到任何比赛大厅都容纳不下。我没料到会这样,也没什么可抱怨的。
我游戏生活的另一半,是德语里所说的 Aufbauspiele,即建造类游戏:Anno、Die Siedler、整个大亨类游戏,凡是让你铺设一个有规则的世界、然后看它运转的东西都算。Hassabis 的 Theme Park 就是其中之一,这让那一章读起来格外亲切。薯条放多了盐,游客就会口渴,多买饮料;过山车太快,乘客就会呕吐:这正是我玩这类游戏所追求的那种机制。我最喜欢那些试图模仿现实、让一套厚重的规则自己生成无人编写的故事的游戏,这就是我热爱 Dwarf Fortress 的原因,也是我不断构建自己的模拟的原因,从一皿在刺激下学习的神经元,到一个任其演化的生态缸。从这个角度看,一个国际象棋引擎是最小的值得构建的模拟:一个有规则的完整世界,而其中有一个必须学习的智能体。
为什么是棋类,为什么是这三种
Shannon 的观点很务实。像国际象棋这样的游戏,规则可以完整写下,结果可以毫无争议地从棋盘上读出,而它的深度无论怎样研究都未曾穷尽。这样的组合很罕见。大多数现实问题规则模糊、结果有争议,也没有衡量标准。一种棋类给你一间实验室,新想法可以在一个下午内接受检验,对手是几个世纪积累的人类知识,而答案是一个数字。
这个领域的历史也恰好是沿着国际象棋、将棋和围棋这三种棋依次展开的,而每一种都打破了在前一种上行之有效的方法。这就是我三种都选、而不是只选一种的原因。
国际象棋大约在六世纪起源于印度北部,当时叫恰图兰卡,经由波斯传入欧洲,并在十五世纪末的西班牙和意大利定型为现代形式,有了长距离行走的后和象。它是 Shannon 选中的棋,是 Levy 的手册所讲授的棋,也是搜索加评估这一经典方法为之打造的棋。1997 年,IBM 的 Deep Blue 击败了 Garry Kasparov,靠的是在专用芯片上每秒搜索两亿个局面,评估函数由人编写和调校。这是三个部分的胜利,却让所有期待洞见的人失望:机器赢在看得更远,而不是理解得更多。从 Levy 那一章开始,有意思的问题一直是:评估函数能否学出来,而不是写出来。对国际象棋而言,这个问题在 2018 到 2020 年间得到了回答,答案是一个住在引擎内层循环里的小型神经网络。它叫 NNUE,而它并不是为国际象棋发明的。
将棋是同一家族的日本分支。它在十一世纪前经由中国和东南亚传入日本,到十六世纪形成现在的样子,并在德川幕府时期成为一种制度,幕府给最好的棋手发放俸禄;名人这一至今仍为将棋冠军加冕的头衔,第一次授予是在 1612 年。如今日本有数百万人下将棋,有职业体系,有电视转播的头衔战,还有一位年轻的明星藤井聪太,他在 2023 年、二十一岁时同时持有全部八大头衔。棋盘是九乘九,每方有八种共二十枚棋子,大多数棋子走到对方的三行内就会升变。有一条规则让它成了另一种游戏。被吃掉的棋子会换边,进入吃子方的手中,之后可以作为一步棋打入几乎任何空格。没有棋子会永久离开棋盘,所以这种棋永远不会像国际象棋那样逐渐简化。典型的一手大约有八十种走法可选,而国际象棋是三十五种;对局更长,残局是双方的竞速,而不是技术性的消耗战。对程序员来说,打入让评估函数难以手写得多,这就是学习最先在这里发生的原因。2006 年,Bonanza 改变了电脑将棋,它是第一个评估函数根据职业棋谱拟合、而非手工调校的程序。2017 年,Ponanza 击败了现任名人佐藤天彦;2018 年,那须悠发表了那个网络设计,两年后 Stockfish 把它用在了国际象棋上。我所追寻的那个想法,就来自将棋。
围棋比两者都古老,也比两者都简单。它源自中国,至少已有两千五百年历史,与琴、书、画并列为文人的四艺;它在八世纪前传入日本,江户时代的职业棋手家族由幕府供养;在韩国它也根基深厚,在那里叫作 baduk。规则写在一张卡片上就够了。两名棋手轮流把黑白棋子放在十九乘十九棋盘的交叉点上。一块棋如果周围没有空点,就会被提走。终局时,围住更多地盘的一方获胜,后手的白方会得到几目补偿。从这些规则中诞生的,是一种每一手都有约二百五十种选择、一局两三百手、而且没有人能手工为局面打分的游戏。Levy 的三个部分在这里失效了。在围棋里向前看四步的搜索几乎什么都看不到,也没有任何公式能在叶节点上判断谁在领先。围棋是这个领域里所有人(包括 Hassabis)都称为大挑战的那种棋,也是 DeepMind 想要展示实力时选中的棋。2000 年代后期的程序用蒙特卡洛树搜索取代了国际象棋的方法:它把成千上万盘随机对局下到终局,统计谁赢;这让程序达到了强业余水平,然后就停滞了。AlphaGo 保留了这种搜索,又给了它两个神经网络,一个提议走法,一个评判局面,先用人类棋谱训练,再用它自己的对局训练;2016 年 3 月,它以四比一击败了李世石。
所以:一种棋,经典方法行得通,网络取代了评估函数;一种棋,同样的方法捉襟见肘,网络在这里被发明出来;一种棋,方法失效,网络必须亲自引导搜索。三者合在一起,就是这个领域四十年历史的一门速成课,而每一种都可以拿任何人都能下载的对手来测量。
为什么我要亲手构建,而不只是读读而已
Hassabis 喜欢引用 Feynman 那句话:我造不出来的东西,我就不理解。这也是这个项目真正的原因。AlphaGo 的论文和 Stockfish 关于 NNUE 的文章我都读过不止一遍。那些图示我能讲解。但我说不出 K 是什么,说不出为什么一个在相同搜索深度下获胜的网络会在相同用时下落败,也说不出一代自我对弈要耗费一台笔记本电脑多少小时的寿命,因为这些正是论文略去不提的东西,而学会它们的唯一办法就是为之付出代价。读这本书让这道鸿沟变得令人不安,而那种让我去造生态缸的冲动,也想让那个有规则、有学习者在其中的世界,在我自己的机器上运行起来。
另一个原因是,原料第一次全都摆在了我的桌上。思想已经发表,参考实现都是开源的。笔记本电脑是一台 MacBook Pro,Apple M4 芯片,十个核心,十六 GB 内存,它不是研究用的机器,通用计算能力却超过了当年的 Deep Blue。我手机上的浏览器现在能运行带向量指令和真正线程的编译代码。至于写代码本身,原本要耗去一整个冬天的晚上,借助编码智能体只用了几天:由我决定构建什么,大部分代码由智能体来敲。这一点属于方法的一部分:智能体写代码,两个引擎之间的对局决定代码好不好,而对局并不在乎代码是谁写的。
为什么用 Rust,而不是 PyTorch
2026 年做机器学习,显而易见的方式是 Python 和 PyTorch;如果目标是一个在服务器上回答问题的模型,我也会用它们。但目标是我手机上的一个对手,在浏览器标签页里,离线运行,这决定了后面的一切。
国际象棋的评估函数是在搜索内部被调用的,每秒大约一百万次,在单个核心上,没有批处理,而不是每个请求调用一次。住在那里的网络不可能是 API 背后的一个模型。它必须是用引擎自身语言写成的几百行算术,在整数上运行,并且随着走棋增量更新,而不是从头重新计算,这正是 NNUE 的全部诀窍。换句话说,推理部分无论如何都得手写。手写完之后,训练器就是同样的算术反过来跑,面对一百万个参数和几乎全为零的输入,它同样只需要几百行。亲手写它,也让我发现了框架本会对我隐藏的东西:一个我凭猜测而非拟合得出的常数,把一个会赢的网络变成了一个会输的网络,而如果用框架,我不会知道为什么。
Rust 是我在这个网站上写所有东西用的语言,从神经元培养到幻想游戏机都是,对引擎而言它也是合适的工具,理由是常见的那些:在每秒运行一百万次的循环里没有垃圾回收器,能控制内存布局,编译器还能从与原生二进制相同的源码生成带向量指令的 WebAssembly。从笔记本电脑上的自我对弈到手机上的每一步棋,都是同一种语言,在同一个仓库里,而网页应用没有构建步骤。代价也要坦白说。在 CPU 上训练一个小型稀疏网络没问题。但如果围棋网络最终成为一个有数百万稠密参数的卷积网络,十个核心上的 Rust 会很慢,到时我就得决定,是写一个 Metal 内核,还是承认这正是笔记本电脑研究与 GPU 相遇的地方。
为什么用 WebAssembly
因为手机才是重点。住在服务器上的对手不属于我;应用商店里的对手要由别人来批准。一个我添加到主屏幕上的网页,能在飞机上使用,运行的二进制与我笔记本电脑上的完全相同,这才是我想要的版本,而在 2026 年,浏览器做得到。WebAssembly 支持 128 位向量指令已经有一段时间了,而 Safari 现在允许页面在线程之间共享内存,只要它带着正确的隔离响应头提供服务,所以我手机上的国际象棋引擎能用四个核心搜索。免费国际象棋网站 Lichess 也是用同样的方式为它的分析棋盘运行 Stockfish,这在我动手之前就证明了这条路是可行的。
这个约束对设计的塑造也超过了任何一篇论文。一个必须随网页下载、在手机上运行的网络必须很小;Kishi 的国际象棋网络是 820 KB,编译进了引擎的二进制文件里。一个必须在浏览器标签页里运行的搜索必须节俭。代码里每一个看起来像是品味的决定,其实都是手机在对某样东西说不。
结果如何
国际象棋引擎最先完成:位棋盘,一个带有一系列常见剪枝启发式方法的搜索,以及一个借用一套知名的棋子位置表的手写评估函数。对手是按 lichess 配置其电脑对手的方式设置的 Stockfish,每个级别二十局,单核:它以十九比一击败 4 级,以十三比七击败 6 级,以半比十九个半输给 7 级。如果你和 lichess 的电脑下过棋,就能据此给它定位:一个扎实的俱乐部棋手,离顶尖还差得很远。
然后是那个循环。引擎从随机开局与自己对弈了五十二分钟,从五万七千盘对局中产生了 560 万个局面,每个局面都标注了搜索对它的判断以及那盘棋的结果。用这些局面训练一个网络只花了不到二十分钟;在双方被允许查看相同数量局面的条件下,它比它所取代的手写评估函数强 85 个等级分,误差正负 32。而当双方被允许使用相同的毫秒数时,两者打成平手,因为网络评估每个局面的成本是手写评估的两倍半。这一句话就是这类学习的全部问题所在,而在拿到这些数字之前,我并不理解它。
将棋有了自己的引擎,结构相同,评估函数也是手写的;它以二十比零击败 Fairy-Stockfish 最弱的设置,以二比十八输给中等设置。围棋用的是 2000 年代后期的方法,即蒙特卡洛树搜索,加上旧程序 MoGo 的棋形模式;对阵最低级别的 GNU Go、每步一秒时,它十盘赢三盘。三个引擎都能在手机上下。在最高级别上,只有国际象棋引擎是我会称为令人满意的对手,而这还是用手写评估函数的结果,因为训练出来的网络还没有在棋钟上赢得自己的位置。
由此打开的问题
我开始时只有一个问题:我能否构建 Levy 的三个部分。而这个月结束时,我有了五个更好的问题。
国际象棋网络在相同搜索下获胜,在相同用时下打平。经过更多代的自我对弈,随着它学习所用的对局越来越强,这会改变吗?还是说,一个笔记本电脑大小的网络永远要为自身的成本买单?我写下这些文字时,循环正在以低优先级运行,好让笔记本电脑仍然能用。为什么一个常数会让结果相差 176 个等级分,这又说明了一个学习得来的组件与它所接入的手工调校系统之间是一种怎样的契约?一旦网络能看到王的位置(那须的原始设计做到了,我的还没有),同样的循环在将棋上是否行得通?围棋需要第二种循环,由搜索来教网络该看哪些走法,而我不知道一台笔记本电脑能在完整的十九路棋盘上训练出什么;书中 AlphaGo 那几章我就快读到了,它们会告诉我 2016 年需要什么,而我想知道的是 2026 年在一台商店里买来的机器上需要什么。而在这一切之下:一个引擎的棋力,从原生二进制到手机浏览器标签页的这一趟旅程中能保留多少,线程又能挽回多少?
每一个问题都是几天的工作和几个数字,我已经开始在仓库里记一本笔记,好让数字一出来就被记下,失败的也包括在内。如果答案和问题一样有趣,这也许会成为几篇文章中的第一篇,一次一个想法,先是国际象棋,然后是将棋,再然后是围棋。且看吧。
参考资料
- Sebastian Mallaby, The Infinity Machine: Demis Hassabis, DeepMind, and the Quest for Superintelligence (Penguin Press, 2026),第 1 至 5 章。
- Claude Shannon, Programming a Computer for Playing Chess, Philosophical Magazine (1950).
- David Levy, The Chess Computer Handbook (Batsford, 1984).
- Yu Nasu, Efficiently Updatable Neural-Network-based Evaluation Functions for Computer Shogi (2018,日文);Stockfish, Introducing NNUE Evaluation (2020).
- David Silver 等, Mastering the game of Go with deep neural networks and tree search, Nature (2016).
- Kishi:引擎、训练循环,以及记录每一次运行的笔记。