Параметры LLM

Общее

Большие языковые модели (LLM) по своей природе вероятностны: на каждом шаге генерации они не «выдают» следующий токен, а строят распределение вероятностей по всему словарю и выбирают из него. Как именно происходит этот выбор — жёстко ли берётся самый вероятный кандидат или допускается случайность, насколько широк круг рассматриваемых вариантов и какие токены штрафуются — определяется набором параметров инференса. Это и есть тема данной статьи: настройки, которые находятся не внутри модели (веса обучены один раз и зафиксированы), а снаружи — на момент каждого вызова.

Параметры инференса — не косметика и не «настройки по вкусу». Одна и та же модель с разными параметрами ведёт себя как две разные модели: temperature = 0 и temperature = 1.2 могут дать ответы, которые невозможно узнать как продукт одной и той же системы. Поэтому утверждение «мы используем модель X» без указания параметров, на которых она вызывается, бессмысленно — два разработчика, использующих одну и ту же модель, могут получать радикально разное качество и сделать противоположные выводы о её пригодности.

Важно с самого начала развести три родственных, но разных понятия.

Параметры инференса (эта статья) — настройки генерации, которые разработчик передаёт при каждом вызове модели: temperature, top_p, max_tokens, seed и так далее. Они меняют то, как модель выбирает токены, но не саму модель.

Метрики — измеримые характеристики результата: качество, латентность, стоимость, токсичность. О том, как системно оценивать модели на ваших данных — в Метрики LLM. Параметры инференса — один из рычагов, которым метрики двигают: изменил temperature — изменилась консистентность ответов, изменилась стоимость (модель стала длиннее отвечать).

Бенчмарки — стандартизированные экзамены, на которых модели сравнивают между собой на рынке. Любой бенчмарк проводится с фиксированными параметрами (обычно temperature = 0 для воспроизводимости), и без указания этих параметров цифра бенчмарка бессмысленна. Подробно — в Бенчмарки LLM.

Параметры инференса решают три практические задачи.

Управление характером ответа. От детерминированного извлечения фактов в JSON до креативного брейншторма — это спектр, и точка на нём задаётся параметрами. Один и тот же модельный вызов может быть либо жёстким парсером, либо источником нестандартных идей — в зависимости от настроек.

Контроль воспроизводимости. Для пайплайнов, тестов, отладки и оценки (включая бенчмарки) критически важна повторяемость: один и тот же запрос должен давать один и тот же ответ. Параметры — единственный рычаг, приближающий модель к детерминизму (полностью он недостижим, но об этом ниже).

Баланс стоимость/качество/скорость. max_tokens напрямую определяет верхнюю границу стоимости запроса и его latency; параметры множественной генерации (best_of, n) умножают стоимость ради качества. Экономика LLM-продукта складывается из этих настроек не меньше, чем из тарифа вендора.

Универсального «правильного» набора параметров не существует — есть набор, адекватный задаче. Ниже разобраны основные параметры по группам, их механика (с формулами) и практические пресеты.

Как выбирается следующий токен

Понимание параметров инференса невозможно без понимания того, что именно они настраивают. Поэтому коротко о базовой механике — это потребуется дальше.

На каждом шаге генерации модель выдаёт для каждого токена i из словаря V число z_iлогит. Логиты — это сырые ненормированные оценки: какой токен «лучше» продолжить текст в этом месте. Чтобы превратить логиты в распределение вероятностей, применяется функция softmax с температурой T:

p_i = exp(z_i / T) / Σ_j exp(z_j / T)

Здесь T — это и есть параметр temperature. После softmax получается распределение вероятностей {p_i} над словарём: Σ p_i = 1, все p_i >= 0. Дальше из этого распределения выбирается следующий токен — либо детерминированно (всегда самый вероятный), либо случайно (семплингом).

