← 返回文章

在 NVIDIA Jetson AGX Orin 上编译 CUDA KataGo,并通过 SSH 接入 Sabaki

记录在 NVIDIA Jetson AGX Orin 上编译 CUDA KataGo,并通过 SSH 让 Mac 上的 Sabaki 调用远端引擎的完整配置经验。

#KataGo#Jetson#CUDA#Sabaki#围棋

在 NVIDIA Jetson AGX Orin 上编译 CUDA KataGo,并通过 SSH 接入 Sabaki

这篇文章记录一次完整的实践:在 Jetson AGX Orin 上编译 KataGo CUDA 版本,使用 Orin GPU 推理,再通过 SSH 让 Mac 上的 Sabaki 调用远端引擎;最后把原来本机的 5D、9D、10K 人类风格配置迁移到 Orin。

本文按 2026-08-13 的实际环境记录,账号密码等敏感信息不写入文章。

一、最终效果

最终在 Orin 上得到:

  • KataGo v1.17.2
  • stable 分支
  • CUDA + cuDNN 后端
  • 针对 AGX Orin 的 CUDA 架构 sm_87
  • 64GB AGX Orin,JetPack 6.2.1
  • Sabaki 通过 SSH key 无密码调用远端 KataGo
  • 普通 KataGo、5D、9D、10K 四个引擎都可以在 Sabaki 中选择

最终目录大致如下:

/home/wooley/KataGo/
├── katago                         # 便捷入口,指向 CUDA 二进制
├── default_gtp.cfg                # 默认 GTP 配置
├── default_model.bin.gz           # 普通 b18 网络
├── g170-b30c320x2-...bin.gz       # 5D/9D/10K 使用的主模型
├── b18c384nbt-humanv0.bin.gz      # 人类风格模型
├── gtp_human5d_search.cfg
├── gtp_human9d_search_example.cfg
├── gtp_human10k_search.cfg
└── cpp/build-cuda/katago           # 实际编译出的二进制

二、为什么选择 stable 分支

KataGo 上游仓库:

https://github.com/lightvector/katago

本次检查时,masterstablev1.17.2 指向同一个提交:

6a1fc5de9fc253723ac475a0683bf0b9d9b7bd19

如果只是个人使用,master 也可能可以编译;但 stable 更适合作为可复现的部署基线,官方编译说明也特别建议分布式相关构建使用 stable 或正式发布标签。

KataGo 有 CUDA、TensorRT、OpenCL 和 Eigen 等后端。Orin 是 NVIDIA GPU,CUDA 后端最直接;虽然本机也安装了 TensorRT,但第一次部署优先选择 CUDA + cuDNN,依赖更清晰、启动更快、排错更容易。

参考:

三、确认 Orin 的硬件和软件环境

登录远端机器:

ssh wooley@192.168.1.28

本次机器的关键环境是:

硬件:NVIDIA Jetson AGX Orin Developer Kit,64GB
系统:Ubuntu 22.04.5,aarch64
JetPack:6.2.1
L4T:36.4.7
CUDA:12.6.68
cuDNN:9.3.0
TensorRT:10.3.0.30
CPU 核心:12
内存:约 61GiB 可用总量

AGX Orin 的 CUDA Compute Capability 是 8.7,所以编译时可以明确指定:

CMAKE_CUDA_ARCHITECTURES=87

这样可以只生成 Orin 需要的机器码,避免编译 KataGo 默认配置中其他 GPU 架构,减少编译时间和二进制体积。

四、安装编译依赖

官方编译说明要求 CMake、C++ 编译器、CUDA、cuDNN,以及 zlib、libzip 等依赖。Orin 上已有 g++、Git、CUDA 和 cuDNN,但没有 CMake 和部分开发包,因此安装:

sudo apt-get update
sudo apt-get install -y \
  cmake \
  build-essential \
  libzip-dev \
  zlib1g-dev \
  libssl-dev \
  libeigen3-dev

