3. Bonsai-27B на рекурсивном форке llama.cpp: полный запуск и реальный бенчмарк на RTX 3050

от автора

Всем привет! Это третья часть про мой форк llama.cpp. В прошлых статьях я показывал, как работает рекуррентность и какие цифры она даёт на обычных моделях. Сегодня — особенное железо: Bonsai-27B, гибридная модель на линейной архитектуре Delta-Net. Расскажу, как её запустить на слабой видеокарте, и главное — покажу реальный замеренный бенчмарк D=0 против D=12 на сложной задаче, которую базовая модель не смогла решить вообще.

Все цифры ниже получены на моём железе вживую. Никакой магии и отрисованных «в пользу» диаграмм.


0. Что такое Bonsai-27B и почему он особенный

Bonsai — это модель на гибридной архитектуре: часть слоёв линейная (Delta-Net, рекуррентные по своей природе), часть — обычное полное внимание (full-attention). Поэтому:

  • В неё рекуррентность форка применяется только к слоям полного внимания — линейные слои и так рекуррентны по конструкции.

  • Модель крайне требовательна к памяти, в формате Q1_0 весит ~3.5 ГБ — влезает в 6 ГБ VRAM с запасом.

  • Это отличный полигон для теста: лёгкие слои Delta-Net дают «базу», а рекуррентный цикл по attention-слоям добавляет глубину рассуждений.

1. Что тебе понадобится

  • Linux/macOS/Windows (WSL тоже подойдёт)

  • Видеокарта: моя — RTX 3050 Mobile 6 ГБ. Это минимум для комфортного запуска.

  • Модель: Bonsai-27B в GGUF (например, Bonsai-27B-Q1_0.gguf)

  • Git + компилятор (cmake, make, gcc/clang)

2. Собираем форк

git clone https://github.com/cubetitled-ui/llama.cpp.gitcd llama.cpp

Под NVIDIA GPU (CUDA):

cmake -B build -DGGML_CUDA=ONcmake --build build -j$(nproc) --target llama-cli llama-server llama-bench

Без видеокарты (CPU):

cmake -B build -DGGML_AVX_VNNI=ONcmake --build build -j$(nproc) --target llama-cli

Проверка:

./build/bin/llama-cli --version

3. Быстрый старт: просто запусти

Рекуррентность включена по умолчанию (D=12). Для Bonsai достаточно одной команды:

./build/bin/llama-cli \  -m /path/to/Bonsai-27B-Q1_0.gguf \  -ngl 99 \  -fa on \  -t 12 \  -p "Write a short story about a robot."
  • -ngl 99 — все слои на видеокарту

  • -fa on — flash attention (сильно ускоряет обработку промпта)

  • -t 12 — число потоков CPU (по числу физических ядер)

4. Параметры рекуррентности (переменные окружения)

Рекуррентность управляется переменными окружения перед командой:

RECURRENT_D — глубина (главный)

0 = выключена, 12 = дефолт, 24 = глубокая.

# базовый движок, без рекуррентностиRECURRENT_D=0 ./build/bin/llama-cli -m Bonsai-27B-Q1_0.gguf -ngl 99 -fa on -t 12# рекуррентный движок (дефолт)RECURRENT_D=12 ./build/bin/llama-cli -m Bonsai-27B-Q1_0.gguf -ngl 99 -fa on -t 12

RECURRENT_LAYERS_COUNT — сколько слоёв зацикливаем

auto (дефолт) = один слой на 8 слоёв модели. 3 = классика с тремя якорями.

RECURRENT_LAYERS_COUNT=8 RECURRENT_D=12 ./build/bin/llama-cli -m Bonsai-27B-Q1_0.gguf -ngl 99

RECURRENT_KV — когда писать кеш

last (дефолт) — кеш пишется с последней итерации цикла, отражая «уточнённое» состояние.

RECURRENT_KV=last ./build/bin/llama-cli -m Bonsai-27B-Q1_0.gguf -ngl 99

Полная таблица всех переменных — в HOWITFUCKINGWORKS.md, раздел 4.

5. Реальный бенчмарк: D=0 против D=12 на сложной задаче

Главное, ради чего всё затевалось. Я прогнал вживую на своей RTX 3050 6 ГБ одну и ту же задачу на двух движках, с одинаковым сидом (seed=42) и одинаковым промптом.

