3.5 NNUE 神经网络评估(进阶)
这是一节进阶,但极其重要——因为 NNUE 正是当今最强引擎 Stockfish 的核心。它解决一个看似矛盾的难题:既想要神经网络评估的强,又要快到能塞进每秒搜千万个局面的 CPU α-β 里。它的答案是“增量更新”,巧妙得值得专门讲一节。本节也是国象的 GPU 训练章。
一、动机:又要网络的强,又要极致的快
上一节我们想用神经网络取代手工评估。但国象引擎和 AlphaZero 有个关键差别:AlphaZero 每步只跑几百次较慢的大网络推理,而传统 α-β 引擎每秒要评估几百万、上千万个局面。如果每个局面都老老实实跑一遍神经网络,再强也会被慢死——一秒评不了几个,搜索深度直接崩盘。
所以 NNUE(Efficiently Updatable Neural Network,反着念)的设计目标很明确:它是一个神经网络,但必须快到几乎不拖慢 α-β。怎么做到?靠一个和我们 2.6 学过的“增量更新”一脉相承的把戏。
二、架构与增量更新:快的秘密
NNUE 是个不大的网络(不像 AlphaZero 那种深 ResNet),输入是一种超大但极稀疏的特征——典型是“(王的位置, 某个子, 它所在格)”这类组合,几万维里只有几十维是 1(因为盘上就那么几十个子)。它的第一层很宽,把这些稀疏特征映射成一个向量,这个向量叫累加器(accumulator)。
秘密就在累加器上:每走一步,棋盘只变了一两个子,所以累加器不必从头重算,只要把“离开的子”减掉、“到来的子”加上即可——几十个数的加减,快到几乎免费。这和 2.6 的 Zobrist 哈希简直如出一辙:
同一个洞察,第三次出现了。Zobrist 哈希靠 XOR 增量更新(2.6)、五子棋判负只扫落子点四方向(2.1)、NNUE 靠累加器增量更新——“局面只变一点点,就别全部重算”是棋类引擎里反复奏效的核心思想。NNUE 不过是把它用到了神经网络的第一层上。
累加器之后接几层很小的全连接,输出一个评估分。整个网络小、且大部分计算被增量更新省掉了,于是它既有神经网络的判断力,又快得能嵌进 CPU 的 α-β。
三、在 5070 Ti 上训练 NNUE
NNUE 的训练和 AlphaZero 不同:它不是“策略+价值”双头,而是一个纯粹的评估回归器——给它海量局面,让它学着输出“这个局面值多少分”。训练数据通常来自已有强引擎(比如 Stockfish 自己)对海量局面的评分,或自对弈对局的结果;损失就是“网络输出 vs 目标分”的回归误差。
环境照旧用 1.7 那套(独立 conda + cu128 PyTorch,Blackwell sm_120 已验证)。规模上 NNUE 网络很小,5070 Ti 训它毫不费力——瓶颈在准备海量带标注的训练局面,而不在算力。要点:
- 数据是关键:几亿个 (局面, 评分) 样本,质量和数量都要够。
- 用 bf16、大 batch:网络小,可以开很大的 batch 喂满显卡。
- 量化:训练用浮点,部署时把权重量化成整数(int8/int16),让 CPU 推理再快一截——这是 NNUE 工程的标志性步骤。
四、接入 α-β,对比手工评估
训练好的 NNUE,用法和 2.8 的混合引擎一模一样:把 3.4 那个手工 evaluate() 整个换成 NNUE 的输出,搜索框架一行不动。结果是棋力的大幅跃升——这也正是 Stockfish 在 2020 年引入 NNUE 后实力大涨的原因。
到这里有个值得回味的呼应:第二章五子棋的“混合引擎”(NN 评估 + α-β + VCF),和国象的“NNUE + α-β”,本质是同一件事——都是用神经网络做评估、用经典搜索做精确计算。两个看似不同的棋种、不同的社区,最后都殊途同归走到了“神经网络 + 搜索”的融合上。这不是巧合,而是这条路确实最强。
五、小结与下一节
- 动机:要网络的强,又要快到能塞进每秒千万次评估的 α-β。
- 增量更新:超稀疏输入 + 累加器,走一步只加减变化的几个子——同 Zobrist 的“别全重算”思想。
- 训练:纯评估回归器,数据是关键,5070 Ti 算力绰绰有余;部署时量化提速。
- 融合:NNUE + α-β 与五子棋的混合引擎同构——“神经网络评估 + 经典搜索”是普适的最强路线。
自己造引擎讲到这就够深了。下一节 3.6 把 Stockfish 当工具用,我们换个务实视角:与其从零造,不如直接调用世界最强的开源引擎——这也正是 ANIMA 把下棋当“技能/工具”的思路。