Проклятие бесконечного reasoning: когда Step-3.5-Flash-Int4 застревает в петле
Вы запускаете Step-3.5-Flash-Int4 через llama.cpp, задаете сложный вопрос, а модель начинает рассуждать... и не может остановиться. Тот же абзац. Снова. И еще раз. "Давайте проанализируем...", "Следовательно...", "Таким образом..." - бесконечный поток одинаковых мыслей.
Это не баг модели. Это следствие неправильных настроек. Особенно для Step-3.5-Flash-Int4 - компактной, но мощной модели для reasoning задач, выпущенной в начале 2026 года. Ее архитектура оптимизирована под цепочки рассуждений, но без правильных параметров в llama.cpp она превращается в заигранную пластинку.
Классическая ошибка: скопировать параметры из документации или чужого примера. Температура 0.7, top_p 0.9 - и готово. Для Step-3.5-Flash-Int4 это гарантия повторений после 200-300 токенов.
Почему Step-3.5-Flash-Int4 особенная и почему она так легко зацикливается
Step-3.5-Flash-Int4 - это не просто очередная 7B-модель. Ее тренировали специально для многошагового reasoning, с акцентом на последовательные рассуждения. В результате:
- Модель склонна к самоподтверждению - каждая следующая мысль строится на предыдущей слишком жестко
- Внутренние механизмы attention слишком "цепкие" к недавнему контексту
- Квантование в Int4 усиливает эффект - некоторые паттерны становятся доминирующими
Если вы сталкивались с проклятием бесконечного reasoning у GLM 4.7 Flash, то здесь ситуация похожая, но с другими корнями.
1 Диагностика: как понять, что проблема в настройках, а не в модели
Перед тем как лезть в параметры, убедитесь. Запустите модель с дефолтными настройками и дайте задачу на reasoning средней сложности. Если через 400-500 токенов вывод начинает повторяться - проблема точно в конфигурации llama.cpp.
# Типичная команда, которая приводит к зацикливанию
./main -m step-3.5-flash-int4.gguf \
--temp 0.7 \
--top-p 0.9 \
--repeat-penalty 1.1 \
-p "Реши задачу: у Васи было 5 яблок..."
Эта конфигурация работает для обычных моделей, но для Step-3.5-Flash-Int4 она смертельна.
Оптимальный набор параметров: не просто цифры, а понимание каждого флага
| Параметр | Обычные модели | Step-3.5-Flash-Int4 | Почему разница |
|---|---|---|---|
| --temp | 0.7-0.8 | 0.3-0.4 | Низкая температура уменьшает случайность, но для reasoning это нужно - меньше шума в рассуждениях |
| --top-k | 40 | 20 | Ограничиваем выбор следующих токенов, предотвращая скачки в логике |
| --repeat-penalty | 1.1 | 1.3-1.4 | Агрессивнее наказываем повторения, особенно важно для длинных reasoning цепочек |
| --repeat-last-n | 64 | 128 | Смотрим дальше в истории, чтобы ловить циклические паттерны |
| --ctx-size | 2048 | 4096 | Reasoning требует больше контекста для хранения промежуточных шагов |
2 Критически важный параметр: --repeat-penalty-range
Вот что большинство упускает. В llama.cpp появился параметр --repeat-penalty-range (в некоторых версиях --repeat-window). Он определяет, на сколько токенов назад смотреть при применении штрафа за повторения.
Для Step-3.5-Flash-Int4 ставьте 256 или 512. Почему? Модель строит reasoning блоками по 5-10 предложений. Если штрафовать только последние 64 токена, она будет повторять блоки целиком.
# Рабочая конфигурация для сложного reasoning
./main -m step-3.5-flash-int4.gguf \
--temp 0.35 \
--top-k 20 \
--top-p 0.85 \
--repeat-penalty 1.35 \
--repeat-penalty-range 256 \
--ctx-size 4096 \
-n 1024 \
--mlock \
-ngl 99 \
-p "Проанализируй следующую бизнес-задачу..."
3 Тонкая настройка: batch size и потоков
Здесь многие совершают ошибку, думая "больше потоков - быстрее". Для Step-3.5-Flash-Int4 в reasoning режиме:
- --threads 4-6 (не 8 или больше) - слишком много потоков мешают последовательному reasoning
- --batch-size 512 для первой загрузки, потом --ubatch-size 256 для инференса
- --no-mmap если у вас быстрый SSD - уменьшает задержки при длинных контекстах
Почему меньше потоков? Reasoning - последовательная операция. Параллелизация на уровне CPU мешает внутренней когерентности модели. Это не матричные вычисления, где больше ядер всегда лучше.
Системные триггеры остановки: когда модель все равно не останавливается
Даже с идеальными параметрами Step-3.5-Flash-Int4 иногда уходит в бесконечный reasoning. Особенно на задачах типа "напиши план на 10 шагов" - она пишет 20, 30, 40...
Добавьте эти флаги:
# Дополнительные ограничители
--mirostat 2 \
--mirostat-lr 0.05 \
--mirostat-ent 3.0 \
--stop "\nОтвет:" \
--stop "\nFinal answer:" \
--stop "\nТаким образом"
Mirostat 2 - алгоритм контроля перплексии. Он следит за "предсказуемостью" вывода и мягко подталкивает модель к завершению. Не используйте mirostat 1 - он слишком агрессивный для reasoning.
Stop-токены должны быть специфичными для вашей задачи. Если модель пишет рассуждение на английском, добавьте "\nTherefore:" и "\nIn conclusion:".
Не переборщите со stop-токенами. Слишком много ограничений сломает естественный flow reasoning. 3-5 достаточно. Если нужно больше, возможно, проблема в prompt engineering, а не в настройках llama.cpp.
Промпт имеет значение: как задавать вопросы Step-3.5-Flash-Int4
Можно идеально настроить llama.cpp, но если промпт кривой, модель все равно зациклится. Step-3.5-Flash-Int4 особенно чувствительна к формулировкам.
Как НЕ делать: "Напиши подробный план разработки приложения. Опиши каждый шаг."
Как делать: "Напиши план разработки приложения на 7 шагов. После шага 7 остановись и выведи 'План завершен'."
Явные ограничения в промпте работают лучше скрытых. Модель обучена следовать инструкциям буквально.
Проверка работоспособности: тестовый сценарий
Создайте тестовый файл и запустите. Если все настроено правильно, модель должна:
- Сгенерировать reasoning на 300-800 токенов
- Не повторять абзацы или предложения
- Естественно завершиться или остановиться по stop-токену
- Не терять логическую связность
#!/bin/bash
# test_reasoning.sh
MODEL="step-3.5-flash-int4.gguf"
PROMPT="Реши задачу: Компания планирует запустить новый продукт. У них есть бюджет 100 000 рублей. Разработка стоит 40 000, маркетинг 35 000, поддержка первый месяц 15 000. Хватит ли бюджета? Объясни по шагам. После вычислений напиши 'Ответ: да' или 'Ответ: нет'."
./main -m $MODEL \
--temp 0.35 \
--top-k 20 \
--repeat-penalty 1.35 \
--repeat-penalty-range 256 \
--ctx-size 4096 \
-n 512 \
--stop "Ответ:" \
-p "$PROMPT" \
| tee test_output.txt
# Проверяем длину и повторения
echo "\n=== Анализ вывода ==="
OUTPUT=$(cat test_output.txt)
TOKEN_COUNT=$(echo "$OUTPUT" | wc -w)
echo "Токенов: $TOKEN_COUNT"
# Ищем повторяющиеся фразы (простая проверка)
echo "$OUTPUT" | grep -o "Таким образом" | wc -l | xargs echo "Фраза 'Таким образом' повторяется:"
А если не помогает? Когда проблема не в llama.cpp
Бывает, что все параметры идеальны, но модель все равно повторяется. Тогда проблема может быть:
- В самой GGUF-версии модели (попробуйте другую квантовку, например, Q5_K_M)
- В контексте диалога (предыдущие сообщения зацикливают модель)
- В специфике задачи (некоторые темы просто провоцируют циклическое reasoning)
В таком случае попробуйте техники из статьи про GLM 4.7 Flash - многие принципы универсальны.
Итоговая конфигурация для продакшена
# Продакшен-конфиг для Step-3.5-Flash-Int4 в llama.cpp
# Для reasoning задач средней сложности
./main -m step-3.5-flash-int4.gguf \
--temp 0.35 \
--top-k 20 \
--top-p 0.85 \
--min-p 0.05 \
--repeat-penalty 1.35 \
--repeat-penalty-range 256 \
--repeat-last-n 128 \
--ctx-size 4096 \
--threads 6 \
--batch-size 512 \
--ubatch-size 256 \
--no-mmap \
--mlock \
-ngl 99 \
--mirostat 2 \
--mirostat-lr 0.05 \
--mirostat-ent 3.0 \
--stop "\nОтвет:" \
--stop "\nВывод:" \
--stop "\nИтак:" \
-n 1024 \
-p "${PROMPT}"
Последний совет: ведите лог экспериментов. Записывайте, какие параметры вы меняли и как это повлияло на вывод. Step-3.5-Flash-Int4 капризна, но предсказуема. Через 10-15 тестовых запусков вы поймете ее "характер" и сможете тонко настраивать под конкретные задачи.
И помните - иногда лучшее решение для бесконечного reasoning не в параметрах llama.cpp, а в архитектуре приложения. Разбивайте сложные задачи на подзадачи, используйте цепочки инструментов или устанавливайте жесткие лимиты токенов на уровне приложения.
Модель не должна думать вечно. Даже если она очень хочет.