Greedy decoding (жадный выбор). Модель всегда берёт токен с максимальной p_i — то есть argmax_i p_i. Это полностью детерминированная стратегия: на одном и том же входе всегда один и тот же выход. Её эквивалент в терминах температуры — T → 0 (softmax вырождается в one-hot распределение на аргмаксе).

Stochastic sampling (вероятностный выбор). Токен выбирается случайно, но с вероятностями, пропорциональными p_i: высоковероятные токены берутся чаще, но не гарантированно. Это даёт разнообразие и «живость» ответов ценой потери детерминизма.

Подавляющее большинство параметров инференса — это управление распределением {p_i} до того, как из него сделают выбор: подогреть (температура), обрезать хвост (top-k, top-p, min-p), штрафануть отдельные токены (penalty, logit_bias). Поэтому дальше все формулы будут модифицировать именно это распределение.

Группы параметров

Параметры инференса удобно разбить на несколько групп по тому, какую часть процесса генерации они затрагивают:

  • Сэмплинг — управление формой распределения вероятностей до выбора токена: temperature, top_k, top_p, min_p. Определяют баланс «предсказуемость ↔ разнообразие».
  • Штрафы за повторения — подавление уже сгенерированных токенов: frequency_penalty, presence_penalty, repetition_penalty. Борются с зацикливанием и избыточным повторением.
  • Ограничения вывода — жёсткие границы результата: max_tokens, stop_sequences. Не влияют на вероятности, а обрывают генерацию.
  • Детерминизмseed. Управляет воспроизводимостью сэмплинга.
  • Управление логитами — ручной сдвиг вероятностей конкретных токенов: logit_bias.
  • Диагностикаlogprobs / top_logprobs. Не влияет на ответ, но возвращает вероятности — для отладки и оценки уверенности.
  • Множественные кандидаты и поискbest_of, n, beam_search, length_penalty. Генерация нескольких вариантов и выбор наилучшего.

Группы по-разному влияют на экономику: сэмплинг и штрафы бесплатны (не меняют число токенов), max_tokens и stop_sequences ограничивают стоимость сверху, а множественные кандидаты умножают её. Ниже параметры разобраны по группам.

Сэмплинг

Самая важная и чаще всего настраиваемая группа. Именно эти параметры определяют, будет ли модель отвечать жёстко и предсказуемо или свободно и непредсказуемо.

Temperature (Температура)

Температура T — параметр, который подаётся в softmax и определяет «остроту» распределения вероятностей. Формула приведена выше: p_i = exp(z_i / T) / Σ_j exp(z_j / T). Практически всегда T ∈ [0, 2] (у некоторых бэкендов до 2.0, выход за пределы чреват деградацией).

Механика температуры лучше всего понимается через крайние случаи.

При T → 0 (на практике просто 0) softmax вырождается: вся масса вероятности сосредотачивается на токене с максимальным логитом. Модель становится жадной — greedy decoding. Выбор полностью детерминирован: один и тот же вход всегда даёт один и тот же первый токен, а значит (поскольку каждый шаг зависит от предыдущих) — и один и тот же весь ответ. temperature = 0 — это «режим максимальной предсказуемости».

При T = 1 распределение не модифицируется: модель выбирает токены в точности с теми вероятностями, которые ей дала её внутренняя модель языка. Это «нейтральная» температура — модель ведёт себя так, как её обучили.

При T > 1 распределение сглаживается: вероятности высоко- и низковероятных токенов становятся ближе друг к другу. Это значит, что маловероятные токены начинают выбираться заметно чаще — модель становится «креативнее» и разнообразнее, но и риск бессмыслицы, галлюцинаций и потери связности растёт. При T → ∞ распределение стремится к равномерному — модель начинает выбирать токены почти наугад, и текст превращается в шум.

