- BrainTools - https://www.braintools.ru -
Всем привет! Это третья часть про мой форк llama.cpp. В прошлых статьях я показывал, как работает рекуррентность и какие цифры она даёт на обычных моделях. Сегодня — особенное железо: Bonsai-27B, гибридная модель на линейной архитектуре Delta-Net. Расскажу, как её запустить на слабой видеокарте, и главное — покажу реальный замеренный бенчмарк D=0 против D=12 на сложной задаче, которую базовая модель не смогла решить вообще.
Все цифры ниже получены на моём железе вживую. Никакой магии и отрисованных «в пользу» диаграмм.
Bonsai — это модель на гибридной архитектуре: часть слоёв линейная (Delta-Net, рекуррентные по своей природе), часть — обычное полное внимание [1] (full-attention). Поэтому:
В неё рекуррентность форка применяется только к слоям полного внимания — линейные слои и так рекуррентны по конструкции.
Модель крайне требовательна к памяти [2], в формате Q1_0 весит ~3.5 ГБ — влезает в 6 ГБ VRAM с запасом.
Это отличный полигон для теста: лёгкие слои Delta-Net дают «базу», а рекуррентный цикл по attention-слоям добавляет глубину рассуждений.
Linux/macOS/Windows (WSL тоже подойдёт)
Видеокарта: моя — RTX 3050 Mobile 6 ГБ. Это минимум для комфортного запуска.
Модель: Bonsai-27B в GGUF (например, Bonsai-27B-Q1_0.gguf)
Git + компилятор (cmake, make, gcc/clang)
git clone https://github.com/cubetitled-ui/llama.cpp.git
cd llama.cpp
Под NVIDIA GPU (CUDA):
cmake -B build -DGGML_CUDA=ON
cmake --build build -j$(nproc) --target llama-cli llama-server llama-bench
Без видеокарты (CPU):
cmake -B build -DGGML_AVX_VNNI=ON
cmake --build build -j$(nproc) --target llama-cli
Проверка:
./build/bin/llama-cli --version
Рекуррентность включена по умолчанию (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 (по числу физических ядер)
Рекуррентность управляется переменными окружения перед командой:
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
auto (дефолт) = один слой на 8 слоёв модели. 3 = классика с тремя якорями.
RECURRENT_LAYERS_COUNT=8 RECURRENT_D=12 ./build/bin/llama-cli -m Bonsai-27B-Q1_0.gguf -ngl 99
last (дефолт) — кеш пишется с последней итерации цикла, отражая «уточнённое» состояние.
RECURRENT_KV=last ./build/bin/llama-cli -m Bonsai-27B-Q1_0.gguf -ngl 99
Полная таблица всех переменных — в
HOWITFUCKINGWORKS.md, раздел 4.
Главное, ради чего всё затевалось. Я прогнал вживую на своей 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 |
|
Финальный ответ |
НЕТ — зациклился |
ДА — правильный |
|
Причина остановки |
|
|
|
Время генерации |
~5.5 мин |
~5.5 мин |
|
Скорость |
21.1 t/s |
19.8 t/s |
D=0 ушёл в бесконечное самокопание: 7000 токенов модель кружила вокруг одних и тех же уравнений, снова и снова «исправляла» свои же ошибки [3] и так и не выдала ответ — генерация оборвалась по лимиту (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). На простых задачах разницы нет вообще — рекуррентность нужна именно там, где модель должна думать долго и связно.
Никому не верь — включая меня. Две команды, один промпт:
# базовый движок
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.
Вопрос: рекуррентность = дообучение? Нет. Веса модели не меняются. Меняется только вычислительный граф инференса.
Вопрос: почему скорость упала на 6%? Каждый рекуррентный цикл — это повторный прогон слоя. Больше вычислений = чуть медленнее. Это плата за глубину рассуждений.
Вопрос: на каких ещё моделях это работает? Qwen3.5 (Next/MoE), Qwen2/2-MoE, Qwen3-MoE, Qwen3-Next, Gemma 2, Mistral 3, Delta-Net (Bonsai). Список — в HOWITFUCKINGWORKS.md, раздел 5.
Репозиторий: https://github.com/cubetitled-ui/llama.cpp [4]
Ветка с ускорением: https://github.com/cubetitled-ui/llama.cpp/tree/patch-speedup [5]
Техническая документация: HOWITFUCKINGWORKS.md в репозитории
Пробовал гонять Bonsai на своём железе? Напиши в комментариях, какая у тебя карта и сколько получилось токенов в секунду — соберу сводную таблицу. До связи!
Автор: SimpleTitled
Источник [6]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/34021
URLs in this post:
[1] внимание: http://www.braintools.ru/article/7595
[2] памяти: http://www.braintools.ru/article/4140
[3] ошибки: http://www.braintools.ru/article/4192
[4] https://github.com/cubetitled-ui/llama.cpp: https://github.com/cubetitled-ui/llama.cpp
[5] https://github.com/cubetitled-ui/llama.cpp/tree/patch-speedup: https://github.com/cubetitled-ui/llama.cpp/tree/patch-speedup
[6] Источник: https://habr.com/ru/articles/1067216/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1067216
Нажмите здесь для печати.