Как ограничить длину ответа в Ollama через num_predict
Узнайте, как использовать параметр num_predict для ограничения количества выходных токенов. Разберем приоритеты настроек и обработку статуса done_reason при достижении лимита.
Что делает параметр num_predict в Ollama
num_predict — это опция Ollama, которая ограничивает количество токенов, генерируемых моделью в одном ответе. Учитываются только выходные токены, поэтому размер промпта на этот лимит не влияет. Когда модель достигает установленного предела, генерация останавливается, иногда на середине слова, а ответ возвращается с параметром done_reason, установленным в length.
Это вся функциональность данной опции. Сложность заключается в том, что Ollama предоставляет три различных места для установки этого значения, и приоритет имеет настройка, расположенная ближе всего к запросу. Почти каждый отчет о том, что "num_predict не работает", связан с тем, что один уровень настроек незаметно переопределяет другой.
num_predict — это не num_ctx
Эти два параметра путают чаще, чем любую другую пару в Ollama, и эта путаница отнимает время при отладке.
num_ctx определяет, какой объем данных модель может прочитать. Это размер контекстного окна, которое содержит промпт и всё, что было сгенерировано к текущему моменту. Увеличение этого параметра требует больше памяти, так как кэш ключей и значений (key/value cache), который модель хранит для этих токенов, растет вместе с окном. Выбор размера num_ctx для вашего оборудования — это отдельная задача со своими специфическими ошибками.
num_predict определяет, какой объем данных модель может записать. Это правило остановки, а не выделения ресурсов. Увеличение этого параметра влияет на время выполнения, а не на объем оперативной памяти, и заранее никакие ресурсы не резервируются.
Они пересекаются в одном аспекте. Сгенерированные токены попадают в контекстное окно по мере их создания, поэтому ответ может прерваться как из-за заполнения окна, так и из-за достижения лимита. Ollama сообщает length в обоих случаях, поэтому число, позволяющее их различить, — это eval_count, о котором рассказано ниже.
Установка параметра через Modelfile
Modelfile позволяет «запечь» значение непосредственно в создаваемую модель. Создайте файл:
FROM qwen3:8b
PARAMETER num_ctx 8192
PARAMETER num_predict 512Затем выполните сборку и проверьте параметры созданной модели:
ollama create qwen3-capped -f Modelfile
ollama show --parameters qwen3-cappedКоманда ollama show --parameters выводит по одной строке для каждого сохраненного параметра с его значением. Если в выводе отсутствует num_predict, значит, в модели не задано ограничение, и Ollama использует значение по умолчанию. Команда ollama show --modelfile qwen3-capped выводит полное определение модели; это самый быстрый способ скопировать параметры, с которыми поставляется существующая модель.
Этот уровень настройки подходит, если вы хотите, чтобы значение наследовалось всеми пользователями модели. Этот метод не подходит, если вы ожидаете, что значение будет окончательным и неизменным, так как это не так.
Установка параметра в объекте options для каждого запроса
Каждый эндпоинт генерации принимает объект options, внутри которого размещается num_predict:
curl http://localhost:11434/api/generate -d '{
"model": "qwen3:8b",
"prompt": "Explain what a reverse proxy does.",
"stream": false,
"options": { "num_predict": 128 }
}'/api/chat использует тот же ключ options с тем же значением. Указанное здесь значение применяется только к данному конкретному вызову. Это уровень, на котором работают ваши инструменты: веб-интерфейс чата, скрипт, обертка SDK или агент для написания кода. Все они отправляют объект options, независимо от того, отображается ли для него поле ввода в интерфейсе.
Установка параметров для одного сеанса с помощью команды /set
Внутри ollama run интерактивный сеанс задает параметры для всех последующих действий в рамках этого сеанса:
>>> /set parameter num_predict 256
>>> /show parameters/show parameters выводит данные, которые сеанс отправит вместе с вашим следующим сообщением. Это самый быстрый способ убедиться, что изменения вступили в силу. Значение сохраняется до тех пор, пока вы не введете /bye. Чтобы сохранить настройки, /save qwen3-capped записывает текущий сеанс, включая параметры, как новую модель. Все, что вы /set здесь, не передается другим клиентам.
Какой параметр имеет приоритет и почему ваш игнорируется
Порядок прост. Параметры, переданные в запросе, имеют приоритет над всем остальным. Строка PARAMETER num_predict в файле Modelfile модели является резервным значением, которое используется, если в запросе нет явного указания. Если не задано ни то, ни другое, применяются встроенные значения по умолчанию Ollama.
/set parameter не является третьим правилом. Интерактивная сессия выступает в роли API-клиента, поэтому всё, что вы там настраиваете, отправляется как options этого запроса, что и объясняет, почему настройки сессии переопределяют Modelfile.
Теперь о сбое, который это объясняет. Вы добавляете PARAMETER num_predict 512, пересобираете модель, но ответы всё равно достигают тысяч токенов. Ваш параметр присутствует, и ollama show --parameters подтверждает это. Он переопределяется при каждом запросе, так как клиент отправляет собственный объект options со своим числом — часто это значение, которое вы ввели в настройках приложения несколько месяцев назад и забыли. ollama show считывает сохранённую модель. Команда не может показать вам то, что приходит по HTTP.
Проверьте серверную часть одной командой. Отправьте запрос, который должен сгенерировать длинный ответ, принудительно установите низкий лимит и считайте два поля:
curl -s http://localhost:11434/api/generate -d '{
"model": "qwen3-capped",
"prompt": "Describe the Linux boot process in detail.",
"stream": false,
"options": { "num_predict": 32 }
}' | jq '.done_reason, .eval_count'Эта команда должна вывести "length" и 32. Если утилита jq отсутствует, установите её с помощью sudo apt install -y jq. Ответ "length" и 32 означает, что сервер учитывает параметр, а ваше приложение отправляет что-то другое. Чтобы увидеть, как сервер интерпретирует запрос, перезапустите его с переменной OLLAMA_DEBUG=1 в окружении и наблюдайте за journalctl -u ollama -f во время взаимодействия с приложением.
Отрицательные значения и числа, которые не следует копировать
num_predict также принимает отрицательные значения, которые являются не счетчиками, а служебными метками. Одно отрицательное значение означает «не ограничивать, продолжать генерацию». Другое использовалось для обозначения «заполнить оставшийся контекст». По состоянию на август 2026 года в справочнике Ollama Modelfile значением по умолчанию указано -1 (бесконечная генерация), а в более ранних версиях той же таблицы для заполнения контекста указывалось -2.
Считайте, что все эти данные зависят от версии, так как они неоднократно менялись. В документации значение по умолчанию долгое время было указано как 128, прежде чем запись была исправлена в конце 2024 года, поэтому многие руководства до сих пор повторяют старое число. Изучите справочник параметров Modelfile для той версии, которую вы используете, а затем подтвердите поведение с помощью проверки eval_count, описанной выше. Значение, которое вы проверили на собственном сервере, надежнее любого значения, прочитанного где-либо еще, включая эту публикацию.
Почему длина вывода — основной фактор затрат на VPS без GPU
Генерация состоит из двух фаз, скорость которых существенно различается. Токены промпта обрабатываются пакетами, по много штук за раз. Токены вывода создаются по одному, и каждый из них требует полного прохода по весам модели. На VPS без GPU этот проход ограничен пропускной способностью памяти, поэтому один сгенерированный токен стоит значительно дороже, чем один токен промпта.
Запросите ответ без потоковой передачи (streaming), и вы увидите реальные цифры:
"prompt_eval_count": 26,
"prompt_eval_duration": 107345000,
"eval_count": 237,
"eval_duration": 4289432000Длительность указана в наносекундах. В этом блоке, который является примером ответа из документации API Ollama, а не замером на конкретном сервере, обработка 26 токенов промпта заняла около 0.1 секунды, тогда как генерация 237 токенов вывода потребовала около 4.3 секунд. Ваша собственная скорость генерации — это eval_count, деленное на eval_duration, переведенное в секунды. Стоит один раз выполнить замер количества токенов в секунду на вашем оборудовании, прежде чем приступать к дальнейшей настройке. Эта скорость зависит как от модели, так и от характеристик машины. Если длинные ответы создают основную нагрузку, модель, оптимизированная для быстрого декодирования, такая как Nemotron 3.5 Lightning на VPS, поможет вернуть часть времени, которое в противном случае пришлось бы ограничивать жесткими лимитами.
Арифметика проста. При скорости 8 токенов в секунду ответ объемом 2,000 токенов занимает ресурсы машины более чем на четыре минуты, при этом модель не знает, что вам нужен был всего лишь один абзац. Некоторые модели также могут зацикливаться, повторяя фразу до тех пор, пока их что-то не остановит. Без ограничения этот единственный запрос будет занимать ядро процессора, пока не исчерпается контекстное окно. num_predict — это параметр, который задает границы, что особенно важно на небольшом самостоятельно хостящемся VPS с Ollama, где один длинный запрос может полностью заблокировать работу всей машины.
Усеченный вывод обычно вызван ограничением, а не ошибкой модели
Симптомы часто выглядят как сбой модели. Ответ обрывается на полуслове. JSON не парсится, так как отсутствует закрывающая скобка. Первым делом возникает желание обвинить модель или квантование. Сначала изучите ответ.
done_reason отвечает на вопрос напрямую. stop означает, что модель завершила работу самостоятельно, либо выдав токен конца последовательности, либо совпав с одной из строк в вашей опции stop. length означает, что генерация была прервана из-за нехватки места. Когда вы видите length, сравните eval_count с вашим лимитом: точное совпадение означает, что его остановил num_predict, а меньшее число означает, что сначала заполнилось контекстное окно.
При потоковой передаче эти поля приходят в финальном чанке, который несет "done": true. Многие клиентские библиотеки отбрасывают этот чанк и передают вашему коду только текст, поэтому одно и то же усечение выглядит необъяснимым внутри приложения и очевидным при использовании curl. Если библиотека скрывает это, отправьте один запрос с curl, чтобы узнать, что на самом деле ответил сервер.
Еще один момент поможет сэкономить время. Увеличение num_predict не заставляет модель писать больше. Оно лишь убирает потолок. Если ответ заканчивается на 200 токенах с done_reason равным stop, значит, модель решила, что закончила, и увеличение лимита ничего не изменит. Короткие ответы с stop — это проблема промптинга. Короткие ответы с length — это проблема лимита.
Выбор значения
- Для интерактивного чата оставьте значение без ограничений и используйте Ctrl+C, чтобы остановить бесконечный ответ. Вы в любом случае следите за экраном.
- Для любых скриптов установите ограничение. Неограниченная генерация внутри цикла — это причина, по которой пакетное задание, рассчитанное на десять минут, может выполняться до следующего утра.
- Для структурированного вывода установите ограничение выше размера самого большого ожидаемого документа, а затем рассматривайте
done_reasonизlengthкак критическую ошибку и выполняйте повторную попытку вместо попытки разбора полученных данных. - Для агента написания кода это значение должно находиться в конфигурации самого агента, так как агент отправляет свои параметры с каждым запросом. В Настройка агента для работы с Ollama описано, где хранятся эти параметры.
Ограничение учитывает токены, а не слова или символы, поэтому не пытайтесь оценивать его «на глаз». Сгенерируйте один типичный ответ без ограничений, прочитайте eval_count и установите лимит с запасом выше этого значения. Разные семейства моделей используют разную токенизацию, поэтому значение, подходящее для модели Llama, может привести к обрезанию того же ответа от модели Qwen 3 на том же VPS.
FAQ
В чем разница между num_ctx и num_predict в Ollama?
num_ctx — это размер контекстного окна, определяющий объем данных, которые модель может прочитать: промпт плюс всё, что было сгенерировано ранее. Это расходует память, так как кэш ключей и значений (key/value cache) растёт пропорционально. num_predict задаёт количество токенов, которое модель может записать в одном ответе. Это расходует время, а не память, и заранее ничего не резервируется. Сгенерированные токены учитываются в обоих параметрах, поэтому ответ может быть прерван любым из них.
Почему мой параметр num_predict игнорируется?
Потому что значение, переданное в запросе, имеет приоритет над значением, сохранённым в модели. Если вы укажете PARAMETER num_predict 512 в Modelfile, а затем будете использовать эту модель через чат-интерфейс или агент для программирования, клиент отправит собственный объект options, значение которого будет решающим. ollama show --parameters по-прежнему будет отображать ваше значение, так как он считывает сохранённую модель и не видит того, что приходит по HTTP. Отправьте один запрос с curl, используя "options": {"num_predict": 32}, и убедитесь, что eval_count возвращает 32. Это подтвердит, что сервер работает корректно, и перенесёт поиск причины в ваше приложение.
Как узнать, был ли вывод обрезан из-за num_predict?
Отправьте запрос с "stream": false и прочитайте done_reason. Значение stop означает, что модель завершила работу самостоятельно. Значение length означает, что место закончилось. Затем сравните eval_count с вашим лимитом: если они в точности совпадают, значит, работу остановил num_predict, а если eval_count меньше, значит, первым заполнилось контекстное окно. При потоковой передаче оба поля приходят в финальном чанке с "done": true, который многие клиентские библиотеки отбрасывают до того, как ваш код получит к ним доступ.
Каково значение по умолчанию для num_predict?
Узнавайте его из своей собственной установки, а не из статей. По состоянию на август 2026 года в справочнике по Modelfile для Ollama указано значение по умолчанию -1, что означает отсутствие ограничения на генерацию. Эта запись была исправлена в конце 2024 года после многолетнего документирования значения 128. Отрицательные значения являются служебными метками, а не счётчиками; в старых версиях той же таблицы также указывалось -2 для заполнения оставшегося контекста. Проверьте справочник параметров Modelfile для вашей версии, а затем подтвердите значение с помощью ollama show --parameters и одного запроса curl.
Увеличит ли повышение num_predict длину ответов модели?
Нет. Это лишь снимает ограничение. Если ответ заканчивается на done_reason из stop, значит, модель решила, что закончила, и увеличение лимита ничего не изменит. Длина в этом случае — вопрос промпта: запрашивайте конкретную структуру, количество разделов или определённый уровень детализации. Увеличивайте num_predict только тогда, когда done_reason возвращает length.