Практическое правило: низкая температура — для задач, где важна правильность и воспроизводимость; высокая — где важна разнообразие и нестандартность.

  • T = 0 — извлечение фактов, классификация, генерация JSON, кодогенерация, пайплайны, тесты, бенчмарки. Ответ должен быть максимально предсказуемым и аккуратным.
  • T = 0.3–0.7 — RAG, суммаризация, перевод, ответ на вопрос по документам. Нужна точность, но лёгкая вариативность формулировок уместна.
  • T = 0.7–1.0 — чат-боты, ассистенты, диалоговые сценарии. Баланс «естественности» и контроля.
  • T = 1.0–1.3 — брейншторм, креативные тексты, генерация идей. Разнообразие важнее точности.
  • T > 1.3 — почти никогда не оправдан; риск деградации выше, чем польза.

Важный нюанс: у части вендоров temperature = 0 технически реализован как «очень маленькое положительное значение», а у части — как полноценный greedy. Это влияет на то, гарантируется ли детерминизм. Подробности — в разделе про seed.

top_k

top_k ограничивает круг рассматриваемых кандидатов фиксированным числом самых вероятных токенов. При top_k = K модель сортирует токены по убыванию p_i, оставляет только первые K, остальные получает вероятность 0, а оставшиеся перенормируются:

S = { K токенов с наибольшими p_i }
p'_i = p_i / Σ_{j ∈ S} p_j,   если i ∈ S
p'_i = 0,                      если i ∉ S

Дальше сэмплинг идёт по этому усечённому распределению p'. Смысл top_k — отрезать «хвост» маловероятных токенов, которые при высокой температуре всё равно почти никогда не должны выбираться, но иногда выбрались бы из-за случайности и сломали бы текст.

Типовые значения: top_k = 40 (классика ранних моделей), top_k = 50, top_k = 100. top_k = 1 эквивалентно greedy.

Главный недостаток top_kжёсткость отсечки. Число K фиксировано и не зависит от формы распределения. Но распределения бывают очень разными: в одних случаях топ-3 токенов покрывают 99% вероятности (модель почти уверена), в других — даже топ-50 не набирает и 80% (модель в растерянности). При фиксированном K = 40 в первом случае в сэмпл попадает 37 практически нулевых токенов (бесполезно), во втором — отсекается масса ещё релевантных кандидатов (вредно). Именно поэтому на практике top_k почти всегда уступает top_p.

top_p (nucleus sampling)

top_p (или nucleus sampling) — динамическая альтернатива top_k. Вместо фиксированного числа токенов берётся минимальное множество токенов, суммарная вероятность которых не меньше p:

S = минимальное множество токенов, для которого Σ_{j ∈ S} p_j >= p
   (токены упорядочены по убыванию p_i)
p'_i = p_i / Σ_{j ∈ S} p_j,   если i ∈ S
p'_i = 0,                      если i ∉ S

Ключевое отличие от top_k: размер множества S зависит от формы распределения. Когда модель уверена и масса сосредоточена на нескольких токенах — S маленькое (отсекается действительно всё лишнее). Когда модель не уверена и вероятность «размазана» — S большое (в кандидатах остаётся всё, что может быть релевантно). Это делает top_p адаптивным и обычно предпочтительным перед top_k.

Типовые значения: top_p = 0.9, top_p = 0.95. top_p = 1.0 — ограничение не действует (сэмпл идёт по всему словарю). top_p близкое к 0.9–0.95 отрезает только откровенный шум, не искажая содержательный выбор.

Распространённая ошибка — одновременно выкручивать и temperature, и top_k, и top_p, накладывая три ограничения друг на друга. Технически это работает (применяются последовательно), но интерпретировать поведение становится невозможно. На практике обычно комбинируют temperature + top_p (самая распространённая пара), а top_k либо не трогают (дефолт), либо фиксируют на широком значении.

min_p

min_p — относительно новый параметр, набирающий популярность в open-source-сообществе (llama.cpp, vLLM и др.) как замена top_k и top_p. Идея: вместо числа кандидатов (top_k) или суммарной вероятности (top_p) задать относительный порог от вероятности самого вероятного токена:

