Гайд · TNWS AI
Как ограничить генерацию llama.cpp через n_predict и проверить причину остановки
Используем native /completion и поля остановки, чтобы отличить заданный лимит от нормального конца ответа.
Задача и применимость
Поисковый вопрос: «как ограничить длину ответа llama.cpp completion n_predict stop stopped_limit». Не отдавать клиенту оборванный ответ как завершённый, когда генерация остановилась на лимите. llama.cpp server, native POST /completion, на 20 сентября 2026 года по официальному README. Нужна именно генеративная GGUF-модель; endpoint несовместим по форме с OpenAI /v1/completions.
Пример рассчитан на уже имеющийся файл модели, полученный законным способом по условиям его лицензии. Здесь не утверждается, что любая GGUF-модель одинаково понимает русский язык или имеет один и тот же чат-шаблон. Фактический номер сборки узнавайте локально через llama-server --version и повторяйте контрольный опыт после обновления бинарника.
Что подтверждено документацией
Документация указывает n_predict как максимум генерируемых токенов, значения 0 — только вычисление prompt в cache и -1 — без такого лимита. stop — массив строк остановки, которые исключаются из content. В ответе присутствуют stop_type, stopping_word, timings и признак truncated; типы остановки включают eos, limit и word.
Порядок действий
- Сформулируйте маленькую задачу с ожидаемым законченным ответом.
- Передайте /completion prompt и ограничение n_predict, не включая stream.
- Прочитайте content, stop_type и truncated; запишите длину ответа.
- Если stop_type=limit, пометьте ответ незавершённым и пересмотрите лимит и контекст.
- Проверяйте каждое новое правило stop на контрольном тексте с теми же словами.
Локальный запуск для описанного сценария (замените путь к файлу на ваш):
./build/bin/llama-server -m /models/your-chat-model.gguf --host 127.0.0.1 --port 8080
Готовый шаблон запроса и проверки
import json, urllib.request
body = {"prompt": "Ответь одной фразой: что такое GGUF?",
"n_predict": 64, "stream": False, "stop": ["<END>"]}
request = urllib.request.Request(
"http://127.0.0.1:8080/completion",
data=json.dumps(body, ensure_ascii=False).encode("utf-8"),
headers={"Content-Type": "application/json"}, method="POST")
with urllib.request.urlopen(request, timeout=90) as response:
result = json.load(response)
print("Текст:", result.get("content", ""))
print("Причина:", result.get("stop_type"),
"усечён контекст:", result.get("truncated"))
if result.get("stop_type") == "limit" or result.get("truncated"):
raise ValueError("Ответ или контекст надо проверить перед публикацией")
Входные данные и ожидаемый результат
Вход: просьба дать одну фразу про GGUF и n_predict=64. Выход зависит от модели; ожидаемые проверяемые данные — строка content и причина остановки. При limit программа сообщает ошибку вместо уверенного показа обрывка. При eos ответ может быть полным, но фактическое утверждение всё равно нужно сверить.
Почему важна именно эта проверка
n_predict ограничивает генерацию, а не размер уже поданного prompt. Если исходные документы переполняют контекст, увеличивать лимит вывода бессмысленно; обратите внимание на поле truncated. Когда модель дала лишь начало предложения, сохранение такого фрагмента в базу знаний как «готового ответа» создаёт ложную уверенность у читателя. Тип limit является сигналом для приложения, а не для модели. Увеличивать лимит до бесконечности также плохо: запросы способны занять слот сервера надолго, поэтому лимит должен соответствовать задаче и ограничениям вашей инфраструктуры.
Работа с реальными данными
Строки stop полезны в многочастных сценариях, но их нельзя выбирать из обычной лексики ответа. Если поставить stop ["доставка"], вопрос о доставке завершится слишком рано, а остановившая строка не попадёт в content. Контрольная строка <END> здесь служит примером маркера, а не гарантией, что модель вообще её выдаст. Когда нужно продолжить диалог после остановки по слову, официальная документация требует учесть исключённое слово в следующем prompt. Лучше избегать ручного продолжения, если задача решается стандартным chat endpoint.
Проверка после изменения модели или нагрузки
Для продакшена проверьте три входа: короткий факт, длинный список и запрос с неоднозначным условием. На каждом сохраните stop_type и факт truncated отдельно от времени генерации. Даже при eos модель может ошибаться по содержанию, так что статус завершения не служит оценкой правды. Не считайте одинаковые n_predict равными по числу символов: токенизация разных языков и моделей отличается. После смены GGUF настройте предел заново по реальной длине ответов и числу слотов, не переносите прежний лимит механически.
Для контрактного ответа с фиксированным количеством полей продумайте явную валидацию полноты: если обещаны три пункта, проверьте, что все три присутствуют до показа. Даже когда stop_type не равен limit, модель может сама закончить раньше по EOS. Разные причины требуют разных действий: при limit пересмотрите бюджет, при word проверьте список stop, при eos проверьте содержимое исходного задания. Результат, в котором не хватает обязательного пункта, нельзя автоматически отправлять в письмо или карточку товара.
Критерии приёмки
- Выход содержит content и осмысленно разобранный stop_type.
- При limit публикация полного ответа не происходит.
- При truncated проверяется вместимость исходного контекста.
Частые ошибки и чего не делать
- Не считать n_predict ограничением длины входа.
- Не выбирать стоп-слово из естественного ответа.
- Не принимать eos за подтверждение фактов.
Краткие ответы на вопросы
Что делает n_predict=0?
Обрабатывает prompt для кэша без выдачи токенов.
Что означает stop_type=limit?
Достигнут лимит генерации.
Входит ли stop-строка в content?
Нет, документация указывает её исключение.
Официальные источники
Частые вопросы
Что делает n_predict=0?
Обрабатывает prompt для кэша без выдачи токенов.
Что означает stop_type=limit?
Достигнут лимит генерации.
Входит ли stop-строка в content?
Нет, документация указывает её исключение.
Читайте также
Как переранжировать найденные документы через llama.cpp /v1/rerank
Запускаем reranker GGUF, подаём список кандидатов и проверяем порядок и связь результата с исходными документами.
Как получить embeddings через llama.cpp /v1/embeddings и проверить pooling
Запускаем специализированную embedding-модель, кодируем две строки и проверяем размерность и числовой формат.
Как получить JSON по схеме через response_format в llama.cpp server
Задаём объектную JSON Schema в chat endpoint, разбираем строку content и валидируем обязательные поля отдельно.
Комментарии
Пока тихо. Скажите первое слово