Задача

Классический криптарифм — требует перебора, проверки и многошаговой цепочки рассуждений:

SEND + MORE = MONEY. Каждая буква обозначает свою цифру 0-9, разные буквы — разные цифры. S и M не могут быть нулём. Найди числовое значение букв S,E,N,D,M,O,R,Y. Покажи полный ход решения шаг за шагом и обязательно проверь результат в столбик в конце.

Условия

  • Модель: Bonsai-27B-Q1_0

  • GPU: RTX 3050 Mobile 6 ГБ, -ngl 99

  • Температура: 0.3, seed: 42, лимит генерации: 7000 токенов (у обоих)

Результаты

Метрика

D=0 (базовый)

D=12 (рекуррентный)

Токенов сгенерировано

7000 (упёрся в лимит)

6594

Финальный ответ

НЕТ — зациклился

ДА — правильный

Причина остановки

length (не успел)

stop (завершил сам)

Время генерации

~5.5 мин

~5.5 мин

Скорость

21.1 t/s

19.8 t/s

Что произошло

D=0 ушёл в бесконечное самокопание: 7000 токенов модель кружила вокруг одних и тех же уравнений, снова и снова «исправляла» свои же ошибки и так и не выдала ответ — генерация оборвалась по лимиту (finish_reason: length). Это ровно тот паттерн «застревания в рассуждении», который я описывал в первой статье.

D=12 довёл цепочку до конца самостоятельно: нашёл решение S=9, E=5, N=6, D=7, M=1, O=0, R=8, Y=2, оформил его таблицей и проверил в столбик:

    9 5 6 7   (SEND)  + 1 0 8 5   (MORE)  -----------  1 0 6 5 2   (MONEY)

Проверка по столбцам сошлась полностью: 9567 + 1085 = 10652. Модель завершила ответ сама, без обрезки.

Вывод из теста

На сложной многошаговой задаче рекуррентный движок доводит рассуждение до ответа, тогда как базовый застревает в цикле. Цена — ~6% скорости (19.8 против 21.1 t/s). На простых задачах разницы нет вообще — рекуррентность нужна именно там, где модель должна думать долго и связно.

6. Как повторить самому

Никому не верь — включая меня. Две команды, один промпт:

# базовый движокRECURRENT_D=0 ./build/bin/llama-cli \  -m /path/to/Bonsai-27B-Q1_0.gguf \  -ngl 99 -fa on -t 12 -n 7000 \  -p "SEND + MORE = MONEY. Каждая буква - своя цифра 0-9, разные буквы - разные цифры, S и M не равны нулю. Найди значения S,E,N,D,M,O,R,Y. Покажи решение по шагам и проверку в столбик."# рекуррентный движокRECURRENT_D=12 ./build/bin/llama-cli \  -m /path/to/Bonsai-27B-Q1_0.gguf \  -ngl 99 -fa on -t 12 -n 7000 \  -p "SEND + MORE = MONEY. Каждая буква - своя цифра 0-9, разные буквы - разные цифры, S и M не равны нулю. Найди значения S,E,N,D,M,O,R,Y. Покажи решение по шагам и проверку в столбик."

Обрати внимание на finish_reason: stop у рекуррентной версии против обрыва по лимиту у базовой — это видно в логах сервера/CLI.

7. Частые вопросы

Вопрос: рекуррентность = дообучение? Нет. Веса модели не меняются. Меняется только вычислительный граф инференса.

Вопрос: почему скорость упала на 6%? Каждый рекуррентный цикл — это повторный прогон слоя. Больше вычислений = чуть медленнее. Это плата за глубину рассуждений.

Вопрос: на каких ещё моделях это работает? Qwen3.5 (Next/MoE), Qwen2/2-MoE, Qwen3-MoE, Qwen3-Next, Gemma 2, Mistral 3, Delta-Net (Bonsai). Список — в HOWITFUCKINGWORKS.md, раздел 5.

8. Полезные ссылки


Пробовал гонять Bonsai на своём железе? Напиши в комментариях, какая у тебя карта и сколько получилось токенов в секунду — соберу сводную таблицу. До связи!

ссылка на оригинал статьи https://habr.com/ru/articles/1067216/