- BrainTools - https://www.braintools.ru -

Мог ли Pentium Pro 1996 года обыграть Каспарова без Deep Blue? Я портировал на него Stockfish

10 февраля 1996 года компьютерная программа впервые выиграла партию у действующего чемпиона мира по шахматам: Deep Blue от IBM обыграл Гарри Каспарова. Тот матч Deep Blue в итоге проиграл, но через год взял реванш со счётом 3,5:2,5.

Ради этого IBM вложила несколько миллионов долларов в разработку и построила специализированный компьютер. Победившая, уже улучшенная версия Deep Blue работала на 30 процессорах P2SC примерно по 120 МГц и, что важнее всего, на 480 заказных шахматных сопроцессорах СБИС: они занимались генерацией ходов и оценкой позиций. На момент постройки Deep Blue был 259-м по мощности суперкомпьютером мира и анализировал больше 200 миллионов позиций в секунду.

Но был ли Deep Blue вообще нужен, чтобы обыграть Каспарова? Может, хватило бы обычного настольного компьютера 1996 года с более умным движком?

Оказывается, Каспарова можно было обыграть без всякого Deep Blue, на серийном железе, и борьбы, скорее всего, даже не получилось бы. Я знаю это потому, что прямо сейчас, пока я пишу это предложение, рядом со мной стоит Intel Pentium Pro на 200 МГц (вышел ровно 31 год назад, 1 ноября 1995 года) с 64 МБ памяти [1]. На нём работает собственный порт Stockfish [2], который при классическом контроле времени играет с оценочным рейтингом Эло 3300 ± 87. Это намного сильнее любого человека и уж точно сильнее Каспарова с его рейтингом чуть ниже 2800. И это ещё не всё: я подключил машину к интернету через сетевую карту Realtek RTL8139C, так что с ней можно сыграть прямо на странице оригинала [3].

Экран Pentium Pro с работающим шахматным движком

Экран Pentium Pro с работающим шахматным движком

Подождите, что? Как так?

Стать сильнее в шахматах можно тремя способами: просчитывать больше ходов, просчитывать более удачные ходы или лучше их просчитывать. Люди, как известно, растут за счёт двух последних. Гроссмейстер в классической партии анализирует примерно столько же ходов [4], сколько любитель, но смотрит только на критические и разбирает их качественнее. Шахматные движки вроде Stockfish [2] работают на кремнии, а не на человеческом мозге [5], и побеждают нас в первом пункте: они перебирают миллионы позиций в секунду. А поскольку на современном движке не так уж много места для микрооптимизаций, которые позволили бы тому же процессору обрабатывать больше позиций в секунду, прогресс шахматного ИИ в основном идёт тем же путём, что и у людей: находятся лучшие способы выбирать ходы и оценивать позиции.

Силу в шахматах измеряют рейтингом Эло. Разница в 200 пунктов означает, что более сильный игрок должен выигрывать три партии из четырёх, а дальше это перемножается: разрыв в 400 Эло соответствует 90% ожидаемых очков, разрыв в 1000 Эло — 99,7%. Лучшие движки, которые можно было запустить на серийном железе 1996 года, имели рейтинг около 2300. Deep Blue оценивался в 2700. У современного Stockfish рейтинг ближе к 3700.

Отсюда вопрос: какая часть преимущества современного движка объясняется тем, что нынешний настольный компьютер чрезвычайно быстр, а какая — тем, что мы просто научились лучше писать шахматные программы? Оказывается, большая часть прироста Эло (+720 из +1335) приходится на более удачное программирование. На долю железа остаётся меньшая.