p_max = max_i p_i
S = { i : p_i >= τ · p_max }        (τ ∈ [0, 1] — параметр min_p)
p'_i = p_i / Σ_{j ∈ S} p_j,   если i ∈ S
p'_i = 0,                      иначе

Смысл: «отрезать все токены, вероятность которых меньше τ от вероятности топового». Когда модель уверена (p_max близко к 1), порог высокий — отсекается почти всё лишнее. Когда модель не уверена (p_max маленькая), порог низкий — в кандидатах остаётся широкое множество.

min_p лишён главных недостатков top_k (фиксированности) и top_p (чувствительности к «длинному хвосту» из множества крошечных вероятностей, который у top_p может незаметно заполнить весь бюджет p). Типовое значение — min_p = 0.05–0.1: отсекает откровенный шум, не искажая содержательный выбор. Параметр особенно удобен для open-source-моделей, где словарь большой и «хвост» тяжёлый.

Штрафы за повторения

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

frequency_penalty и presence_penalty

Это пара параметров в стиле OpenAI, которые применяются к логитам до softmax и сэмплинга. Оба штрафа зависят от того, какие токены уже появились в текущей генерации, но штрафуют по-разному.

z'_i = z_i
        - α · count(i)            // frequency_penalty
        - β · 1[token i уже встречался]   // presence_penalty

Здесь count(i) — сколько раз токен i уже сгенерирован, 1[...] — индикатор факта появления, αfrequency_penalty, βpresence_penalty. Обычно оба параметра принимают значения в [-2, 2], где 0 — штраф отключён, положительные значения штрафуют, отрицательные — поощряют повторение.

Разница между штрафами тонкая, но важная.

frequency_penalty (α) штрафует пропорционально частоте токена: чем больше раз токен уже появился, тем сильнее понижается его логит. Это подавляет зацикливание — повторение одних и тех же слов подряд. Но если токен появился один раз — штраф невелик.

presence_penalty (β) штрафует за сам факт появления токена, независимо от того, сколько раз он встретился. Это не подавляет повторы конкретных слов, а расширяет словарь — заставляет модель использовать новые токены, которых ещё не было. Полезно для разнообразия формулировок в длинных текстах.

Типовые пресеты:

  • frequency_penalty = 0, presence_penalty = 0 — нейтрально (по умолчанию у большинства моделей).
  • frequency_penalty = 0.3–0.6 — мягкое подавление повторов (чат, ассистенты).
  • presence_penalty = 0.3–0.6 — больше разнообразия в длинной генерации.
  • Значения выше 1.0 — агрессивный штраф; модель может начать выбирать неестественные слова только потому, что естественные уже «запретили».

repetition_penalty

repetition_penalty — альтернативная реализация штрафа за повторения, пришедшая из open-source-экосистемы (Hugging Face Transformers, llama.cpp). Механика другая: штраф применяется мультипликативно к логитам уже встречавшихся токенов:

z'_i = z_i / γ,   если токен i уже встречался (γ > 1)
z'_i = z_i,       иначе

Здесь γrepetition_penalty, обычно в [1.0, 1.5]. При γ = 1.0 штраф отключён, при γ = 1.1–1.3 — типовое подавление повторов. Деление логита на γ > 1 понижает его, и после softmax уже встречавшиеся токены получают меньшую вероятность.

Ключевое предупреждение: repetition_penalty и пара frequency_penalty / presence_penalty — разные реализации одной и той же идеи. Их нельзя смешивать: большинство бэкендов поддерживают либо одну схему, либо другую. Если API принимает оба (редкость), одновременное применение даёт двойной штраф и непредсказуемый результат. Перед настройкой штрафов обязательно уточните, какую схему использует ваш бэкенд.

Ограничения вывода

Эти параметры не влияют на вероятности — они задают жёсткие границы результата.

max_tokens

max_tokens — верхний предел числа токенов в ответе модели. После его достижения генерация принудительно останавливается, независимо от того, закончила ли модель мысль. Это прямой рычаг контроля стоимости и latency: каждый выходной токен стоит денег и времени, и max_tokens ставит на это жёсткую крышу.

