Build Notes(全記録)
囲碁ソルバー Phase 1「動く版」スナップショット
作成: 2026-07-15(Claude Code)
参照: E:\go\go_solver_build_handover.txt(引き継ぎ書)
結論
online-fine-tuning-solver(NeurIPS 2023)の killallgo ソルバを Docker不使用・WSL2ネイティブでビルドし、 リポジトリ同梱の学習済みPCNモデルで、ドキュメント記載の参照問題2問の判定再現に成功。 RTX 5090(sm_120)上でlibtorch推論が動作。
スナップショット(動く版の固定点)
| 項目 | 値 |
|---|---|
| OFTS | df2d80c(branch neurips2023) |
| minizero submodule | 06e6811(2023-02-07) |
| chat submodule | 96014ac |
| libtorch | 2.8.0+cu128(shared-with-deps, ~/Projects/go/libtorch) |
| CUDA toolkit | 12.8(V12.8.61, /usr/local/cuda-12.8) |
| GPU / driver | RTX 5090(sm_120)/ 595.79(CUDA 13.2対応) |
| gcc / cmake | 13.3.0 / 3.28.3 |
| boost / pybind11 | 1.83.0 / 2.11.1(apt) |
| ビルドコマンド | cmake -DCMAKE_BUILD_TYPE=Release -DGAME_TYPE=KILLALLGO -DCMAKE_PREFIX_PATH=~/Projects/go/libtorch -DCUDAToolkit_ROOT=/usr/local/cuda-12.8 |
| 成果物 | build/killallgo/killallgo_solver(65MB), chat/chat |
※ minizero master の Dockerfile ピン(参考): CUDA 12.9.1 + torch 2.9.0+cu128 + libtorch 2.8.0+cu128。 ※ 推論バックエンドは libtorchのみ。TensorRTは不使用(リポジトリ全体にTRT参照なし)→ 引き継ぎ書§2の懸念どおり「TRT11でビルド」の前提は消滅。
適用パッチ(2箇所のみ)
CMakeLists.txt(OFTSルート):find_package(Torch)の直後にfind_package(Python COMPONENTS Interpreter Development.Module REQUIRED)を追加。 理由: libtorchのCMakeが先にPythonをInterpreterのみでfindするため、pybind11のpython_add_libraryが未定義になる(find_packageはディレクトリスコープなのでトップレベルに置く)。minizero/minizero/environment/chess/bitboard.h:#include <cstdint>を追加。 理由: gcc 13で暗黙の推移的includeが削除された。
動作検証(docs/Launch-the-Standalone-Solver.md の参照問題)
設定: 学習済みモデル training/gpcn_n32_m16_empty_op/model/weight_iter_100000.pt(リポジトリ同梱、35MB TorchScript)
- 文書記載パラメータ(rzone/block_tt/GHI check有効、situational superko、simulation上限10000)。
| 問題 | 本環境の出力 | docs期待値 | 判定 |
|---|---|---|---|
| 1(証明) | 1 1 40c1cffff 1112 "" |
1 1 2060c1cffff 1513 "" |
status一致(1=証明) |
| 2(反証) | 2 -1 21c3fff 214 "20c1e7c:0:20c1654;0" |
2 -1 a1c3e7c 245 "" |
status一致(-1=反証) |
- ノード数/RZ形状の差は、libtorch世代差によるNN出力の微小な浮動小数点差と マルチスレッド(4スレッド×32並列)の非決定性で探索順序が変わるためと解釈。
- 要追跡: 問題2で本環境のみGHI注釈が出た。判定は一致しているが、Phase 3の GHI/コウ正当性検証の題材にする。
- GPU動作確認: solve中にVRAM 690MiB(モデル+CUDAコンテキスト)。
環境の罠と回避策(この機体固有)
- WSL2のNAT経路はバルクDLが激遅(35〜80KB/s。VPN常駐時のWSL NAT劣化。Windows側は47MB/s)。
→ 大容量ファイルは
powershell.exe経由でcurl.exeを使いWindows側でDLし、/mnt/e経由で持ち込む。 libtorch 3.76GBが51秒で落ちた。memory.db の rules にも登録済み。 - OFTSサブモジュールのURLはSSH形式 →
git -c url."https://github.com/".insteadOf="git@github.com:" submodule update --init --recursive - libtorch展開後、Dockerfile踏襲で
share/cmake/Caffe2/public/cuda.cmakeのPython::Interpreter→${Python_EXECUTABLE}にsed(minizero公式Dockerfileと同じ対処)。 - TensorRT 11.0.0が既にシステム導入済み(
libnvinfer.so.11.0.0)。本プロジェクトでは未使用だが 将来の「PCN推論のTRT化」は発展課題として面白い。
Phase 2「CUDA 13.2へ登る」完了記録(2026-07-15)
方針: ユーザー指定により CUDA 13.2 + TRT 11.0(=既存環境そのまま、ドライバ更新なし) をターゲットに変更。
TRT 11.0.0.114は+cuda13.2パッケージでこの機体のドライバ上限(13.2)と一致。ソルバ本体はTRT不使用。
到達点
| 構成 | ビルド | 回帰(参照問題1/2) |
|---|---|---|
| libtorch 2.8.0+cu128 + CUDA 12.8(動く版) | ✓ | 1 40c1cffff 1112 / -1 21c3fff 214 |
| libtorch 2.9.1+cu130 + CUDA 13.2 toolkit | ✓ 追加パッチ0 | status/rzone/GHI完全一致(1114ノード±2) |
| libtorch 2.11.0+cu130 + CUDA 13.2 toolkit(最新) | ✓ 追加パッチ0 | 完全一致 |
- 公式libtorchのCUDA 13系は「cu130」のみ(cu132は存在しない)。cu130はマイナー互換で13.2環境上で動作
- ビルドdir:
build/killallgo_cu130_291/build/killallgo_cu130_2110(Phase 1のbuild/killallgoは温存) - 解答時間: 3〜5秒/問(3世代とも同等)
遭遇した山: cudartシンボル横取りSIGSEGV(今回の最重要知見)
症状: cu130系バイナリが起動直後にSIGSEGV。バックトレースはWSLドライバの
libnvidia-ptxjitcompiler.so.1内__strlen_avx2、呼出元はシステムの/usr/local/cuda-13.1/lib64/libcudart.so.13。
原因: TorchConfig経由で実行ファイルがシステムのlibcudart.so.13をリンクする。
動的リンクのシンボル解決優先順(実行ファイルの依存が先)により、libtorch同梱のcudart 13.0
(libcudart-<hash>.so.13)ではなくシステムcudart 13.1が全cudart呼び出しを乗っ取る。
13.0でビルドされたlibtorchのfatbin登録と13.1 cudartが混線しPTX JIT経路でクラッシュ。
- Phase 1(cu128)が無事だった理由: 実行ファイルの要求が
libcudart.so.12で、解決先が 12.8(libtorchと同版)だったため横取りされても無害だった LD_LIBRARY_PATH(~/.bashrc 119行目で/usr/local/cuda-13.1/lib64をexport)を消しても、 ldconfig経由で13.1が解決されるため不十分- cu130のlibtorch_cuda.soはsm_120のSASS同梱(cuobjdumpで確認: sm_75〜sm_120、PTXなし)。 JITが走ること自体が異常のシグナル
対策(regress.sh実装済み):
- 実行時:
env -u LD_LIBRARY_PATH LD_PRELOAD=<libtorch>/lib/libcudart-<hash>.so.13 <solver> - 恒久: 各libtorchのlibに
ln -s libcudart-<hash>.so.13 libcudart.so.13(RUNPATH解決用) - 検証: LD_PRELOAD適用でスモークテスト全項目PASS、ソルバ回帰完全一致
もう一つの罠: workerのstdin EOF挙動
echo 問題 | killallgo_solver -mode workerのようにstdinを即EOFにすると、探索完了前に
シャットダウンして結果が出ないことがある(分散運用前提の2023年コードの仕様。レース依存)。
→ regress.shはFIFOでstdin write端を保持し、結果行を検出したら閉じる方式。
残メモ
- 問題2のGHI注釈
"20c1e7c:0:20c1654;0"は3世代とも同一に出る(docsの期待値は"")。 toolchainドリフトではなく本環境の探索経路の性質。Phase 3のGHI検証題材。 - 学習パイプライン(PCN再学習)を回す場合はPython側torch(cu130系)をuvで用意する。
- 将来のTRT化はTRT 11.0(+cuda13.2)でそのまま着手可能。TRT 11.1はCUDA 13.3前提なので ドライバ更新まで保留。
Phase 3「分散ソルバによる求解再現」記録(2026-07-15)
到達点: EASY-smallセット37/37問を分散求解で証明
単一マシン(1×RTX 5090 + 285K)上に論文の分散構成を再現し、EASY-small全37問を証明。
- 36問はデフォルト設定(SIM=1e6, PCN=16.5)でwin。合計1901秒(最短4.9s、最長375s=EASY-36)
- EASY-44のみ result「?」 → 原因究明の結果、本システムの正しさ担保機構が見えた(下記)
- 結果一覧:
EASY_RESULTS.txt/ 各問題の.stat/.jobs/.sgf/.7esgfはOFTSリポジトリ直下
構成(tmuxセッションsolver)
| 窓 | 内容 |
|---|---|
| chat | scripts/chat/start-service.sh 8888(モニタ: nc localhost 8888) |
| broker | CHAT=localhost:8888 scripts/chat/broker.sh b1 |
| worker | CHAT=localhost:8888 CUDA_VISIBLE_DEVICES=0 LD_PRELOAD=<2.11のcudart> scripts/chat/worker.sh W1-0 b1 |
| manager | CHAT=localhost:8888 LD_PRELOAD=... scripts/run-manager.sh killallgo <ID> BROKER=b1 CVD=0 ONLINE=false SIM=1000000 |
- ワーカのソルバ設定(chat経由):
solver cmdline build/killallgo/killallgo_solver -conf_file config/worker.cfg -mode worker -conf_str "actor_num_parallel_games=48"→solver launch build/killallgoはkillallgo_cu130_2110へのsymlinkに変更(旧2.8バイナリはkillallgo_cu128_280)- 一発コマンド送信ヘルパ:
~/Projects/go/chatcmd.sh "b1 << query status" - LD_PRELOAD(cudart対策)はworker.shとrun-manager.shの起動環境に注入(子プロセスへ伝播)
RAMプロファイル(memory=55GB WSLでの実測)
- ワーカ(48並列×sim10万): 高水位約31GBでプラトー(ジョブ間で解放されない)
- マネージャ(SIM=1e6): 約18GB(問題ごとにプロセス再起動で解放)
- 残1.8〜2.6Giまで下がるがスワップ未使用で完走。アイドル時は
W1-0 << solver killでワーカ解放(次ジョブ投入で自動再起動・モデル再ロード約10秒)
EASY-44の教訓: GHI条件付き証明とPCN閾値の相互作用
- デフォルト(PCN=16.5)ではルートのPCN値16.245が閾値以下 → ルート丸ごと1ジョブで投入
- ジョブはstatus=1(証明)で返るが長いGHI注釈付き(コウの経路履歴に条件付きの証明)
- マネージャは
is_root_virtual_solved=1を立て、無条件winとは認定せず「?」を返す = 引き継ぎ書§7「コウ無視のソルバは嘘の証明を返す→妥協しない」が機能している証拠 - PCN=16に下げて再実行 → マネージャが木を分解(644ノード/146ジョブ)しGHIを局所解決 → win確定(24.8s)
- 発展課題への示唆: ルート直投げ時のGHI後処理(virtual solved解消の再探索)は改善余地。 2512.21365の「稀パターン誤判定」と合わせてPhase 3研究テーマの入口
オンライン微調整(online-cp/sp)セットアップ完了(2026-07-15)
論文の本体機構「解きながらPCNを微調整する」を単一GPU構成で稼働させた。
構成(tmuxセッションsolverに3窓追加)
| 窓 | ノード | 実体 | 環境注入 |
|---|---|---|---|
| LL1 | trainer | game-solver-trainer.sh → killallgo_solver -mode zero_server(port 9999) |
LD_PRELOAD(2.11 cudart) |
| LL1-sp | 自己対戦 | zero-worker.sh sp → killallgo_solver -mode sp(GPU 0, batch 256) | LD_PRELOAD(2.11 cudart) |
| LL1-op | 最適化 | zero-worker.sh op → python game_solver/trainer/learner/train.py |
PATHに既存torch venv(LD_PRELOADは厳禁) |
- Python側は既存のローカルLLM用venv(torch 2.9.1+cu128 / Py3.12)を読み取り専用で再利用 (venvへの書き込みゼロ。WSL激遅回線でのtorch wheel再取得を回避)
- pybindモジュールは
PYTHONPATH=.でbuild.killallgo.pybind_pcn_learnerをnamespace import (torch非リンクなのでlibtorch版数と無関係、CPython 3.12 ABIのみ一致必要) - ⚠️ op(Python)にはLD_PRELOADを渡さないこと: cu13のcudartをtorch cu128のPythonに preloadすると逆方向のシンボル横取りになる。C++ノード(LL1/LL1-sp/W1-0/manager)のみに適用
.pkl(optimizer込みチェックポイント)はtorch 2.9のweights_onlyデフォルトでもロード可(パッチ不要)- パッチ(+1行): run-manager.sh の TRAINER_HOST を環境変数で上書き可能に
(デフォルトはhostnameから合成され
DESKTOP-XXXX1という解決不能名になるためTRAINER_HOST=localhostを注入)
実行コマンド(managerウィンドウ)
CHAT=localhost:8888 TRAINER_HOST=localhost TRAINER_GPU=0 LD_PRELOAD=<2.11のcudart> \
scripts/run-manager.sh killallgo <ID> BROKER=b1 CVD=0 ONLINE=true SIM=1000000
検証結果: EASY-08(最重量問題)でbaseline比8.2倍
| モード | 時間 | マネージャ木 | ジョブ数 | 備考 |
|---|---|---|---|---|
| baseline(48w) | 284.3s | 19302 | 1196 | |
| online(32w+trainer同居) | 34.5s | 4793 | 460 | load_model配信1回、weight_iter_100200生成、sp棋譜2イテレーション |
- ワーカが少ない(32 vs 48)のに8.2倍。単一サンプルだが論文の主張(オンライン微調整の優位)と整合
- torch 2.9.1(Python)が学習→TorchScript export→libtorch 2.11ワーカがロード、の世代跨ぎ交換が動作
JA本番運転(2026-07-15 19:13開始)
- コマンド:
CHAT=localhost:8888 TRAINER_HOST=localhost TRAINER_GPU=0 LD_PRELOAD=<2.11 cudart> scripts/run-manager.sh killallgo JA BROKER=b1 CVD=0 ONLINE=true SIM=2500000 TIMEOUT=259260 - RAM配分の根拠: マネージャRSSは実測で 固定約13GB + 約5.3GB/1e6ノード(SIM=1e6→18GB, 3e6→28.6GB)。 SIM=2.5e6(≈26GB) + ワーカ24並列(≈16GB) + トレーナー3点(≈8GB) ≈ 50GB / 53GB
- TIMEOUT=3日(259260s)。想定: 十数時間〜数日 or SIM上限到達で未解終了(その場合はPCN閾値/ワーカsim/SIM再配分で再挑戦)
- 期待verdict: 論文のJA(ID1)相当は「loss」(白が活き(無条件活き/セキ)を作れず黒が全消し=黒の勝ちの証明)の可能性が高い
運用メモ(この構成で覚えておくこと)
- LL1/LL1-sp/LL1-opノードはONLINE実行が終わるたびに死ぬ(stop処理が
kill -TERM 0で プロセスグループごと落とす)→ ONLINE実行前に毎回3窓を立て直す - 進捗確認:
tmux a -t solver(managerウィンドウ) /wc -l JA-online-*.jobs/ls training/online_JA-*/model//~/Projects/go/chatcmd.sh "b1 << query status" - 停止: managerウィンドウでCtrl+C(run-manager.shがワーカジョブとトレーナーを掃除する)
- 結果: JA-online-.{stat,log,jobs,sgf,7esgf} + training/online_JA-/(微調整済みモデル)
(参考)当初の判断メモ: JA開局(論文メイン実験)
- JA〜JD(5手時点からの開局)が論文の本丸。論文環境は384ワーカ(GTX 1080Ti×12相当)で baseline約9〜32時間/問
- 本機は48ワーカ相当(CPUバウンド、GPUはNN推論のみで余裕)→ 数日規模の見込み
- RAM制約: run-manager.shのデフォルトSIM=5e6はマネージャ約40GB+ワーカ31GB > 53GB → SIM=3e6程度+ワーカ縮小(games=32)が現実解。マネージャ木がSIM上限に達すると未解で終わる リスクあり(その場合はワーカ側sim増で1ジョブを重くする方向へ再配分)
- 実行するなら:
scripts/run-manager.sh killallgo JA BROKER=b1 CVD=0 ONLINE=false SIM=3000000(+ワーカ再設定)をsolverセッションで放置運転+Monitor監視
ベンチマーク設計(2026-07-16 未明、ユーザー発案)
「同一ソルバ・同一問題・同一開局でGPU世代だけが違う」クリーンな実測比較として本JA走行を位置づける。
論文リファレンス行はOFTS docs掲載のJA online(SIM=1e7, 7g384w+1sp1op):
loss / 32,105s / 木1,413,138 / ジョブ281,648 / ノード1,728,286,526 / 6,136n/job / load_model 208
- 完走時:
~/Projects/go/ja_bench_report.shが比較表を自動生成(開局名/総ジョブ/総秒/総ノード/モデル更新回数) - 経過5.65h時点の中間実測: 274 nodes/s/slot(論文141.3の1.94倍)、システム全体6,238 n/s
- 注記: nodes/s/slotはCPU+GPU混合値。スロット当たりCPU配分が論文の約2倍である点を明記して比較する
- 次の実験計画(2軸分離): セキDB(双活データベース)追加後に同じJAを再求解 → 「5090+セキDB vs 1080Ti+セキなし」でハード寄与とアルゴリズム寄与を分離できる
- タイムアウトは解除済み(77h完走予測 > 当初3日設定のため)。解除手順の注意:
watchdogの
sleepを殺すと即quitが飛ぶ。sleepの親サブシェル(run-manager本体とargv同一の fork、sleepと連番PID)をkillすること。実行前にpgrepで本体PIDと区別し、実行後に本体生存を確認する
リファレンス出典の注記(2026-07-16、ユーザー指摘反映)
- 比較主行 = OFTS docs掲載値(32,105s / 281,648ジョブ / 1.728Bノード / load_model 208)。 本走行はdocsのコードベース(neurips2023)からの再現なのでこちらが正当な比較対象。
- 論文本文TableのJA ONLINE-CP行(22,384s / 1.29Bノード)は別条件(ワーカ数・top-k設定が docsと異なる)のため脚注併記に留める。abstractの全体主張は「baseline比23.54%の計算時間」。
- ja_bench_report.sh にも同注記を実装済み。
研究ロードマップ(2026-07-16、ユーザー調査による周辺状況整理)
台湾(CGI/RLG Lab)系列: ①セキDB(2024-11、1日→482秒の事例) ②RZ縮小(arXiv 2510.00689、 平均85.95%に圧縮、再利用可能知識化→大盤への道) ③L&D RZ研究(arXiv 2512.21365、IEEE ToG、 稀パターン誤判定・即生き優先の癖・趙治勲事典2問の修正)。8路/9路の次世代はまだ→フロンティア未移動。
Alberta(Müller研)系列: CGT+αβ/df-pn路線。6×6 Go完全解プロジェクト進行中(5×5/5×6はvan der Werf済)。 MCGS(minimax型組合せゲームソルバ、GitHub: ualberta-mueller-group/MCGS)、SEGClobber、 KataGo完全解析(Husna MSc 2024)。Ting Han Weiが両陣営の共著=協働体制、ただしコード統合は未着手。
ハイブリッド構想(未開拓地): NNソルバが「難しい」と判定した部分木をCGT手法で厳密求解。 本環境での実装距離は近い:
- workerプロトコル(stdin
+ id sgf/ stdoutid status rzone nodes ghi)は疎結合で、 CGTワーカを同プロトコルでbrokerに混在登録可能(solver cmdlineはワーカ毎に設定できる) - ルーティング対象は運用上可視: sim上限unsolvedジョブ(JA 8h時点で77件)、GHI注釈付き証明(EASY-44型)
- 資源も分離: 台湾軸=5090 / Alberta軸=285K CPU(引き継ぎ書§1の役割分担そのまま)
- JA走行の.jobsに全ジョブのRZビットマスクが蓄積中 → RZ縮小(②)の検証コーパスに転用可能
優先順位(ユーザー方針): JA完走→ベンチ表 → ①セキDB → 同一JA再求解で2軸分離(ハード/アルゴ寄与) → ②RZ縮小 or ハイブリッド試作。
🏆 JA完全求解達成(2026-07-17 13:30頃 JA_DONE)
結果: loss(黒の生きを厳密証明)— docs環境と判定一致、再現成功。
| 指標 | 本機 | docs(1080Ti×12/384slot) | 比 |
|---|---|---|---|
| 壁時計 | 148,879s (41.4h) | 32,105s | 4.6倍遅(slot 1/16) |
| nodes/s/slot | 284.0 | 141.3 | 2.00× |
| 必要ノード | 1.011B | 1.728B | 0.59× |
| 総ジョブ | 241,415 | 281,648 | 0.86× |
| モデル配信 | 4,007回 | 208回 | 19× |
| 最終木 | 1,194,363 | 1,413,138 | — |
- スロット実効生産性 ≈ 3.4×(速度2.0×・ノード削減1.71×)。ハード/アルゴ寄与の部分分離まで1走で取得
- 証明木: 分岐ピーク深さ15(38.3万)、最深31。最終モデルstep 902,400 / acc_value_m 0.906
- 成果物: E:\go\JA_results(stat/sgf/7esgf/jobs/log.gz/ベンチ表/検死)
- 教訓: RAMベースの木充填推定は誤校正だった(最終木1.19M ≪ 推定2.5M)。managerのRSS成長はTT/ 断片化を含む。今後の容量推定は.statの実測木サイズを基準にする
- 夜間インシデント: 同居する別のローカルLLMサービスの夜間ジョブとGPU競合(01:00-02:00)、向こうの180sタイムアウト失敗1件。 vLLMはスリープ運用でGPU解放を確認。長期運転時は夜間帯の共存設計を要検討
- 微調整モデル4,013世代=393GB問題 → 間引き(final+anchor+10万step毎)を提案中
- 次: セキDB導入 → 同一JA再走で「5090+セキDB vs 1080Ti+セキなし」二軸比較(ユーザー設計)