一个 AI agent 从零复现迷你 AlphaZero

从随机乱下,到赢过搜索算法九成

这是 vibe-bench 里的一道题:在一个 2017 年的 AlphaZero 五子棋仓库上,从全新的网络开始自我对弈、训练,并和纯蒙特卡洛树搜索对战评估。Naive N0.5 在一台没有 GPU 的机器上写出并行训练程序,把网络从 0% 胜率训练到了 90% 以上;最好的检查点下 100 局赢 95 局,和仓库自带的预训练模型(94 局)打平。右边这局就是训练出的网络(蓝圈)对纯 MCTS 的一盘实战。

本页展示的是这道题的第五版运行(v5)。此前的几版是我们为找到合适提示所做的尝试,放在页面后半部分说明。

0% → 90%对纯 MCTS 的胜率,各 30 局
4072局自我对弈,1105 次更新
14.8 hagent 连续执行,其中训练 10.5 h,纯 CPU
87%仓库自带模型,同样设置
蓝圈:Naive 训练的网络无圈:纯 MCTS

它是怎么一步步变强的

每个点是一个训练检查点。我们把它和每步 1000 次随机模拟的纯 MCTS 各下 30 局、轮流先手,阴影是 95% 置信区间。点任意一个检查点,右边的棋盘会回放那个阶段的真实对局。

Naive 训练的网络95% 置信区间仓库自带模型(87%)
以表格查看
当前检查点
网络最近一次落子前的估值

蓝色光晕是网络在轮到它落子时给出的概率:训练初期几乎平均撒满棋盘,越往后越集中到少数几个落点。估值条显示网络最近一次落子前对局面的估值,向右表示它认为自己占优。

损失

策略损失、价值损失与 L2 正则项之和

策略熵

越低说明落子越果断;36 个点均匀分布时是 3.58

价值网络解释方差

训练批次上对胜负变化的解释程度,越接近 1 越好

还能更强吗

训练到第 595 次更新时,胜率停在 60% 左右。我们请 GPT-6-Astra 读了全部训练指标和复算对局,结论是还有明显空间,而且问题出在一个具体的地方。

观察数据含义
胜率仍在上升第 250 次更新到最终,平均每 100 次更新约 +7 个百分点(95% 区间 +0.6 到 +13.7)没有看到明确的平台期;末段相邻检查点相差 2 到 7 局,仍有明显波动
后手是主要差距第 595 次更新时先手 13/15、后手 5/15;自带模型先手 15/15、后手 11/15自带模型多赢的 8 局里有 6 局来自后手,这部分还没学够
落子还不够果断网络给出的最高落子概率平均 16%,自带模型 51%策略仍然分散,有继续收敛的余地
更新幅度稳定末段 KL 平均 0.026,目标 0.025每次更新的幅度受控,训练没有不稳定;一个明确的瓶颈是下面这条
自博弈数据过早变旧8 个自博弈进程在约第 70 次更新时就下完了全部 600 局之后 500 多次更新用的都是早期弱网络下出的棋谱,"更强的网络下出更好的棋"这个循环提前断了

据此估计,再训练 600 到 1000 次更新、让自我对弈始终用最新的网络,70% 到 85% 是合理的目标。我们把这条诊断作为反馈补进题目,训练接着进行,结果见下一节。

把循环接上之后

从第 595 次更新起,我们只在题目里补了一条反馈:自我对弈必须始终使用最新的网络,和训练保持同步,并记录每批数据是落后几次更新的网络下出来的。没有给其他算法提示。训练在同一个工作区里接着进行。到第 1105 次更新时成绩已不再上升,我们停止了训练。

第 595 次更新之前之后
训练数据是多旧的网络下的约第 70 次更新后不再有新棋谱,末段数据落后 500 次以上更新全程每批最多落后 4 次更新,平均 2 次
自我对弈局数600 局又下了 3472 局

对纯 MCTS 的胜率

评估设置和上文相同:学出来的网络每步搜索 400 次,纯 MCTS 对手每步搜索 1000 次,先后手交替。评估由我们在独立容器里完成,不影响训练。

模型30 局(种子 777,与上文复算相同)100 局(种子 2024)
第 595 次更新18/30(先手 13/15,后手 5/15)—
第 695 次更新29/30(先手 15/15,后手 14/15)92/100(先手 50/50,后手 42/50,1 局平)
第 720 次更新27/30(先手 15/15,后手 12/15)90/100(先手 50/50,后手 40/50,1 局平)
第 895 次更新27/30(先手 15/15,后手 12/15)95/100(先手 50/50,后手 45/50,1 局平)
第 1045 次更新27/30(先手 15/15,后手 12/15)90/100(先手 50/50,后手 40/50,2 局平)
仓库自带模型26/30(先手 15/15,后手 11/15)94/100(先手 49/50,后手 45/50)

