В чём проблема: Laguna S 2.1 молчит в режиме рассуждений
Модель Laguna S 2.1 не выводит цепочку рассуждений из-за некорректной обработки параметра preserve_thinking в chat-template. Проблема проявляется при любых запросах, требующих reasoning - модель сразу генерирует финальный ответ, пропуская этап обдумывания. Разработчики Poolside дважды обновляли шаблон за сутки, но сообщество подтверждает: корень проблемы глубже, чем казалось изначально. Решение уже найдено и проверено - замена chat-template на шаблон от Qwen 27B через флаг --chat-template-file в llama.cpp.
Как выглядит отсутствие reasoning: пример до и после
Сравните два вывода модели на один и тот же запрос «Реши уравнение 3x + 7 = 22». Без исправления Laguna S 2.1 отвечает сухо и без размышлений:
Ответ: x = 5После замены шаблона модель показывает полную цепочку:
<think>Дано уравнение 3x + 7 = 22. Нужно найти x. Сначала вычтем 7 из обеих частей: 3x + 7 - 7 = 22 - 7, получаем 3x = 15. Теперь разделим обе части на 3: 3x / 3 = 15 / 3, получаем x = 5. Проверим: 3 * 5 + 7 = 15 + 7 = 22. Всё верно.</think>
Ответ: x = 5Отсутствие reasoning критично для сложных задач - математических расчётов, генерации кода, логических выводов. Без промежуточных шагов модель чаще ошибается, а пользователь теряет возможность проверить ход мыслей.
Корень зла: параметр preserve_thinking и баг шаблона чата
Chat-template в llama.cpp - это Jinja-шаблон, который форматирует промпты перед отправкой в модель. Он определяет, как сообщения пользователя и ассистента преобразуются в токены, и управляет специальными режимами - в частности, включением reasoning через параметр preserve_thinking.
В оригинальном шаблоне Laguna S 2.1 этот параметр обрабатывается с ошибкой. Фрагмент проблемного кода выглядит так:
{% if preserve_thinking %}
{% set thinking = true %}
{% else %}
{% set thinking = false %}
{% endif %}Логическая ошибка в том, что preserve_thinking всегда интерпретируется как false при стандартном вызове - модель никогда не входит в режим рассуждений. Параметр либо не передаётся вообще, либо его значение теряется на этапе рендеринга шаблона.
Почему обновления от Poolside не помогли
За сутки Poolside выпустили два обновления chat-template. Первое исправляло синтаксис Jinja-условий, но не затрагивало логику preserve_thinking. Второе добавило проверку на наличие параметра, но по-прежнему не гарантировало его корректную передачу при запуске через llama.cpp. Сообщество быстро выявило: официальные фиксы не закрывают проблему полностью - параметр остаётся неактивным в большинстве сценариев инференса.
Решение: замена chat-template на шаблон от Qwen 27B
Шаблон Qwen 27B корректно обрабатывает preserve_thinking и совместим с архитектурой Laguna S 2.1. Обе модели используют схожий формат токенизации и структуру специальных токенов, поэтому замена не ломает другие функции - стриминг, системные промпты, остановку генерации.
Сообщество протестировало этот подход на десятках задач: от простых диалогов до сложных математических расчётов. Результат стабилен - модель начинает выводить цепочки рассуждений без побочных эффектов.
Пошаговая инструкция с кодом
Скачайте шаблон Qwen 27B из официального репозитория:
wget https://huggingface.co/Qwen/Qwen2.5-7B-Instruct/resolve/main/tokenizer_config.json -O qwen27b_template.jinjaЗапустите llama.cpp с флагом --chat-template-file:
./llama-cli \
-m laguna-s-2.1.Q4_K_M.gguf \
--chat-template-file qwen27b_template.jinja \
--temp 0.7 \
--top-p 0.9 \
-n 4096 \
-p "Реши уравнение 3x + 7 = 22"Модель начнёт генерацию с блока <think>, внутри которого развернёт цепочку рассуждений, и только затем выдаст финальный ответ.
Проверка: как убедиться, что reasoning работает
Используйте тестовый промпт, который гарантированно требует пошагового обдумывания:
В комнате находятся 5 человек. Каждый пожал руку каждому ровно один раз. Сколько всего рукопожатий произошло? Решай по шагам.Ожидаемый вывод с корректным reasoning:
<think>Это задача на комбинаторику. Количество рукопожатий между n людьми, где каждый жмёт руку каждому ровно один раз, вычисляется по формуле сочетаний: C(n,2) = n(n-1)/2. Подставляем n=5: 5 * 4 / 2 = 10. Проверим перебором: 1-й жмёт 2,3,4,5 (4 шт.), 2-й жмёт 3,4,5 (3 шт.), 3-й жмёт 4,5 (2 шт.), 4-й жмёт 5 (1 шт.). Сумма: 4+3+2+1 = 10.</think>
Ответ: 10 рукопожатий.Если вы видите блок <think> с промежуточными шагами - режим рассуждений активирован корректно.
Почему это работает: совместимость Laguna S 2.1 и Qwen 27B
Laguna S 2.1 и Qwen 27B разделяют общие архитектурные корни - обе модели построены на трансформерной архитектуре с идентичным токенизатором на основе SentencePiece. Формат специальных токенов (<|im_start|>, <|im_end|>) совпадает, что делает шаблоны взаимозаменяемыми.
Шаблон Qwen 27B явно проверяет наличие preserve_thinking и принудительно устанавливает соответствующий режим генерации. Он не зависит от внешних флагов, которые могут теряться при передаче в llama.cpp. Тесты сообщества подтверждают: замена не влияет на качество ответов в обычном режиме, но гарантированно включает reasoning при необходимости.
Альтернативные методы и их ограничения
Ручная правка оригинального шаблона Laguna S 2.1 возможна, но требует глубокого понимания Jinja-синтаксиса и внутренней логики модели. Ошибка в одном условии может сломать форматирование всех промптов. Этот подход нестабилен и не рекомендуется для продакшн-использования.
Использование других моделей для reasoning - например, DeepSeek-R1 или Qwen с уже встроенным режимом - решает задачу, но теряет смысл, если вам нужна именно Laguna S 2.1 с её 120B параметров и специфическими возможностями. Замена шаблона сохраняет модель и добавляет функциональность без компромиссов.
Замена шаблона через --chat-template-file - самый простой и надёжный путь. Одна команда при запуске, никаких правок в исходниках, никаких рисков для стабильности.
Влияние на качество ответов: что меняется с включением reasoning
На математических задачах точность вырастает кратно. Модель перестаёт угадывать ответ и начинает последовательно выводить решение. Пример на задаче «Чему равен интеграл от 0 до 2 функции x²?»:
Без reasoning:
Ответ: 8/3С reasoning:
<think>Интеграл от x² равен x³/3. Подставляем пределы: F(2) - F(0) = (2³/3) - (0³/3) = 8/3 - 0 = 8/3.</think>
Ответ: 8/3Оба ответа верны, но во втором случае пользователь видит ход решения и может проверить его. На задачах с генерацией кода reasoning помогает модели продумать архитектуру перед написанием - результат содержит меньше логических ошибок и более структурирован.
Подробный разбор форсированного мышления в Laguna S 2.1 и влияния chat-template на поведение модели - в статье «Форсированное мышление в Laguna-S-2.1: как простая новая строка заставляет модель рассуждать».
Выводы и дальнейшие шаги
Баг локализован в chat-template - параметр preserve_thinking не передаётся корректно при стандартном запуске. Замена шаблона на Qwen 27B решает проблему полностью: модель начинает выводить цепочки рассуждений без побочных эффектов.
Следите за обновлениями Poolside - разработчики могут выпустить официальный фикс, который устранит необходимость в обходном решении. Пока этого не произошло, способ с --chat-template-file остаётся самым надёжным вариантом для локального инференса Laguna S 2.1 с полноценным reasoning.
Если вы сталкивались с похожими проблемами при запуске других моделей - обратите внимание на материал «Почему Qwen 3.6 27B забывает инструкции: разбор потери контекста в Opencode и llama.cpp», где разбираются системные причины сбоев при локальном инференсе.