用 10 亿棋局蒸馏 Stockfish:Gigafish 数据集与 79M 混合架构模型
Distilling Stockfish with One Billion Positions
开发者从 Lichess 开放数据库提取 39 亿个棋局的 FEN 与 Stockfish 评估,去重后以 depth 10 标注,构建出据称最大的开源状态价值国际象棋数据集 Gigafish,并发布在 HuggingFace。
简而言之:我提取了 39 亿个国际象棋局面的 fens 和 stockfish 评估值。然后我用其中 10 亿个训练了一个神经网络。据我所知,这是已发布的最大的开放状态-价值国际象棋数据集。该数据集以 Huggingface 上的 Gigafish 数据集形式发布。

在整个训练过程中,损失持续下降,这强烈表明数据量的重要性。
Stockfish 是目前世界上最强的国际象棋引擎。它的工作方式是对每个局面使用一个小型神经网络数百万次。一个有趣的问题是,我们能否用更准确的价值函数来替代搜索深度。2024 年,DeepMind 的研究人员尝试回答这个问题。关键的是,这种方法没有保持搜索深度不变,尽管他们有 150 亿个动作-价值对,但只有大约 5.3 亿个状态-价值估计。
一个局面的 stockfish 评估值能很好地指示获胜概率,所以我想重新审视这个问题。为此,我构建了一个固定搜索深度的大型状态-价值数据集,并尝试了不同的模型架构。
注意力并非你所需的一切
我训练了三大类架构的变体:纯 Vision Transformer、纯 ResNet,以及 ResNet 块后接 Transformer 块的混合架构。
我进行了试点运行,以缩小到最适合此任务的架构。第一次试点运行训练了一个 40M 参数的变体,很快就发现混合架构和 ResNet 架构明显优于纯 vision transformer。与 ResNet 和混合架构相比,vision transformer 无法从卷积提供的归纳偏置中受益。它实际上需要从头学习什么是二维网格。

在第一次试点运行中,vision transformer 明显不如 ResNet 和混合架构。
然后我进行了一次扩大规模的 80M 参数试点运行,以比较纯 ResNet 与混合架构。从损失曲线可以看出,ResNet 受益于其关于棋盘的归纳偏置,因此纯 ResNet 模型上的损失迅速下降。然而,它难以学习准确评估所必需的更细微的全盘关系,学习速度较慢。
混合方法让我们兼得两者之长。ResNet 块快速学习空间模式并将其输入 Transformer 块。这也是 transformers 以数据饥渴著称的部分原因:它们可以持续处理海量数据集。

从第二次试点运行中我们可以看到,混合方法既受益于卷积提供的归纳偏置,也受益于注意力块的全局推理。
输入格式
模型的输入格式都相同:
- 6 个 8x8 位棋盘,表示行棋方棋子
- 6 个 8x8 位棋盘,表示对手棋子
- 6 个“元”平面,编码王车易位权、完整回合计数器等信息
使用的损失函数
训练任务是预测从行棋方视角的评估值。(换句话说,如果当前玩家正在获胜,预测的百分比应 >50%。)模型有 103 个输出 logits。前 101 个桶映射到 0% 到 100% 的获胜概率。最后两个桶处理强制将杀。
损失由两个部分组成:一个是交叉熵分量(CE),用于惩罚正确桶之外的预测概率质量;另一个是序数分量(ORD),用于惩罚远离正确桶的预测。这两个损失以加权和的方式组合。
训练细节
最终的混合架构是一个 79M 参数的模型,由 6 个 ResNet 块输入到 16 个 Transformer 块。它使用 AdamW 训练,学习率为 1e-4,预热约 20M 个样本,批量大小为 1024。
结果
训练开始时总损失超过 7.0。到训练结束时,CE 损失稳定在 2.49,ORD 项稳定在 0.29,总训练损失约为 2.64。在约 5 万个局面的留出验证集上,模型达到了 2.648 的验证损失。
其他指标更能说明问题。方向准确率,即模型是否正确预测哪一方占优,达到了 92.97%。换句话说,给定一个任意局面,模型在约 20 次中有 19 次与 Stockfish 就哪一方占优达成一致,考虑到数据集中不明确局面的数量,这相当令人印象深刻。
对于没有强制将杀的局面,模型预测的获胜概率平均偏差约 4–5 个百分点。将这些获胜概率转换回 Stockfish 厘兵值,在从几乎必败到几乎必胜的完整范围内,厘兵 MAE 为 64 cp。
由于计算资源限制,我决定将训练上限设为 10 亿个局面,这花了大约三天。但从损失曲线来看,仍有大量性能尚未挖掘。
对阵 Stockfish 的表现
由于我们使用深度 10 的 Stockfish 作为教师,我们应该预期模型的表现大约与深度 10 的 Stockfish 相当,但会有一些小误差。

在不同搜索深度下对阵 Stockfish 的胜、和、负百分比。在深度 7 之前,它下得相当不错,但到深度 9 时,它大多在输或和。
构建 Gigafish 数据集
该数据集由 Lichess Open Database 构建,使用了 37 个月对局中的局面。我首先使用一个多线程 Rust 脚本从每盘对局中提取 fen 局面。
接下来,我对 fen 进行了去重,因为许多局面在数据集中被过度代表。我用磁盘上的简易 map-reduce 完成了这项工作:对每个 fen 进行哈希,并将其追加到与哈希前 12 位对应的文件中。这产生了 4096 个单独文件,它们足够小,可以在 RAM 中使用哈希集分别去重。
最后,我用深度 10 的 Stockfish 对每个剩余 fen 进行了标注。虽然这是一个高度并行的任务,但即使分布在 24 个核心上,也花了一天多的计算时间。
据我所知,这是最大的开放 (position, eval) 国际象棋数据集。ChessBench 数据集有更多的数据点,但那些是状态-动作-价值(局面 + 着法 + 评估),并且不是在固定搜索深度下计算的。
来源:Hacker News · blog.lukesalamone.com