🗺️ Roadmap: value-модель и сильный алгоритм
Как читать
Это живой документ: статусы и даты правим по месту, историю решений держит журнал. Каждый шаг имеет гейт — проверяемое условие, без которого на следующий шаг не переходим. Обоснование всей архитектуры: win-probability-for-sparse-positions.
Статусы: ✅ готово · 🔄 в работе · ⏳ ждёт гейта · 📋 запланировано · 🧊 горизонт
Шаг 0 — чистые данные и Brier-бенчмарк ✅
Фундамент обеих веток (prior аналитики и eval бота): на каких метках учимся и как сравниваем оценщиков.
- Решение по фильтру меток: только
termination = king_captured— разом отсекает таймауты (проигрыш по часам ≠ качество позиции), отказы от удвоения (double_declined = поражение без доигрывания), ранние договорные ничьи турниров и частичные финальные ходы (они бывают только у timeout/draw/resign). Решено 2026-08-09. - Рейтинг на экспорте НЕ фильтруем: срезы и веса делаются в ev (
train.pyуже взвешивает: бот-партии 0.3, unrated 0.5, рейтинг-рампа 0.6–1.5). - Свежий экспорт
training_data_kc_20260809.csv.gz— 1 330 746 партий / 19 992 727 строк за 12 мин (09.08). - Фильтрация
kcp_full_20260803до king_captured — 17,1 из 18,9 млн строк выжило (90,6%). - Переобучение на чистых метках (09.08): rich AUC 0.706 / rich+KCP AUC 0.728 (log-loss 0.602) / kcp-nodice 0.710 — KCP-фичи подтверждены, roll-aware сильнее dice-free; таблица в журнале.
- Rich-обогащение свежего экспорта (20 млн строк за 8 мин) + переобучение rich на нём: AUC 0.7008 — стабильно с 02.08-снапшотом, дрейфа нет (09.08).
- KCP-обогащение дельты — завершено chunk-раннером с автобисектом (09.08): 2 738 404 из 2 738 412 строк, 8 в карантине (4 партии с повёрнутой доской, движковый баг #549); beturanga-строки досчитаны отдельно — 125 764, карантин 0.
- Слияние полного датасета: 19 991 736 строк, 0 дублей (
training_data_kcp_full_20260809.csv.gz). - Флагман переобучен на полном корпусе —
kcpdice_full_20260809: AUC 0.7260 / log-loss 0.6032 против 0.7280 / 0.6021 на снапшоте 02.08. Вывод: 🔑 объём данных исчерпан как рычаг, ограничивают фичи (тот же результат независимо показал rich);king_capture_attack— фича №2 по важности. - После мержа #593 и бампа движка — пересчитать 8 карантинных строк (косметика: 0,0004% корпуса).
- Изотоническая пост-калибровка — померено, НЕ требуется (0.2132 против 0.2132 по Brier; модель уже откалибрована).
- Brier-бенчмарк собран (холдаут 2 млн ходов, сегментация по частоте позиции): модель выигрывает у эмпирики во всех сегментах, включая n≥10; смесь
(w+α·prior)/(n+α)проигрывает чистой модели (α упирается в максимум сетки); эмпирика по (позиция+бросок) хуже, чем по позиции. MC: MAE 4,5 пп, сохраняет 43% сигнала, 25 с/позицию. -
rawboard_l000в бенче не участвовал (требует своей фича-сборки) — добить при возврате к шагу 3(b).
Гейт взят 09.08. Решение по итогам: 🔑 вероятность считает модель — одна, без смеси и без пост-калибровки; эмпирика остаётся в explorer’е как описательные данные головы распределения, но в оценку не подмешивается; MC уходит из горячего пути. Подробности и таблицы — журнал; исходный план с пометками об опровержении — win-probability-for-sparse-positions.
Шаг 1 — измерительный стенд силы 📋
Прежде чем «улучшать алгоритм» — договориться, как меряем. Уроки: «плато K=24», которого не было (400 партий дают ±4–5 пп) и разворот эффекта K=all по контролю.
- Целевые контроли: 3+2 — основной (все текущие дуэли уже на нём), 10+10 — вторичный (качество без цейтнота).
- Зафиксировать протокол вердикта: парные партии с зеркальными костями, 1600 партий (разрешение ~2 пп) или SPRT; seeded-прогоны.
- Референс-скрипт стенда (referee/timed-arena чанками, как на текущих дуэлях) — задокументировать как «стандартный замер».
Гейт: любой будущий «+X пп» принимается только со стенда.
Шаг 2 — учитель размечает ✅
Учитель = медленный сильный оценщик; его роль — не играть, а размечать позиции для дистилляции и prior-прекомпьюта.
- Уже готово заранее:
training_data_kcp_full_20260803.csv.gz— KCP-разметка всей базы (снапшот 02.08) сделана облачным CPU-прогоном ещё до этого плана. - Дельта дозаметена (09.08) — считал MacBook, а не Azure: временная ВМ дважды умерла на движковом баге и была снесена, счёт ~€2 (см. журнал).
- Решить, нужен ли учитель сильнее статики (2-ply поверх лучшей модели) для следующего витка дистилляции.
Гейт взят: KCP-покрытие = весь актуальный корпус (19 991 736 строк), непокрыто 8 карантинных строк.
Шаг 3 — студент: быстрый наследник учителя ⏳
- (a) LightGBM-дистиллят — проверено 09.08, НЕ работает больше: свип lambda даёт разброс 0.0003 AUC, лучшая точка — контроль (чистый rich). Июльские +2.2 пп были эффектом малых данных; на 20 млн строк rich-9 насыщен. Переобучение rich на свежем корпусе даёт Brier −0.0016 — арену на это не тратим (неизмеримо).
- (b) Raw-board / MLP — ЗАКРЫТА как игрок, замерено 12.08. Timed-дуэль
rawboard-1 vs oracle-3(K=24, 3+2, зеркальные кости, 7 400 партий): 46.37%, ci95 ±0.99 пп → −25 elo. Условие «дешевизна разрыв не отыгрывает» подтвердилось, причём решает не win-rate, а 0/0 поражений по времени на всех промежуточных срезах: сеть проигрывает оценкой, а не тем, что не влезает в часы. Согласуется с поправкой, что rawboard оказался ~5× дорожеrichза оценку, а не дешевле. Как кандидат prior’а остаётся в бенче шага 0. Сырые данные:dicechess-ev,logs/timed-duel-rawboard-2026-08-12/. - 🔑 (c) NNUE-прототип — теперь ЕДИНСТВЕННЫЙ оставшийся рычаг (PyTorch/MPS → офлайн-сравнение), см. what-is-nnue. Три замера 09.08 (данные, дистилляция, ретрейн) показали, что rich-9 упёрся в фичи, а KCP-фичи дают 5% по Brier, но не влезают в бюджет листа. Рукописный инференс в движке — только после доказанной силы офлайн.
Гейт: студент ≥ учитель − ε по log-loss на holdout при цене ≤ бюджета листа поиска.
Шаг 4 — студент в поиске → oracle-4 📋
- 2-ply expectimax поверх студента; K подбирается под контроль (урок ev#14: потолок K растёт с бюджетом времени).
- Wall-clock дисциплина: TimeManager/deadline на ход.
- Парная дуэль против oracle-3 на стенде шага 1.
Гейт: статистически значимый плюс на 3+2 → деплой как oracle-4.
Продуктовый трек: анализ партий 📋
Применение готовых serving-моделей к просмотрщику партий — дизайн: game-analysis-design. Не зависит от шагов 3–5 (использует уже задеплоенные модели), поставляется фазами:
- Фаза 1 — шкала оценки (только UI, бэкенд готов): точка на границе каждого хода от 13-входовой модели — analytics-ui#206.
- Фаза 2 — удача против решения: roll-aware эндпоинт для
kcpdice_serving(19 входов,EV_ROLL_MODEL_PATH) — analytics#276; полоски «что дали кости / что сделал игрок». - Фаза 3 — оценка ходов: грейдер
TurnGenerator× модель — analytics#277; winrate-loss, зевки, accuracy. Порог зевка калибруется поmine_blunders.py(задача в ev).
Гейт фазы 3: цена типичного хода ≤ ~3 с на 4 ядрах (померено, не угадано) и корректная деградация на деплоях без моделей.
Шаг 5 — self-play / TD 🧊
Вторая половина замысла ev#16: TD self-play снимает зависимость от качества человеческих меток. Заводить только после полного оборота цикла «учитель → студент → поиск» и работающего стенда.
Ресурсы и дедлайны
- MacBook — экспорт, rich-обогащение, LightGBM, калибровка, бенч, прототипы сетей (MPS).
- Azure-кредит €150 — остаётся под арены и возможные GPU-свипы шага 3(c). При круглосуточных ВМ горит ~€9.4/день; четыре ВМ заняты дуэлями. 🔑 Квота кредитной подписки — 4 vCPU на регион, и поверх неё capacity-ограничения: из пяти проверенных регионов D4 нашёлся только в polandcentral.
- Бюджетный алерт на кредитной подписке не предупреждает об истощении кредита — следить руками (Cost Management → Credits).