Чтобы это проверить, я провёл два эксперимента. В первом используется Crafty [6] — сильный движок 1996 года, исходный код которого сейчас открыт. На моём Pentium Pro сборка Crafty 11.13 образца 1996 года играет с рейтингом 1999 ± 90 при секунде на ход и 2383 ± 77 при десяти секундах на ход. На современном железе (Ryzen 7) рейтинг этого движка при той же секунде на ход резко вырастает до 2614 ± 97. Но если взять этот движок и постепенно добавлять в него всё, что мы знаем о проектировании сильных движков — современные алгоритмы поиска вроде fail-soft, LMR и истории поправок (correction history), более удачный поиск успокоения (quiescence search) и нейросетевую оценку (NNUE), — то на Pentium Pro рейтинг поднимается до 2718 ± 34 при секунде на ход и до 2974 ± 74 при десяти.

Во втором эксперименте я пошёл дальше: вместо того чтобы обновлять Crafty, попробуем просто запустить на железе 1996 года Stockfish, лучший шахматный движок сегодня, и посмотрим, как он сыграет. Это требует некоторой работы и сводится в основном к тому, чтобы переписать код на 32-битную арифметику (Pentium Pro — 32-битная машина) и уложиться в 64 МБ памяти. Наивный порт играет примерно на 2496 ± 64 при секунде на ход (2940 ± 76 при десяти). Но можно лучше! Современный Stockfish рассчитан на современный процессор. Подстроив алгоритм и настроив его под Pentium, можно поднять рейтинг до 2846 ± 35 при секунде на ход, 3109 ± 79 при десяти и 3180 ± 80 при тридцати.

Короче всего всё это подытожить матчем из 100 партий. Когда я его провожу, современный движок на Pentium Pro 1996 года играет против Crafty 1996 года, запущенного на современном железе, и набирает 78 побед, 17 ничьих и 5 поражений.

Дальше — подробности.

Технические детали: железо и ОС

Про железо, честно говоря, рассказывать особо нечего. Я купил подержанный («винтажный», как было написано в объявлении; чувствую себя старым) настольный ПК со стандартными для своего времени комплектующими. В нём Intel Pentium Pro на 200 МГц на материнской плате Intel VS440FX и 64 МБ памяти SIMM на частоте 66 МГц. Операционная система грузится с 3,5-дюймовой дискеты на 1,44 МБ, в интернет машина выходит через Realtek RTL8139C. Ещё там стоит видеокарта Trio64V+ с 1 МБ памяти, подключённая к монитору по VGA, и клавиатура PS/2, но ими я почти не пользуюсь: общаюсь с машиной через последовательный порт, подключённый к моему современному компьютеру.

Для тех, кому трудно соотнести это железо с ценами: Pentium Pro на 200 МГц стоил на старте продаж в ноябре 1995 года 1325 долларов, а четыре модуля SIMM по 16 МБ обошлись бы примерно в 2000 долларов. С остальной периферией такая машина, скорее всего, стоила бы около четырёх-пяти тысяч долларов. То есть это хорошая рабочая станция, но никак не суперкомпьютер. А с учётом амортизации и экспоненциального роста железа та же машина в 1997 году, когда прошёл второй матч, вероятно, стоила бы уже около тысячи долларов (кому нужен Pentium Pro, когда почти во всём лучший Pentium MMX продаётся всего за 400 долларов?).

Между шахматным движком и интернетом стоит самописная «операционная система», единственная задача которой — запустить движок и подключить его напрямую к сетевой карте. (Везде в этой статье, где я говорю «я написал», на самом деле имеется в виду «я попросил написать языковую модель». Код здесь написан с помощью Fable 5.1, Opus 5.5 и GPT-6. Сама же статья написана человеком.) Система сделана максимально компактной: эта ОС (которая на самом деле скорее гипервизор или что-то в этом роде) лежит на загрузочной дискете. Всё, что она делает, — переводит Pentium Pro в 32-битный защищённый режим, инициализирует сетевую карту и ждёт дальнейших указаний. После этого я могу отправить в память любую «пользовательскую» гостевую программу, и система её запустит. Написанная мной шахматная программа поднимает самописный HTTP-сервер. Он ждёт входящих HTTP-запросов с позицией (в виде строки FEN) и максимальным временем на ход, на каждый запрос гоняет движок, пока не истечёт таймер, и возвращает ответ.

