Руководство по инференсу
Почему инференс недетерминирован
Миф об «одном и том же» вопросе
Ответы LLM могут различаться, даже когда два запроса выглядят одинаково. Сэмплирование намеренно вносит разброс; изменения в обслуживании, скрытый контекст, результаты инструментов и некоторые параллельные ядра добавляют ещё. Побайтовая воспроизводимость требует контроля над всем входом, конфигурацией декодирования, версией модели и рантайма, а также средой выполнения.
Главное: расхождения возникают в четырёх основных областях: генерация и сэмплирование, контекст и вход, система и архитектура, оборудование и реализация. Понимание этих факторов необходимо для надёжных ИИ-систем.
Категория 1: намеренные параметры генерации и сэмплирования
«Бросок кубика»: сэмплирование способно увеличить разнообразие ответов
1. Temperature
Масштабирует логиты токенов перед сэмплированием, меняя то, насколько сосредоточено распределение вероятностей.
2. Начальное значение (seed)
Компьютеры используют «seed» (стартовое число), чтобы порождать псевдослучайные последовательности.
3. Top-P (nucleus sampling)
Модель выбирает из наименьшего набора токенов, суммарная вероятность которых достигает порога (например, 0,9). Набор кандидатов пересчитывается на каждом шаге генерации.
4. Top-K
Модель выбирает из K наиболее вероятных токенов (например, из первых 50).
5. Другие стратегии сэмплирования
Такие сэмплеры, как Mirostat или typical sampling, отбирают токены-кандидаты по другим правилам.
Категория 2: настройки запроса, формирующие ответ
Изменение этих настроек меняет договор о формате ответа; это не доказательство недетерминированности
6. Штрафы за повторы, частоту и присутствие
Эти настройки понижают оценки уже встречавшихся токенов и подавляют повторы. Изменение штрафа меняет распределение кандидатов даже при фиксированном seed.
7. Условия остановки (max tokens)
Жёсткий предел длины ответа. Запуск с max_tokens=50 отличается от запуска с max_tokens=500.
8. Условия остановки (стоп-последовательности)
Модель останавливается, если порождает заданную строку (например, "\nHuman:"). При стохастическом сэмплировании разные пути могут встретить стоп-последовательность в разных местах.
Категория 3: переменные контекста и входных данных
«Память»: вход модели часто содержит не только последнее сообщение пользователя
9. История диалога (окно контекста)
Самая частая причина кажущейся недетерминированности. Модель видит весь предшествующий диалог, а не только последний вопрос.
Один изменённый токен создаёт другой вход и может изменить ответ
10. Предел окна контекста (точка «забывания»)
У моделей конечное окно контекста, и его размер зависит от модели. Длинные диалоги окружающее приложение может обрезать, свернуть в резюме или отклонить; содержимое за пределами переданного контекста модели недоступно.
11. Системный промпт
Инструкция более высокого приоритета, задаваемая приложением или API. Разработчику она может быть видна, а конечному пользователю нет, и её изменение меняет стиль и поведение ответов.
12. Поиск и внешние инструменты
Существенный источник различий во входных данных от запроса к запросу. В сценарии с опорой на поиск приложение может:
- Приостановить генерацию
- Вызвать внешний инструмент (например, Google Search API)
- Получить новые динамические данные (результаты поиска)
- Внедрить эти данные в контекст
Результаты инструментов меняются между запросами, а это меняет вход модели и может изменить ответ
Категория 4: системные и архитектурные переменные
«Оркестр»: за словом «модель» часто стоит сложная система из нескольких моделей
13. Обновления и версии модели
Модель, которой вы пользуетесь сегодня, может быть новой, переобученной или обновлённой по сравнению со вчерашней. Модель v1.2 отвечает не так, как модель v1.3.
14. A/B-тесты и канареечные выкатки
Провайдер или ваш собственный шлюз может распределять трафик между версиями во время выкатки. Если версию нельзя зафиксировать, два запроса попадут в разные развёртывания и дадут разные ответы.
15. Спекулятивное декодирование
Черновая модель предлагает токены, которые проверяет целевая модель. Точные реализации стремятся сохранить целевое распределение, но различия в рантайме, батчинге, приближениях или конфигурации всё же влияют на воспроизводимость.
16. Архитектура Mixture of Experts (MoE)
Маршрутизатор выбирает подмножество экспертов для каждого токена. При фиксированном входе функция маршрутизации может быть детерминированной, тогда как пределы ёмкости, батчинг и детали реализации создают разброс на уровне развёртывания.
Категория 5: оборудование и низкоуровневая реализация
«Физика»: самый глубокий и наименее управляемый источник разброса
Осторожно: некоторые решения рантайма дают разный результат даже при температуре 0 и фиксированном seed.
17. Параллельные ядра и порядок редукции чисел с плавающей запятой
Фиксированные операции в фиксированном порядке воспроизводимы. Разброс появляется, когда параллельные ядра или редукции выполняются в другом порядке и различия округления накапливаются:
- Параллелизм: GPU выполняют миллиарды вычислений одновременно
- Арифметика с плавающей запятой: машинные вычисления с дробями не вполне ассоциативны
- Следствие: небольшие изменения оценок меняют выбор токена, когда кандидаты очень близки
Пример: из-за округления (a+b)+c ≠ a+(b+c) → 0,81234567 против 0,81234568 → выбрано другое слово
18. Конфигурация квантизации
Квантизованная модель использует представления меньшей точности, чем другая сборка, и поэтому может давать другие оценки или ответы. Фиксированная пара из квантизованной модели и рантайма сама по себе не является недетерминированной; записывайте точную квантизацию и рантайм как часть версии модели.
19. Батчинг
Ваш запрос обрабатывается в «батче» вместе с запросами других пользователей. То, как они группируются и дополняются, меняет точный порядок вычислений на GPU и запускает эффекты плавающей запятой.
20. Dropout во время инференса
При инференсе dropout обычно отключён. Исследовательские приёмы вроде dropout по Монте-Карло намеренно оставляют его включённым; такой промышленный рантайм будет стохастическим, пока не управлять его случайным состоянием.
Что важно помнить разработчику
Как приблизиться к детерминированности
- Установить температуру 0 (жадное декодирование)
- Использовать фиксированное значение seed
- Точно контролировать весь входной контекст
- Использовать одну и ту же версию модели
- Принять, что расхождения на уровне оборудования всё равно возможны
Как принять недетерминированность
- Строить системы, которые спокойно переносят разброс
- Применять метрики оценки, учитывающие смысловую эквивалентность
- Использовать ограниченное число повторов только для безопасных или идемпотентных операций
- Следить за стабильностью качества, а не за совпадением ответов