实际安装后使用的是 CMake 3.22.1、g++ 11.4.0。

经验:Ubuntu 的 apt 镜像在某些网络环境下可能非常慢。如果 apt-get update 长时间不动,不要重复启动多个安装进程,先等待当前进程结束,或者更换镜像源。

五、获取 KataGo 源码

标准方式是直接克隆 stable 分支:

git clone \
  --branch stable \
  --single-branch \
  --depth 1 \
  https://github.com/lightvector/katago.git \
  ~/KataGo

本次实践中,Orin 直接从 GitHub 克隆的速度非常慢,因此改用本地下载源码压缩包,再通过局域网传输:

curl -L --fail \
  https://codeload.github.com/lightvector/katago/tar.gz/refs/heads/stable \
  -o /tmp/katago-stable.tar.gz

scp /tmp/katago-stable.tar.gz \
  wooley@192.168.1.28:/home/wooley/

然后在 Orin 上解压到 ~/KataGo

压缩包不包含 .git 目录,所以后面 CMake 配置需要加:

-DNO_GIT_REVISION=1

这个选项只是不把 Git 提交号嵌入二进制,不影响 KataGo 的运行。若使用完整 Git clone,则可以不加这个选项。

六、配置并编译 CUDA 版本

进入源码目录,使用 CMake 配置:

cmake \
  -S "$HOME/KataGo/cpp" \
  -B "$HOME/KataGo/cpp/build-cuda" \
  -DUSE_BACKEND=CUDA \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_CUDA_ARCHITECTURES=87 \
  -DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc \
  -DCUDAToolkit_ROOT=/usr/local/cuda \
  -DNO_GIT_REVISION=1

如果 CMake 找不到 cuDNN,可以额外检查:

ls -l /usr/include/cudnn.h
ls -l /usr/lib/aarch64-linux-gnu/libcudnn.so*

必要时手动指定 cuDNN 路径,例如:

-DCUDNN_INCLUDE_DIR=/usr/include
-DCUDNN_ROOT_DIR=/usr

开始编译:

cmake --build "$HOME/KataGo/cpp/build-cuda" --parallel 8

Orin 有 12 个 CPU 核心,本次使用 8 个并行任务。若设备同时运行其他服务,建议用 --parallel 4,避免编译时占满 CPU 和内存。

编译成功后检查:

~/KataGo/cpp/build-cuda/katago version

应看到类似:

KataGo v1.17.2
Using CUDA backend
Compiled with CUDA version 12.6.68

七、准备普通模型并验证 GPU

KataGo 引擎本身不包含神经网络模型,需要另外下载。第一次验证使用官方 b18 网络:

kata1-b18c384nbt-s9492280320-d4181591514.bin.gz

官方网络页面:

https://katagotraining.org/networks/

将模型放到:

~/KataGo/default_model.bin.gz

复制默认配置:

cp ~/KataGo/cpp/configs/gtp_example.cfg \
   ~/KataGo/default_gtp.cfg

由于 KataGo 按实际二进制所在目录寻找默认配置和模型,而编译出的二进制位于 cpp/build-cuda,可以建立符号链接:

ln -s ../../default_model.bin.gz \
  ~/KataGo/cpp/build-cuda/default_model.bin.gz

ln -s ../../default_gtp.cfg \
  ~/KataGo/cpp/build-cuda/default_gtp.cfg

ln -s cpp/build-cuda/katago \
  ~/KataGo/katago

执行 benchmark:

cd ~/KataGo
./katago benchmark \
  -model ~/KataGo/default_model.bin.gz \
  -config ~/KataGo/default_gtp.cfg \
  -v 200 \
  -n 2 \
  -t 1,2,4,6,8,12 \
  -i 1

实际运行时可以看到:

Cuda backend thread 0: Found GPU Orin
compute capability major 8 minor 7
useFP16 = true
useNHWC = true

本次短 benchmark 的结果大致是:

搜索线程 visits/s
1 110
2 131
4 255
6 395
8 412
12 470

如果目标是约 1 秒一手棋,12 线程是本次测试的推荐值;如果使用固定 visits,线程数不一定越高越强,因为线程过多会增加 MCTS 并行搜索损失。

八、先做一次 GTP 协议验证

printf '%s\n' \
  name \
  version \
  'boardsize 9' \
  'komi 7.5' \
  'play b D4' \
  'genmove w' \
  quit | \
  ~/KataGo/katago gtp \
    -model ~/KataGo/default_model.bin.gz \
    -config ~/KataGo/default_gtp.cfg

只要看到 GTP ready,并且 genmove 返回合法着法,就说明二进制、CUDA、模型和 GTP 协议都正常。

一个容易踩的坑是 shell 会把带空格的 GTP 命令拆开。下面这种写法会产生空命令或参数错误:

printf '%s\n' boardsize 9 komi 7.5 genmove b quit

应把完整命令放进引号:

printf '%s\n' 'boardsize 9' 'komi 7.5' 'genmove b' quit

九、为 Sabaki 配置 SSH key

Sabaki 启动引擎时不能方便地交互输入 SSH 密码,因此应使用 SSH key。

本机原来已经有:

~/.ssh/id_rsa
~/.ssh/id_rsa.pub

将公钥复制到 Orin:

ssh-copy-id \
  -i ~/.ssh/id_rsa.pub \
  wooley@192.168.1.28

然后测试无密码登录:

ssh -T \
  -i ~/.ssh/id_rsa \
  -o BatchMode=yes \
  -o IdentitiesOnly=yes \
  wooley@192.168.1.28 \
  'printf "SSH key works: %s@%s\\n" "$USER" "$(hostname)"'

成功后,Sabaki 就不需要保存 SSH 密码。建议实际部署后删除或轮换临时使用过的密码,并优先使用专用 SSH key。

十、创建 Sabaki 的本机 SSH 包装脚本

Sabaki 需要启动一个本机可执行文件。最稳妥的方式是在 Mac 上创建一个很薄的包装脚本,由它负责 SSH 到 Orin,再启动远端 KataGo。

普通引擎脚本示例:

#!/bin/zsh

exec /usr/bin/ssh \\
  -T \\
  -o BatchMode=yes \\
  -o IdentitiesOnly=yes \\
  -o StrictHostKeyChecking=yes \\
  -o ConnectTimeout=10 \\
  -o ServerAliveInterval=30 \\
  -o ServerAliveCountMax=3 \\
  -i /Users/guwei/.ssh/id_rsa \\
  wooley@192.168.1.28 \\
  '/home/wooley/KataGo/katago gtp -model /home/wooley/KataGo/default_model.bin.gz -config /home/wooley/KataGo/default_gtp.cfg -override-config "logAllGTPCommunication=false,logSearchInfo=false"'

保存为 katago-orin-ssh,并设置可执行:

chmod +x ~/Documents/KataGO/katago-orin-ssh

其中:

  • -T 禁用伪终端,避免远端 shell 提示符混进 GTP 输出
  • BatchMode=yes 保证没有 key 时快速报错,而不是卡住等待密码
  • StrictHostKeyChecking=yes 避免连接到未知主机
  • exec 让 Sabaki 的进程管理更干净
  • 两个日志选项只用于减少 Sabaki 控制台噪声,不改变中国规则或搜索参数

测试包装脚本:

printf '%s\n' name version quit | \
  ~/Documents/KataGO/katago-orin-ssh

十一、把普通 KataGo 加入 Sabaki

Sabaki 版本为 0.52.2,配置文件位于:

~/Library/Application Support/Sabaki/settings.json

推荐优先使用 Sabaki 的引擎管理界面新增引擎:

名称:KataGo Orin SSH
路径:/Users/guwei/Documents/KataGO/katago-orin-ssh
参数:留空

参数留空是因为远端模型、配置和 SSH 参数已经写在包装脚本里。