Технические детали: софт

Как я уже говорил, я (ещё раз: языковая модель) переделал два движка. Более сильный из них построен на Stockfish, адаптированном для эффективной работы на тридцатилетнем процессоре. При классическом контроле времени он играет с оценочным рейтингом 3300 (см. примечание ниже) — достаточно выше 2800 Каспарова, чтобы ожидать от «Stockfish-1996» результата примерно 9 из 10. Второй движок (лишь немного слабее) начинается с исходников Crafty 11.13 и переносится во времени: в него добавлено всё, чему мы научились в написании шахматных движков за последние тридцать лет.

Примечание автора. На моей единственной машине невозможно сыграть достаточно партий с классическим контролем, поэтому число экстраполировано с более коротких. Я намерил 3180 ± 80 при 30 секундах на ход, а при переходе от 1 к 10 и от 10 к 30 секундам движок получал +70 Эло на каждое утроение времени. В классической партии выходит около шести минут на ход (с учётом обдумывания во время хода соперника), так что стоит ожидать около 3350 Эло. С поправкой на убывающую отдачу безопасная оценка — 3300.

Обновляем Crafty 11.13 (1996) современными приёмами

Первым движком, над которым я (читай: моя LLM) работал, был Crafty 11.13 — его релиз 1996 года. Здесь модели пришлось сделать больше всего работы, чтобы перенести назад идеи, найденные за последние 30 лет. Ниже разбивка, откуда берётся прирост Эло при одной и десяти секундах на ход (о расхождении между ними — в примечании).

Примечание автора. Иногда приросты при 1 и при 10 секундах расходятся. Частично это вполне может быть шум: я сыграл всего несколько сотен партий, а это даёт довольно большую погрешность. Но и сигнала здесь немало. Компьютер 1996 года гораздо медленнее, поэтому при секунде на ход у него очень маленькая глубина поиска, и скорость оценки позиции важнее её качества. А на большой глубине, когда движок перестаёт зевать тактику, оценка позиции становится гораздо важнее.

1 с/ход

10 с/ход

Что изменилось

1999 ± 90

2383 ± 77

Crafty 11.13 в том виде, в каком он вышел в декабре 1996 года. Исходный альфа-бета движок, как он был написан: собственная функция оценки и стандартные для 90-х алгоритмы поиска.

2063 ± 73 (+64 ± 116)

2323 ± 75 (−60 ± 107)

Первое улучшение — в основном микрооптимизации. Две таблицы поиска на 64 тысячи элементов заменены вызовами инструкций bsf/bsr, а атаки дальнобойных фигур уходят от старой функции на повёрнутых битбордах. В сумме движок становится на 15% быстрее, но алгоритмы те же.

2022 ± 73 (−41 ± 103)

2420 ± 76 (+97 ± 106)

Следующее улучшение касается алгоритмов поиска. Сюда входят fail-soft (возвращает настоящую оценку без обрезки по границам окна), futility pruning и late-move pruning (пропускают тихие ходы у листьев дерева), late move reduction (просчитывает поздние ходы на полуход мельче) и упорядочивание ходов по таблицам контрходов и истории.

2224 ± 72 (+202 ± 103)

2520 ± 74 (+100 ± 106)

Следующее изменение настраивает поиск и функцию оценки. Сначала SPSA подбирает все константы поиска по нескольким тысячам партий игры с самим собой. Затем у членов оценки появляются отдельные значения для миттельшпиля и эндшпиля (смешиваются по оставшемуся материалу), и все веса оценки подбираются заново (Texel tuning). Наконец, в функцию оценки добавлены члены мобильности, вознаграждающие за безопасные поля под ударом фигур.

2192 ± 72 (−32 ± 102)

