Нейросеть — плохой калькулятор, и это не баг

от автора

Коллега прислал скриншот: попросил модель перемножить два шестизначных числа, та выдала ответ мгновенно, уверенно и с ошибкой аккурат в середине числа — первые и последние цифры правильные, серединка выдуманная. Подпись под скриншотом была короткая: «И вот этому мы доверяем юнит-экономику?» Вопрос риторический, но он вскрывает недопонимание, которое я встречаю постоянно, в том числе у технарей: от языковой модели ждут поведения калькулятора, а потом обижаются. Давайте разберём, почему арифметика для LLM — противоестественное занятие, почему она при этом «иногда работает» и что индустрия с этим делает. Спойлер: делает, и довольно успешно, просто не там, где кажется.

Начать придётся с банальности, которую все знают и мало кто продумывает до конца: языковая модель предсказывает следующий токен, а не исполняет алгоритм. Умножение в столбик — это процедура: разряды, переносы, промежуточные суммы, строгий порядок операций. Процессор её исполняет, школьник исполняет, а трансформер за один проход — нет: он порождает текст, похожий на правильный ответ, опираясь на статистику виденных примеров. Для коротких чисел этой статистики навалом — таблица умножения и мелкая арифметика встречаются в обучающих данных миллионы раз, поэтому «7 × 8» модель выдаёт безошибочно. Но это работа памяти, а не вычислителя: примерно как вы отвечаете «пятьдесят шесть», не перемножая ничего в голове. С ростом разрядности похожие примеры из данных заканчиваются, и модель начинает делать то, что умеет, — правдоподобно продолжать. Отсюда фирменный почерк ошибок: верные крайние цифры (их проще выучить как паттерн) и каша в середине, где нужно честно тащить переносы.

Второй слой проблемы — токенизация, и вот тут начинается настоящая инженерная трагикомедия. Модель не видит цифр — она видит токены, а на числа токенизаторы исторически резали текст безо всякого уважения к позиционной записи: где-то «2023» был одним токеном, а «2024» — двумя, где-то числа дробились на неровные куски вроде «123» + «45». Попробуйте поделить столбиком число, которое вам показывают нарезанным случайными ломтями, — примерно в таких условиях модель и работает. В новых поколениях токенизаторов ситуацию подлатали: одни семейства моделей режут числа строго по одной цифре, другие — блоками по три, что заметно улучшило арифметику, но природы процесса не изменило. Знаменитый вопрос про количество букв «r» в слове strawberry — ровно та же болезнь: модель оперирует токенами, а не символами, и просьба посчитать буквы для неё звучит как просьба посчитать пиксели на фотографии по её словесному описанию.

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

Теперь хорошие новости: индустрия эту проблему прекрасно знает и решает её единственно разумным способом — не учит гуманитария считать в уме, а даёт ему калькулятор. Механизм называется tool use, он же function calling: модель на лету понимает, что перед ней вычислительная задача, пишет код или вызывает внешнюю функцию, получает результат от нормального детерминированного исполнителя и уже его вставляет в ответ. Встроенные интерпретаторы кода давно есть у ChatGPT, аналогичные механизмы — у GigaChat и других крупных игроков; в API это делается через объявление функций. Разделение труда тут идеально честное: LLM блистает там, где надо понять задачу и составить процедуру, а исполняет процедуру кремний, который не галлюцинирует. Мой любимый бытовой трюк из той же оперы — добавить к расчётной просьбе слова «напиши код и выполни его»: качество арифметики меняется скачком, потому что вы явно переключили модель из режима «вспоминай похожее» в режим «составь алгоритм».

Этажом выше, на уровне пользовательских продуктов, ту же идею довели до логического конца: формулу вообще забирают у модели и зашивают в сценарий, оставляя нейросети только сбор входных данных и объяснение результата. Таких «калькуляторов с человеческим лицом» уже целый жанр — от самодельных GPTs с прописанной методикой до готовых расчётных мини-приложений в сервисах-конструкторах вроде отечественной Сферы (sphere.su), где под типовой расчёт даётся форма с полями, а не поле для фантазии. Под узкие задачи — сметы, кредиты, дозировки, что угодно — часто существует и специализированный сервис; искать их можно по каталогам вроде There’s an AI for That или galleryai.ru, только с одной оговоркой: обязательно проверяйте, что у находки под капотом. Зашитая формула и «тот же чат, но с красивым лендингом» — это два принципиально разных класса надёжности, а снаружи они, увы, близнецы. Тест простой: прогоните один и тот же расчёт трижды. Формула ответит трижды одинаково.

Из всего этого у меня сложилось три рабочих правила, которые я навязываю коллегам с занудством, достойным лучшего применения. Разовый расчёт — только через код: просите модель показать вычисление программой, а не «в уме», и пробегайтесь глазами по логике. Любой ответ — сверять хотя бы по порядку величины: грубая прикидка в голове ловит большинство «выдуманных серединок». А повторяющийся расчёт — выносить из модели насовсем: формула должна жить в скрипте, таблице или сценарии, где она зафиксирована и версионируется, потому что модель может «творчески переосмыслить» методику в любой момент, и вы об этом не узнаете. Сформулировать можно короче: LLM — великолепный автор процедур и никудышный их исполнитель. Не заставляйте поэта работать процессором — у них обоих есть занятия получше.

Ну и традиционное: несите в комментарии любимые арифметические фейлы моделей — коллекционирую. Особенно интересуют случаи, когда ошибка была найдена уже после того, как число уехало в отчёт. По моим наблюдениям, именно такие истории обращают в веру «считай кодом» надёжнее любых статей, включая эту.

ссылка на оригинал статьи https://habr.com/ru/articles/1056936/