Экономический смысл прямой. Для коммерческих моделей цена считается за токен; для self-hosted — токены определяют время работы GPU. max_tokens = 4096 вместо max_tokens = 256 на массовом продукте может увеличить стоимость в разы — особенно если модель без явного лимита склонна «растекаться мыслью по древу».

Главный риск — обрыв на середине. Если max_tokens подобран слишком маленьким, модель может закончить ответ посреди предложения или посреди JSON-объекта. Для пайплайнов, где вывод парсится программой, обрыв посреди структуры — падение всего downstream-шага. Поэтому для структурированного вывода max_tokens подбирают с запасом, а парсер делают устойчивым к неполному выводу.

Особый случай — reasoning-модели (OpenAI o-серии, DeepSeek-R3, Claude с extended thinking). У них часть max_tokens расходуется на скрытые reasoning tokens — внутренние рассуждения, которые не попадают в видимый ответ, но за которые тоже нужно платить. max_tokens = 1000 у reasoning-модели может дать всего 200 токенов видимого ответа, а 800 — уйти на reasoning. Это меняет расчёт бюджета: для таких моделей лимит нужно ставить существенно выше, чем подсказывает желаемая длина ответа.

stop_sequences

stop_sequences (у некоторых вендоров — stop) — список строк, при появлении любой из которых генерация немедленно останавливается. Сама стоп-строка в ответ не попадает (у большинства бэкендов). Это инструмент для контроля формата и границ ответа.

Главные сценарии:

  • Структурированный вывод. Если модель должна вернуть один JSON-объект и ничего больше, полезно задать stop_sequences = ["\n\n", "```"] или иной разделитель, по которому модель обычно начинает «пояснять» свой ответ. Это снижает риск, что downstream-парсер подавится лишним текстом.
  • Разделение ролей в few-shot промптах. Если промпт содержит примеры вида User: ... Assistant: ..., стоп-последовательность на "User:" не даст модели продолжить диалог за пользователя.
  • Ограничение длины «смысловое». Иногда stop на "---" или маркере разделителя удобнее, чем max_tokens: модель останавливается именно в семантической границе, а не посреди токена.