2565 ± 74 (+45 ± 104)

Дальше функция оценки переписывается и заменяется нейросетевой: небольшой сетью, обученной на 11 миллионах позиций из игр с самим собой, размеченных собственным поиском движка. Сам по себе этот шаг даёт немного, но готовит следующий…

2420 ± 82 (+228 ± 109)

2712 ± 74 (+147 ± 104)

Только что полученная NNUE переобучается с более сильным учителем вместо игры с собой. В принципе, учителем мог бы быть и сам движок, но ради экономии времени я взял Stockfish. Так вместо ~4000 ядро-лет 1996 года (вполне выполнимо в 1996-м, но, увы, не на моём единственном одиноком компьютере) хватило нескольких дней на современном компьютере с современным движком.

2630 ± 82 (+210 ± 116)

2810 ± 75 (+98 ± 105)

С гораздо более сильной оценкой поиск наконец может на неё опираться. Добавлен reverse futility pruning: досрочный выход, когда оценка говорит, что позиция уже выиграна. Ускорен и сам оценщик (кеш оценок, аккумуляторы, общие с нулевыми ходами), что позволило расширить сеть в 6 раз. Заодно вычищен код: например, убраны частные случаи Crafty, которые имели значение при слабой оценке, но с NNUE больше не нужны.

2720 ± 82 (+90 ± 116)

2938 ± 74 (+128 ± 105)

Параметры снова подбираются через SPSA под новую функцию оценки. Заодно, что забавно, исправлено несколько багов в коде. И наконец, изменена NNUE: добавлены выходные головы, которые выбираются по числу фигур на доске, несколько скрытых нейронов и вдвое больше обучающих данных из игр с собой.

Переносим Stockfish 17 на Pentium Pro

Со вторым движком, как уже говорилось, я поступил наоборот. Я (снова читай: моя LLM) портировал Stockfish на железо 1996 года, а потом подкрутил параметры, чтобы он лучше подходил для малой глубины поиска. Поэтому и приросты здесь скромнее: крупных алгоритмических выигрышей уже не осталось.

1 с/ход

10 с/ход

Что изменилось

2496 ± 64

2940 ± 76

Stockfish 17, втиснутый в машину. Первый наивный порт переписывает Stockfish 17 под машину 1996 года: одно ядро, без SIMD, без 64-битных регистров и без стандартной библиотеки C++. Из него убраны многопоточность, эндшпильные таблицы и NNUE на 71 МБ, которую заменила сеть гораздо меньшего размера. Битборды переписаны как пара 32-битных целых, а маленькая NNUE считается обычной целочисленной арифметикой.

2590 ± 67 (+94 ± 93)

2961 ± 74 (+21 ± 106)

Более быстрое обновление аккумуляторов. Второе исправление следит, чтобы текущие суммы NNUE лучше поддерживались в актуальном состоянии, и ускоряет оценщик.

2752 ± 68 (+162 ± 95)

3006 ± 74 (+45 ± 105)

Более дешёвая функция оценки, смесь с PeSTO, другие флаги компилятора. NNUE снова меняется: она уменьшена и настроена под Pentium Pro, что втрое сокращает время оценки. Вместе с ещё несколькими оптимизациями этот шаг даёт самый большой прирост при секунде на ход, где важнее всего чистая скорость, и гораздо меньший при десяти секундах.

2780 ± 67 (+28 ± 95)

3070 ± 72 (+64 ± 103)

Дообучение NNUE на собственной политике. По сути, повторение [7] предыдущей работы, но уже на Stockfish: несколько миллионов позиций оцениваются Stockfish, чтобы заново получить веса NNUE.

2784 ± 65 (+4 ± 93)

3070 ± 72 (+0 ± 101)

SPSA для перенастройки поиска, PeSTO убран благодаря улучшенной NNUE. Исходный Stockfish рассчитан на несколько миллионов узлов в секунду, поэтому на медленном процессоре параметры приходится перенастраивать ещё одним проходом SPSA. После этих изменений проход с PeSTO больше не нужен.