最好的是第 895 次更新:100 局赢 95 局,先手全胜,后手 45/50,和自带模型的 94 局(后手同样 45/50)打平。之后成绩回落到 90 局左右,所以我们停止了训练。30 局的结果波动较大:第 695 次更新 30 局赢 29 局,看上去已超过自带模型,换 100 局后是 92 局。这些差距都在 100 局的正常波动范围内,准确的说法是打平,不是超过。和第 595 次更新相比,后手胜率从三分之一升到八成以上,说明把自我对弈和训练接上确实是关键。

上方三张训练指标图里,第 595 次更新之后策略熵从约 2.8 降到 1.3 左右,网络落子明显更果断;损失降到 2 左右。价值网络的解释方差反而更低、波动更大:之后的经验池只保留最新的 512 个局面,之前的经验池有 1 万条,后期一直在同一批旧棋谱上训练,更容易拟合。所以这项指标前后不能直接比,胜率要看对局。

换到更难的 8×8 五子连珠。同样从零训练约 19 小时,最终模型对纯 MCTS 40 局赢 27 局(67.5%,先手 13/20、后手 14/20);仓库自带的 8×8 模型是 40 局全胜,这一题还有明显差距。

用的什么算法:AlphaZero

和 2017 年 DeepMind 的 AlphaZero 同一个思路,规模缩小到 6×6 棋盘、四子连珠。不看任何人类棋谱,只靠自己和自己下。

1 · 自我对弈

网络指导搜索

每走一步,用蒙特卡洛树搜索模拟 400 次。搜索时由网络提供"哪里值得看"和"这个局面谁占优",不做随机推演。

2 · 记录

留下训练样本

每一步记下三样东西:棋盘状态、搜索后的落子分布、这局最后谁赢了。再做 8 种旋转翻转,把数据扩大 8 倍。

3 · 训练

让网络学搜索

策略头去逼近搜索给出的落子分布,价值头去预测最终胜负。每更新一次用 512 个样本、过 5 遍。

4 · 循环

更强的网络下更好的棋

训练进程每次更新后发布新参数,自我对弈进程每 4 局重新加载一次,用更强的网络下出更好的数据,再训练,再循环。

选点规则(PUCT):a* = argmax [ Q(s,a) + c · P(s,a) · √N(s) / (1 + N(s,a)) ],c = 5
Q 是这一步的平均胜负,P 是网络给的先验概率,N 是访问次数。
项目设置
棋盘6×6,四子连珠
网络输入 4 个 6×6 平面(我方子、对方子、上一手、轮到谁),3 层 3×3 卷积(32、64、128 通道),策略头输出 36 个点的概率,价值头输出 −1 到 1 的估值
自我对弈8 个进程并行,每步 400 次搜索
训练每消化一局更新一次;批 512、过 5 遍;Adam,学习率 0.005,按 KL 散度自适应(目标 0.025,倍数上限 1.0);经验池 1 万条
规模共 1105 次更新、4072 局自我对弈,训练用时约 10.5 小时(第 595 次之前 5 小时 49 分,之后约 4 小时 47 分);agent 执行两段共约 14.8 小时(8.9 + 5.9)
第 595 次更新后的改动自我对弈每局开始前加载最新网络,和训练保持同步;经验池改为只保留最新 512 个局面
评估对手纯 MCTS:不用网络,每步 1000 次随机推演
框架Python 2.7、Theano 0.7、Lasagne,全程 CPU

我们是怎么找到这组提示的

本页展示的是 v5。在它之前,我们用同一道题做了几轮尝试,每一轮暴露的问题都变成了下一轮的一条提示。下面列出主要的几次,略去提前停止的 v1;这些尝试本身不是展示内容。

v0无提示

把时间花在反复审查自己的代码上(880 次 code-review),只做了最多 20 局的冒烟实验,网络没有学到东西,4 小时后超时。

v2软提示

提示"一小时内开训",它派出 23 个子 agent 审计仓库文档,74 分钟没开始训练。

v3硬提示

"20 分钟内必须开训"并禁用子 agent,它 20 分钟就搭好 12 进程并行训练;但每 50 局才更新一次,600 局只更新 12 次,网络没学会。

v4加节奏

补上仓库原版的训练节奏,损失和价值指标都在变好,复算胜率却只有 3%,最后上下文超限退出。

v5同 v4 + 研究流程 skill

从零训练到 60%;补上“自我对弈与训练同步”的反馈后接着训练,到 90%。它还自己发现并修正了评估脚本的一个判定错误:第一版把"谁是学出来的模型"弄反了,导致一半对局的胜负算反。

我们为什么要复算。v5 从十几个检查点里挑出第 275 次更新,报告 20 局赢 18 局,并注明置信区间很宽。它的评估让学出来的网络每步搜索 1000 次;我们改用仓库原版的设置,每步 400 次,并更换随机种子、增加到 30 局。在这个设置下,第 275 次更新是 43%,最终模型是 60%。在同一批对局上挑选最佳检查点可能高估表现,但两次评估的搜索预算也不同,差距不能全归因于挑选。上面的曲线全部来自我们的复算。