如果直接编辑 JSON,一定先备份:

cp \
  "$HOME/Library/Application Support/Sabaki/settings.json" \
  "$HOME/Library/Application Support/Sabaki/settings.json.bak"

对应的引擎项类似:

{
  "name": "KataGo Orin SSH",
  "path": "/Users/guwei/Documents/KataGO/katago-orin-ssh",
  "args": "",
  "commands": ""
}

修改后重启 Sabaki,在引擎列表中选择 KataGo Orin SSH

十二、迁移 5D、9D、10K 人类风格配置

这里有一个重要概念:5D、9D、10K 不是三个完全不同的神经网络。它们主要是:

  1. 同一个普通主模型
  2. 同一个人类监督模型 b18c384nbt-humanv0.bin.gz
  3. 不同的搜索配置和 humanSLProfile

原来本机 Homebrew KataGo 使用的文件是:

/opt/homebrew/Cellar/katago/1.15.3/share/katago/g170-b30c320x2-s4824661760-d1229536699.bin.gz
/opt/homebrew/Cellar/katago/1.15.3/share/katago/b18c384nbt-humanv0.bin.gz
/opt/homebrew/Cellar/katago/1.15.3/share/katago/configs/gtp_human5d_search.cfg
/opt/homebrew/Cellar/katago/1.15.3/share/katago/configs/gtp_human9d_search_example.cfg
/opt/homebrew/Cellar/katago/1.15.3/share/katago/configs/gtp_human10k_search.cfg

通过局域网复制到 Orin:

scp \
  /opt/homebrew/Cellar/katago/1.15.3/share/katago/g170-b30c320x2-s4824661760-d1229536699.bin.gz \
  /opt/homebrew/Cellar/katago/1.15.3/share/katago/b18c384nbt-humanv0.bin.gz \
  /opt/homebrew/Cellar/katago/1.15.3/share/katago/configs/gtp_human5d_search.cfg \
  /opt/homebrew/Cellar/katago/1.15.3/share/katago/configs/gtp_human9d_search_example.cfg \
  /opt/homebrew/Cellar/katago/1.15.3/share/katago/configs/gtp_human10k_search.cfg \
  wooley@192.168.1.28:/home/wooley/KataGo/

三份配置的关键区别:

配置 规则 humanSLProfile maxVisits 线程
5D chinese preaz_5d 400 8
9D chinese preaz_9d 400 8
10K chinese preaz_10k 100 1

可以用下面命令确认规则和 profile:

grep -E 'rules|humanSLProfile|maxVisits|numSearchThreads' \
  ~/KataGo/gtp_human5d_search.cfg \
  ~/KataGo/gtp_human9d_search_example.cfg \
  ~/KataGo/gtp_human10k_search.cfg

为每个配置创建一个包装脚本,区别只在远端配置文件:

katago-orin-5d   -> gtp_human5d_search.cfg
katago-orin-9d   -> gtp_human9d_search_example.cfg
katago-orin-10k  -> gtp_human10k_search.cfg

远端命令的共同部分是:

/home/wooley/KataGo/katago gtp \
  -model /home/wooley/KataGo/g170-b30c320x2-s4824661760-d1229536699.bin.gz \
  -human-model /home/wooley/KataGo/b18c384nbt-humanv0.bin.gz \
  -config /home/wooley/KataGo/gtp_human5d_search.cfg \
  -override-config "logAllGTPCommunication=false,logSearchInfo=false"

然后在 Sabaki 中把原来的三个引擎改成:

KataGo5D   -> /Users/guwei/Documents/KataGO/katago-orin-5d
KataGo9D   -> /Users/guwei/Documents/KataGO/katago-orin-9d
KataGo10k  -> /Users/guwei/Documents/KataGO/katago-orin-10k

三个引擎的参数栏都留空。

十三、逐个验证人类风格引擎

不要只检查 Sabaki 列表是否出现,最好从命令行逐个启动:

printf '%s\n' \
  name \
  version \
  'boardsize 9' \
  'komi 7.5' \
  'genmove b' \
  quit | \
  ~/Documents/KataGO/katago-orin-5d

将脚本名替换为 katago-orin-9dkatago-orin-10k 重复测试。

正常输出应包含:

Using Chinese rules initially
Loaded model g170-b30c320x2-s4824661760-d1229536699
Loaded human SL model b18c384nbt-humanv0
GTP ready, beginning main protocol loop

并且 genmove b 返回一个合法着法。

十四、这次实践中最有价值的经验

1. 先确认 GPU 架构,再决定编译参数

Orin 使用 sm_87。强制指定 CMAKE_CUDA_ARCHITECTURES=87 可以明显减少无关架构的编译工作。

2. CUDA 后端不等于只安装 CUDA

KataGo CUDA 后端还需要 cuDNN。CMake 阶段要同时确认 nvcccudnn.hlibcudnn.so 都存在。

3. 编译成功不代表运行成功

至少要做三层验证:

  1. katago version
  2. benchmark 并确认识别到 Orin compute capability 8.7
  3. GTP genmove 返回合法着法

4. Sabaki 连接远端引擎时,包装脚本比直接写 SSH 命令更可靠

包装脚本可以固定 SSH key、绝对路径、日志选项和远程配置,Sabaki 只负责启动一个本地可执行文件。

5. 不要让 Sabaki 保存 SSH 密码

使用 SSH key 后,Sabaki 启动引擎不需要交互输入密码,也不会把密码写进引擎配置。

6. 5D/9D/10K 的区别主要来自配置

迁移时不要误以为需要三套完全不同的网络。真正需要的是同一个主模型、同一个人类模型和三份搜索配置。

7. 远端下载慢时,利用本地网络传输

源码和模型从外网下载慢时,可以先在网络条件较好的电脑下载,再用 scp 通过局域网复制到 Orin,通常更稳定。

十五、常见故障排查

Sabaki 启动后提示找不到模型

优先在包装脚本中使用模型和配置的绝对路径,不依赖当前工作目录:

/home/wooley/KataGo/default_model.bin.gz
/home/wooley/KataGo/default_gtp.cfg

Sabaki 一直 loading

先在终端运行对应包装脚本:

printf '%s\n' name version quit | \
  ~/Documents/KataGO/katago-orin-5d

如果终端也卡住,检查 SSH key;如果终端正常,检查 Sabaki 的路径和参数栏是否重复填写了命令。

GTP 控制台出现远端 shell 提示符

检查 SSH 命令是否包含:

-T

并确保包装脚本最后使用 exec 启动 SSH。

编译时找不到 CUDA

检查:

which nvcc
nvcc --version
ls -l /usr/local/cuda

并在 CMake 中明确指定:

-DCMAKE_CUDA_COMPILER=/usr/local/cuda/bin/nvcc
-DCUDAToolkit_ROOT=/usr/local/cuda

运行时没有使用 GPU

正常启动日志应出现:

Cuda backend thread 0: Found GPU Orin

如果没有,检查是否误用了旧的 Eigen/OpenCL 二进制,或者 Sabaki 仍然指向本机 Homebrew KataGo。

十六、最终推荐

  • 普通分析:使用 KataGo Orin SSH
  • 想要人类风格 5D:使用 KataGo5D
  • 想要人类风格 9D:使用 KataGo9D
  • 想要较弱、较自然的业余棋风:使用 KataGo10k
  • 需要更强的普通分析时,可换用官方最新网络,但要重新 benchmark
  • 不建议同时在 Sabaki 中启动多个大型引擎实例,避免重复占用 GPU 显存和 CPU 线程

这套方案的核心思路是:Orin 负责 CUDA 推理,Mac 只运行 Sabaki 和 SSH 包装脚本;这样界面和引擎解耦,后续升级模型或调整配置时,不需要重新改 Sabaki 的连接方式。