返回列表

[9th Place Solution] Cfish + Simple SPSA

643. FIDE & Google Efficient Chess AI Challenge | fide-google-efficiency-chess-ai-challenge

开始: 2024-11-18 结束: 2025-03-06 游戏AI AI大模型赛
[第 9 名解决方案] Cfish + 简单 SPSA

[第 9 名解决方案] Cfish + 简单 SPSA

作者: ymg_aq  |  发布时间: 2025-03-08  |  竞赛排名: 第 9 名

我分享获得第 9 名的解决方案。最终代码公开在以下链接:

GitHub 仓库 https://github.com/ymgaq/Cfish_kaggle

选择基础程序

在测试了多个国际象棋引擎后,我最终选择了 Cfish

正如其他顶级参与者所指出的,由于 glibc 的原因,Cfish 相比基于 C++ 的引擎具有内存消耗更低的优势。此外,在 Kaggle 的单核环境中,它的搜索速度似乎略优于 Stockfish。

内存优化

  • 移除了 NNUE,完全依赖 HCE 评估。
  • 将置换表 (Transposition Table) 大小减少到 1MB。
  • 反击着法历史 (Counter Move History):
    • 通过合并条件 (inCheck, CaptureOrPromotion) 减少分支 (减少 1/4)。
    • 将反击着法历史的索引从棋子改为棋子类型 (减少 1/2)。
  • 将物质价值表 (Material Table) 和兵型哈希表 (Pawn Hash Table) 大小减少到 1024。

这些调整使内存使用量约为 4MB。

二进制大小压缩

  • 移除了不必要的函数和类 (NNUE, Bench, TBProbe, PolyBook, NUMA 等)。
  • 移除了不必要的 UCI 选项。
  • 优化构建命令:
    • make build -j ARCH=x86-64-bmi2 EXTRACFLAGS="-ffunction-sections -fdata-sections" EXTRALDFLAGS="-Wl,--gc-sections"
  • 使用 strip 命令。
  • 使用 upx --lzma 压缩二进制文件。

这些减少使得二进制文件大小保持在 64KB 以下,即使使用 O3 优化而不是 Os。

增强搜索

Cfish 的搜索最初与 Stockfish13 匹配,但被修改为类似于 Stockfish16 的 HCE 搜索方法和参数。与原始搜索实现相比,此修改将引擎提高了约 +30 Elo。通过在 Kaggle 的 CPU 环境中使用 O3 而不是 Os 优化,平均搜索速度提高了约 8-9%。

SPSA

国际象棋引擎通常使用一种强大的黑盒优化方法,称为 SPSA (同步扰动随机逼近)。

简单来说,两个参数分别扰动 +δ 和 -δ 的引擎版本相互对抗,获胜版本的调整被接受。通过同时随机扰动和测试所有参数并重复比赛,识别出最佳参数。

虽然存在强大的 SPSA 库,如 fishtestOpenBench,但我选择了一个针对单机优化的简单自定义 SPSA 脚本。我的脚本 约 400 行,基于文献和可用的 Perl 实现。它利用 cutechess-cli 并在多个线程上并发运行 SPSA 测试,采用比赛的 2000 开局库和 10 秒时限控制。

这种简单的方法产生了约 +30 Elo 的改进,将我的解决方案推向了金牌。

考虑到排行榜 (LB) 的随机性,我提交了两个相同的二进制文件作为最终提交。

其他尝试(未采用)

  • 根据公开分享的笔记本测试了 Ethereal。
  • 评估了 Stockfish 6 到 16 所有 HCE 版本的内存优化策略。迁移到 Cfish 以满足 5MB 内存限制。
  • 尝试使用 bullet 训练 (768x2)-10-1 NNUE 网络,但不幸的是,我无法超越 HCE 的性能。
  • 时限控制参数的 SPSA 调整在 LB 测试中无效,因此未采用。

我发现其他利用 NNUE 和神经网络的获胜解决方案非常有趣,对于将我的方法完全限制在 HCE 上略感后悔。虽然这是我第一次开发国际象棋引擎,但在类似嵌入式系统的约束内进行优化证明是非常吸引人的。我向比赛组织者和所有参与者表示诚挚的感谢,感谢他们广泛而有价值的贡献。

同比赛其他方案