Wintersalmon | Blog

막다른 실험 두 번 끝에, YINSH AI는 학습 부족이 아니라 모델이 작은 게 문제였습니다

7 min read

제가 계속 조정하던 것은 애초에 병목이 아니었습니다

YINSH는 이 워크스페이스에서 만드는 보드게임 중 하나이고, 그 AI 상대인 gen-077 챔피언은 몇 주째 더 강해지지 못하고 있었습니다. 저는 세 번의 12시간 GPU 실험으로 이 챔피언을 이기려 했습니다. 먼저 학습 라운드마다 데이터를 더 많이 먹였고, 다음엔 라운드끼리 서로 이어 쌓이게 했습니다. 둘 다 아슬아슬하게 막혔습니다. 정답은 제가 끝까지 고정해 두었던 변수, 바로 신경망의 크기였습니다. 크기를 2배로 키우자 처음부터(from scratch) 두 세대 만에 챔피언을 이겼습니다.

TL;DR

  • 실험 1 (라운드당 데이터 증가): 챔피언 대비 −143에서 −85 Elo까지 가까워졌지만 거기서 멈췄습니다. 끝내 이기지 못했습니다. (PR #1278/#1281, doc 19.)
  • 실험 2 (라운드가 서로 누적): 더 나아지지 않았고 −115 Elo, 상승 추세도 없었습니다. (PR #1282/#1283, doc 21.)
  • 단서: AI는 랜덤 상대에게는 계속 강해졌지만 챔피언 상대로는 아니었습니다 — 더 강한 수를 표현하기엔 신경망이 너무 작다는 신호였습니다.
  • 실험 3 (신경망 2배, 128 channels × 10 blocks, 약 3.36M 가중치): 챔피언을 +170 Elo로 이겼고, 두 번 승급한 뒤 정체됐습니다. 새 챔피언은 gen-202. (PR #1284/#1285/#1286, doc 23.)
  • 처음부터 시작한 신경망이 단 한 라운드 만에 옛 챔피언 수준에 도달했습니다 — 학습이 아니라 옛 크기가 벽이었다는 명백한 증거입니다.

AI가 게임을 배우는 방식, 반복되는 하나의 루프

학습은 AlphaZero 방식의 루프이고, 세 단계가 반복된다고 그리면 이해가 쉽습니다. Self-play: 현재 챔피언이 트리 탐색으로 강한 수를 골라 자기 자신과 수백 판을 둡니다. Train: 새 신경망이 그 탐색된 수들을 모방하도록 학습합니다 — 챔피언의 가장 좋은 직관을 배우는 것입니다. Gate: 새 신경망이 챔피언과 시합을 하고, 엄격한 통계 심판이 정말로 더 강한지 판정합니다.

이 심판이 생각보다 더 중요합니다. SPRT gate는 확신이 설 때까지 판을 이어 두고, 이긴 후보는 새 800판으로 다시 검증해 진짜 실력일 때만 새 챔피언으로 인정합니다. 이 글의 모든 실험에서 gate는 한 번도 손대지 않았으므로, “승급(promotion)“은 언제나 측정된 진짜 향상을 뜻합니다.

두 막다른 길: 데이터도, 누적도 멈췄습니다

첫 가설은 가장 뻔한 것이었습니다 — 신경망이 학습 부족이라는 것. 그래서 실험 1은 self-play 판수(256 → 512), 학습 패스(epoch 3 → 5), 과거 라운드 기억 범위(window 6 → 8)를 늘렸습니다. 효과는 있었습니다 — 부분적으로요. 새 신경망들은 gen-077 대비 −143에서 −85까지 올라왔는데, 옛 크기로는 최고 기록이었습니다. 하지만 −85는 여전히 음수입니다 — 가까워졌을 뿐, 앞서지는 못했습니다. (Elo는 상대적 점수라, 음수는 챔피언보다 약하다는 뜻입니다.)

실험 2는 누적을 시도했습니다 — 매 라운드를 챔피언으로 리셋하지 않고 직전 라운드의 신경망에서 출발시켜, 향상이 쌓이도록 한 것입니다. 결과 곡선은 거의 똑같았고 최고점은 −115였습니다. 교훈은 의외였습니다 — 매 라운드가 같은 챔피언의 대국을 학습했기에, 출발점은 몇 번의 학습 패스 뒤 씻겨 사라졌습니다. 같은 선생, 같은 천장이었습니다.

단서는 “어떤 상대를 이기고 있었나”였습니다

정직한 신호는 두 숫자에 숨어 있었습니다. 두 실험 모두에서 신경망의 랜덤 상대 승률은 계속 올랐지만(0.67 → 0.73), 챔피언 상대 승률은 제자리였습니다. 전반적으로는 유능해지는데 특정 강한 상대를 앞지르지 못하는 신경망은 정확한 메시지를 던집니다 — 챔피언 수준을 표현할 용량은 있지만, 그보다 더 나은 것을 표현할 용량은 없다는 것입니다. 이는 학습 문제가 아니라 capacity ceiling(용량 천장)입니다. 두 번의 실패가 바로 그 증거였습니다.

더 큰 신경망이 두 세대 만에, 처음부터 이겼습니다

실험 3은 단 하나만 바꿨습니다 — 신경망을 96 channels × 8 blocks(1.73M 가중치)에서 **128 × 10(약 3.36M)**으로, 약 2배 키운 것입니다. 저는 느린 출발을 예상했습니다. 더 큰 신경망은 옛 챔피언의 가중치를 물려받을 수 없어(모양이 안 맞습니다) 랜덤에서 시작하기 때문입니다. 그래서 “더 큰 신경망 파이프라인이 돌아가기는 하는지” 확인하는 smoke test로 잡았습니다.

기대 이상이었습니다. 랜덤에서 시작한 첫 세대가 이미 옛 챔피언의 최고 기록과 맞먹었습니다. 두 번째 세대는 gate에서 gen-077을 +113 Elo로, 재검증에서는 +170으로 이겼습니다 — 승률 65.8%. 이 전체 작업에서 첫 챔피언 교체였습니다. 세 번째 세대가 또 승급(+43)했고, 네 번째는 무승부 수준으로 나오며 상승이 정체됐습니다 — 그래서 무승부 시합에 GPU를 더 태우는 대신 일찍 멈췄습니다. 새 챔피언은 gen-202, 이미지는 2026.06.28.030243-86a60ce.

가장 많은 시간을 잡아먹은 실수들

세 가지인데, 주니어 엔지니어가 새겨둘 만합니다. 첫째, 저장된 상태에 대한 잘못된 가정입니다 — 디스크의 학습 데이터가 제 예상과 어긋나 있었고, 그대로 띄웠으면 오래되고 품질이 섞인 대국으로 학습할 뻔했습니다. 인수인계 메모를 믿는 대신 실제 파일을 직접 읽어 잡아냈습니다. 둘째, 실행 스크립트에 --warm-start가 하드코딩돼 있어, 크기가 다른 신경망이 옛 챔피언 가중치를 크래시 로드할 뻔했습니다. 해결은 플래그 하나를 게이트로 둔 것(PR #1284)이었습니다. 셋째, 제 모니터링 스크립트가 이후 모든 세대에서 “승급!”을 외쳤습니다 — “이번 세대가 승급했나”가 아니라 “어느 세대든 승급한 적 있나”를 검사했기 때문입니다. 대시보드도 나름의 방식으로 거짓말을 한다는 교훈입니다. 셋 다 과학은 아니었지만, 모두 실제 시간을 잡아먹었습니다.

이것이 앞으로 바꾸는 것

요지는 작고 겸손합니다 — 몇 주 동안 데이터·epoch·누적을 만졌는데, 답은 모델을 더 크게 만들라였습니다. 이제 YINSH는 gen-077 이후 처음으로 진짜 더 강한 챔피언을 갖게 됐고, “지표가 어떤 상대를 상대로 움직이는지 읽어라”라는 진단법은 제가 계속 재사용할 부분입니다. 다음은 용량을 더 밀어붙이는 것(더 큰 신경망, 또는 gen-202에서 출발시키기)과, 아직 옛 두뇌를 마주하는 플레이어에게 gen-202를 드디어 배포하는 것입니다.

핵심 용어

  • Neural network — 일일이 코딩하는 대신 예시로 패턴을 배우는 프로그램으로, 여기서는 좋은 YINSH 수와 누가 이기는지를 예측합니다.
  • Channels / blocks — 신경망 크기를 키우는 두 다이얼로, 둘 중 무엇을 늘려도 복잡한 수를 표현할 용량(과 학습 연산량)이 커집니다.
  • Self-play — AI가 자기 자신과 대국해 학습 예시를 스스로 만들어내며, 사람 기보가 필요 없습니다.
  • Elo — 상대적 실력 점수로, 여기서는 챔피언 대비로 재므로 음수면 더 약함, 양수면 더 강함을 뜻합니다.
  • SPRT gate — 도전자가 진짜 더 강한지 확신이 설 만큼만 판을 두고 판정하는 통계 심판입니다.
  • From scratch — 기존 모델을 물려받지 않고 랜덤 가중치에서 학습을 시작하는 것입니다.
  • Capacity ceiling — 아무리 학습해도 더 나은 해를 표현하기엔 모델이 너무 작은 지점입니다.

참고 자료

  • docs/task-log/20260614-yinsh-ai-impl-plan/19-capacity-run-result.md — 실험 1, −85에서 막힌 “데이터 증가” 시도.
  • docs/task-log/20260614-yinsh-ai-impl-plan/21-compounding-run-result.md — 실험 2, 상승 없이 비슷한 수준에 머문 누적 시도.
  • docs/task-log/20260614-yinsh-ai-impl-plan/23-bigger-net-128x10-result.md — 실험 3, 더 큰 신경망과 두 번의 승급.
  • #1284 — 크기가 다른 신경망이 크래시 없이 처음부터 학습하도록 한 플래그 하나짜리 수정.
  • #1285 / #1286 — 승리한 128×10 실험의 launch와 stop.
  • AlphaZero (DeepMind) — 이 파이프라인이 본뜬 self-play + 탐색 + 학습 루프.

AI 작업 노트

이 캠페인 전체는 손이 아니라 Claude Code 에이전트가 운영했습니다 — GitOps 설정을 편집하고, launch/stop PR을 열고 머지했으며, 노트북 Wi-Fi가 클러스터로 바로 닿지 못해 loopback 네트워크 relay를 통해 12시간 실험들을 지켜봤습니다. 통한 패턴은 매 실험을 가설과 사전 합의된 성공 기준(승급·부분·무효)을 적어 둔 하나의 실험으로 다룬 것으로, 덕분에 에이전트가 결과를 읽고 다음 수를 정할 수 있었습니다. 실패한 패턴은 디스크 상태에 관한 인수인계 메모를 믿은 것입니다 — 에이전트는 파일을 직접 확인하고서야 어긋남을 잡았고, 이제 이는 상시 사전 점검 단계가 됐습니다.


Hungjoon

I'm Hungjoon, a software engineer based in South Korea. This is my long-form notebook — homelab, Kubernetes, AI infra, and whatever else keeps me up at night.