Главный риск stop_sequencesложное срабатывание. Если стоп-строка встречается в легитимном содержании ответа (например, "Глава" в художественном тексте), модель обрывается раньше времени. Поэтому стоп-последовательности выбирают максимально нейтральными и маловероятными в полезном тексте — обычно это специальные маркеры (<|end|>, ###, ===) или редкие сочетания символов.

Детерминизм и воспроизводимость

seed

seed — число, которое инициализирует генератор случайных чисел, используемый при сэмплинге. При одинаковом seed, одинаковом входе и одинаковых параметрах модель выдаёт одинаковый ответ. Это единственный способ добиться воспроизводимости у вероятностной модели — зафиксировать случайность.

seed решает несколько задач:

  • Отладка. Воспроизвести конкретный «плохой» ответ, чтобы понять, что пошло не так.
  • Тестирование. Фиксированный набор запросов с фиксированным seed даёт стабильный набор ответов — основа для регрессионных тестов промптов.
  • Бенчмарки. Все стандартизированные тесты моделей (см. Бенчмарки LLM) проводятся с seed = 0 и temperature = 0 (или близким к 0), чтобы результаты были сопоставимы между запусками.

Критические оговорки, без которых seed создаёт ложное чувство контроля.

seed не гарантирует детерминизм между бэкендами. Один и тот же seed у OpenAI, Anthropic и локальной Llama даст три разных ответа. Причины разные: разные реализации сэмплинга, разные численные типы (FP16 vs FP32), разный порядок редукций на GPU, batching-эффекты в инференс-движках (vLLM, TensorRT-LLM). Воспроизводимость через seed работает только в рамках одного бэкенда и одной версии модели.

seed не сохраняется между версиями модели. Новая версия модели (gpt-4-0613gpt-4-1106 и т. д.) обучена иначе, у неё другие логиты — и тот же seed даст другой ответ. Если у вас регрессионные тесты на seed, при смене версии модели их придётся переразмечать.

temperature = 0 не равно seed на 100%. У части вендоров temperature = 0 реализован как очень маленькое положительное значение (например, 1e-10), и из-за численной нестабильности greedy всё равно может иногда отклоняться. Если нужна строгая воспроизводимость — фиксируйте и seed, и temperature = 0, и не полагайтесь на temperature = 0 в одиночку.

Распределённый инференс ломает детерминизм. На крупных инференс-серверах запрос может попасть на разные GPU или пройти через разный batching, и из-за недетерминизма операций на GPU (особенно в FP16) один и тот же seed может дать слегка разные ответы даже на одном бэкенде. Для бизнес-логики, где важна строгая идемпотентность, это нужно учитывать.

Управление логитами и диагностика

logit_bias

logit_bias — словарь {token_id: bias}, который прибавляет указанное смещение к логитам конкретных токенов до softmax:

z'_i = z_i + b_i,   где b_i — bias для токена i (из logit_bias)

После этой коррекции распределение пересчитывается через softmax с температурой и сэмплинг. Смысл параметра — ручной, не зависящий от контекста сдвиг вероятностей отдельных токенов.

Типовые сценарии:

  • Форсировать токен. Большой положительный bias (например, +100) практически гарантирует, что токен будет выбран. Полезно, когда нужно жёстко зафиксировать начало ответа (например, всегда начинать с {, если дальше ждёте JSON).
  • Запретить токен. Большой отрицательный bias (например, -100) приравнивает вероятность токена к нулю. Применяют для блокировки определённых слов или символов, которые модель упорно генерирует вопреки инструкции.
  • Тонкая коррекция. Небольшой bias (±1..5) слегка повышает или понижает вероятность конкретного токена, не запрещая его полностью.

Главная сложность logit_bias — он работает с token_id, а не с текстом. Чтобы запретить слово, нужно знать, на какие токены оно разбивается токенизатором именно этой модели. Разные модели токенизируют по-разному: одно и то же слово на русском может быть одним токеном у одной модели и тремя — у другой. Поэтому logit_bias редко переносится между моделями без перенастройки.

У ряда современных API есть более высокоуровневые альтернативы — response_format (JSON-режим) и structured outputs / constrained decoding (грамматическое ограничение вывода через формальную грамматику, JSON Schema или регулярку). Они решают ту же задачу надёжнее, чем ручной logit_bias, и там, где они доступны, их предпочтительнее использовать.

logprobs и top_logprobs

logprobs (включить/выключить) и top_logprobs (число N) — диагностический параметр, который не влияет на генерацию, но вместе с ответом возвращает для каждого сгенерированного токена его логарифмическую вероятность log p_i, а также вероятности N наиболее вероятных альтернативных токенов на этом шаге.

Это окно во «внутреннее состояние» модели, которое критически полезно для нескольких задач.

Оценка уверенности. Если модель выбрала токен с p = 0.95 — она «уверена». Если с p = 0.3 — «сомневается», и дальше по ответу можно ожидать галлюцинацию. Без logprobs у пользователя нет никакого сигнала об уверенности модели в собственных словах, а с logprobs — есть. Это связывает параметр с метрикой калибровки (см. Метрики LLM, раздел «Калибровка»).

Отладка выбора токена. Если модель ведёт себя странно на конкретном шаге, top_logprobs показывает, какие альтернативы она рассматривала и насколько близко. Часто это объясняет «неожиданное» поведение: модель выбрала низковероятный токен из-за сэмплинга, и виден более вероятный кандидат, который был бы выбран при меньшей температуре.

Альтернативные варианты. Несколько верхних токенов на каждом шаге — это готовый материал для построения альтернативных продолжений без повторной генерации. В исследованиях и при тонкой оптимизации промптов это ценный сигнал.

Минус logprobs — заметный рост объёма ответа (и, у коммерческих моделей, иногда стоимости запроса), потому что на каждый токен возвращается массив вероятностей. Для production-сценариев с большими объёмами его включают точечно, только где нужен сигнал уверенности.

Множественные кандидаты и поиск

Эта группа параметров генерирует несколько вариантов ответа и выбирает наилучший. Идея простая: если один сэмпл может оказаться неудачным из-за случайности, давайте возьмём несколько и выберем лучший — по какой-то метрике или просто самый вероятный.

best_of и n

best_of (или n, num_return_sequences — названия зависят от бэкенда) задаёт число N независимо сгенерированных вариантов ответа. Дальше возможно два режима.

best_of без ранжирования. Генерируется N вариантов, и возвращается тот, у которого суммарная логарифмическая вероятность максимальна:

score(variant) = Σ_t log p(token_t)        // суммарная log-вероятность токенов
выбирается вариант с максимальным score

Это «лучший по модели» вариант — тот, который модель сама считает наиболее вероятным. Подходит для задач, где нет внешней метрики качества, а хочется просто снизить дисперсию сэмплинга.

n с возвратом всех вариантов. Возвращаются все N вариантов, а выбор лучшего делается на стороне вызывающего — например, второй моделью (LLM-as-a-judge) или эвристикой. Это основа reranking-схем в генерации.

Главный минус очевиден: стоимость и latency умножаются на N. best_of = 5 означает пятикратную стоимость и примерно пятикратное время ответа. Поэтому множественные кандидаты используют точечно — там, где качество одного сэмпла критично, а экономика позволяет (например, генерация финального ответа в дорогом RAG-пайплайне, но не в массовом чате).

beam search и length_penalty

Beam search — классический алгоритм поиска, пришедший из машинного перевода и суммаризации. В отличие от сэмплинга, он ведёт не одну последовательность, а B «пучков» (beams) — на каждом шаге расширяет каждый пучок всеми возможными следующими токенами, оставляет B лучших по суммарной лог-вероятности и так до конца. Параметр Bnum_beams.

Чтобы сбалансировать предпочтение коротких последовательностей (короткий текст имеет более высокую суммарную log-вероятность просто потому, что слагаемых меньше), при скоринге применяется length penalty:

score = (Σ_t log p(token_t)) / L^λ

Здесь L — длина последовательности, λlength_penalty. При λ = 1 влияние длины нейтрально, при λ > 1 длинные последовательности штрафуются слабее (модель предпочитает длинные ответы), при λ < 1 — сильнее (модель предпочитает короткие).

Beam search даёт более «уверенные» и связные ответы, чем жадный выбор, и исторически был стандартом в машинном переводе и суммаризации. Но для современных чат-моделей он почти не используется по нескольким причинам.

Потеря разнообразия. Beam search систематически выбирает «безопасные», высоковероятные формулировки — ответы получаются правильными, но пресными и однообразными. Для диалога это плохо: пользователи ценят «живость».

Вычислительная стоимость. num_beams = B означает, что на каждом шаге модель обсчитывает B гипотез, а не одну. Стоимость и latency растут пропорционально.

Рассогласование с обучением. Современные чат-модели обучены (в том числе через RLHF) на сэмплинге, а не на beam search; их поведение оптимизировано именно под вероятностный выбор. Применение beam search к такой модели часто даёт худший результат, чем простой сэмплинг с правильной температурой.

Поэтому beam search сегодня — нишевый инструмент для задач с эталоном и метрикой выбора (перевод, суммаризация в пайплайнах), а для чат-сценариев практически не применяется.

Как выбирать параметры под сценарий

Нет «правильных» значений параметров вообще — есть значения, адекватные задаче. Ниже — практические пресеты для типовых сценариев. Это отправные точки, которые нужно калибровать на собственных данных (см. Метрики LLM).

Сценарий temperature top_p top_k penalties max_tokens stop Примечание
Извлечение фактов, классификация, JSON 0 1 выкл. с запасом да Максимальная предсказуемость
RAG, ответ по документам 0.2–0.4 0.9–0.95 выкл. с запасом опц. Точность приоритетнее разнообразия
Перевод, суммаризация 0.3–0.5 0.9 выкл. или слабый repetition_penalty по задаче опц. Можно beam search для перевода
Чат-бот, ассистент 0.6–0.8 0.9–0.95 freq 0.2–0.4 широкий нет Баланс естественности и контроля
Креатив, брейншторм 0.9–1.2 0.95–1.0 presence 0.3–0.6 широкий нет Разнообразие важнее точности
Reasoning-модели см. док. выкл. с учётом reasoning tokens нет Часто фиксированные параметры
Бенчмарки, тесты 0 1 выкл. с запасом нет Строгая воспроизводимость

Несколько универсальных принципов, которые стоит держать в голове независимо от сценария.

Минимум изменяемых параметров. Чем больше параметров отступает от дефолта, тем сложнее интерпретировать поведение и тем выше риск внезапной деградации при смене версии модели. Начинайте с temperature и top_p, добавляйте остальные только если есть измеримая причина.

Фиксируйте параметры в конфиге. Параметры инференса — часть контракта модели с продуктом. Они не должны подбираться «на глаз» каждым разработчиком: фиксируйте их в конфигурации, версонируйте и меняйте осознанно, через метрики.

Перепроверяйте схему штрафов. Перед настройкой frequency_penalty / presence_penalty / repetition_penalty уточните, какую схему поддерживает ваш бэкенд, и не смешивайте несовместимые.

Антипаттерны

Несколько типовых ошибок, которые встречаются регулярно.

«Выкрутил всё на максимум». Одновременная высокая temperature, широкий top_p, агрессивные штрафы и большой max_tokens — модель начинает вести себя непредсказуемо, ответы теряют связность, стоимость взлетает. Каждый параметр по отдельности осмыслен, но их комбинация на экстремальных значениях почти никогда не оправдана.

«temperature = 0 гарантирует детерминизм везде». Как описано в разделе про seed, это не так: детерминизм работает только в рамках одного бэкенда, одной версии модели и без распределённого инференса. Если бизнес-логика полагается на строгую идемпотентность, это нужно явно тестировать на целевом окружении.

Смешение OpenAI- и HF-штрафов. frequency_penalty + presence_penalty и repetition_penalty — две несовместимые реализации одной идеи. Если бэкенд принимает обе (редкость), одновременное применение даёт двойной штраф и непредсказуемый результат.

Игнорирование stop_sequences в пайплайнах. Если вывод модели парсится программой, отсутствие stop_sequences — постоянный риск, что модель добавит «поясняющий» текст после полезного ответа и сломает парсер. С другой стороны, слишком агрессивные стоп-строки приводят к ложным обрывам. Выбирать их нужно так же осознанно, как и температуру.

max_tokens «по умолчанию» для reasoning-моделей. Стандартный лимит, подобранный под обычные модели, у reasoning-модели почти всегда оказывается слишком маленьким — значительная часть уходит на скрытые reasoning tokens, и ответ обрывается на середине видимой части.

Подбор параметров «на одном примере». Параметры подбираются на репрезентативном наборе запросов с измеримыми метриками, а не по одному «показательному» примеру. На одном запросе легко получить картину, которая не подтвердится на массе.

Резюме

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

Здоровый подход — минимализм и измеримость: менять как можно меньше параметров, каждое изменение обосновывать измеримой причиной, фиксировать значения в конфигурации и проверять устойчивость выборки на собственных метриках. Подробно о том, какие метрики выбирать под разные сценарии — в Метрики LLM; о том, как модели сравнивают между собой на стандартизированных тестах с фиксированными параметрами — в Бенчмарки LLM. Общий контекст осознанного встраивания ИИ в процесс разработки — в разделе Искусственный интеллект.