2819 ± 65 (+35 ± 92)

3074 ± 72 (+4 ± 101)

Возвращена история поправок, остальные параметры и NNUE настроены совместно. Этот проход возвращает в Stockfish историю поправок для непешечной структуры (non-pawn correction history), совместно оптимизирует параметры (опять через SPSA) и заново подгоняет NNUE.

2846 ± 35 (+27 ± 74)

3109 ± 79 (+35 ± 107)

Последний шаг не меняет кода: другой компилятор, оптимизация на этапе компоновки и выравнивание кода по 32 байтам.

Так обыграл бы он Каспарова?

Думаю, почти наверняка, но ситуация чуть сложнее, чем хотелось бы. Дело в том, что на протяжении всей статьи я слегка лукавил. Рейтинги Эло относительны, а я сравнивал свой движок с разными версиями Stockfish, сила которых известна по рейтинг-листу компьютерных шахмат CCRL [8]. Люди играют с движками нечасто, поэтому шкала ФИДЕ и шкала CCRL могут немного расходиться — так же, как рейтинг игрока в ФИДЕ не переводится напрямую в его рейтинг в онлайн-шахматах. К счастью, мои движки играют на уровне 3200–3300, а у Каспарова было чуть меньше 2800, так что запаса должно с лихвой хватить, чтобы поглотить любое расхождение.

Но если вы вдруг знаете супергроссмейстера с рейтингом 2700+, который хотел бы попробовать обыграть движок 2026 года на железе 1996-го, — я с радостью приму вызов!

Вывод

Когда люди делают что-то впервые, они редко делают это эффективно. Увидев путь, который точно сработает, если его масштабировать, мы так и поступаем. И только позже, когда успеваем лучше разобраться в задаче, понимаем, что того же можно было добиться гораздо экономнее, если подойти к делу с умом.

В основном я затеял это ради развлечения: вопрос, можно ли было обыграть Каспарова на обычном железе, показался мне забавным. Но ещё я надеялся, что это хоть немного прояснит, с какой скоростью идёт алгоритмический прогресс в «ИИ». Шахматные движки в 1997 году были уже весьма развитыми: в конце концов, Алан Тьюринг помогал писать первую шахматную программу почти на пятьдесят лет раньше. Так что тогда, наверное, казалось правдоподобным, что новых идей осталось немного. Задним числом легко увидеть, что это не так.

Отсюда вопрос: сколько мы недобираем с современным «ИИ», то есть с языковыми моделями? Обгонят ли улучшения софта в ближайшие годы рост масштабов железа? Понятно, что этот игрушечный эксперимент не даёт на это окончательного ответа, но намекает на возможное будущее. (Наверное, тут есть и какой-то урок про использование LLM — «ИИ», — которые ускоряют поиск ответов на странные исследовательские вопросы вроде этого.)

(И да, если у кого-то есть идеи, чем занять Pentium Pro через несколько недель, когда он перестанет быть нужен для этого шахматного движка, — дайте знать!)

Автор: opium

Источник [9]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/37991

URLs in this post:

[1] памяти: http://www.braintools.ru/article/4140

[2] Stockfish: https://stockfishchess.org/

[3] странице оригинала: https://nicholas.carlini.com/writing/2026/algorithmic-improvements-chess.html

[4] примерно столько же ходов: https://psycnet.apa.org/record/1982-00955-001

[5] мозге: http://www.braintools.ru/parts-of-the-brain

[6] Crafty: https://en.wikipedia.org/wiki/Crafty

[7] повторение: http://www.braintools.ru/article/4012

[8] CCRL: https://computerchess.org.uk/4040/rating_list_all.html

[9] Источник: https://habr.com/ru/articles/1103342/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1103342

www.BrainTools.ru

Rambler's Top100