HyperNanbeige-33B: гибридная квантизация и быстрый инференс 33B-модели на одной RTX 3090

Как уместить рассуждающую модель Nanbeige4.3-33B с контекстом 57 344 токенов и четырьмя параллельными слотами в 24 ГБ VRAM за счёт хирургической сборки GGUF, симметричного KV-кэша и спекулятивного декодирования без драфт-модели.

  • LLM
  • GGUF
  • llama.cpp
  • квантизация
  • CUDA
  • агентная разработка

HyperNanbeige-33B вырос из прикладной инженерной задачи: запустить рассуждающую модель Nanbeige4.3-33B (52 слоя, архитектура Llama с GQA, SwiGLU и словарём на 166 912 токенов) локально на одной видеокарте NVIDIA RTX 3090 (24 ГБ VRAM) для многошаговых агентных циклов в OpenCode.

Стандартные кванты заставляют выбирать между деградацией рассуждений на младших форматах и нехваткой видеопамяти под длинный контекст на старших. Репозиторий HyperNanbeige-33B и опубликованные веса Nanbeige4.3-33B-Hyper-GGUF закрывают этот разрыв без дополнительного оборудования.

Задача и ограничения видеопамяти

В агентной разработке модель за один проход читает десятки тысяч токенов кода, вызывает инструменты поиска и редактирования файлов, анализирует вывод тестов и удерживает длинную историю сессии. Для комфортной работы на одной карте с 24 ГБ памяти одновременно нужны четыре свойства:

  1. Сохранность внимания и выходного классификатора, чтобы на шаге 10-15 агентного цикла не ломались JSON-вызовы инструментов и кириллица.
  2. Запас видеопамяти под контекст свыше 50 000 токенов и параллельные слоты запросов.
  3. Высокая скорость чтения длинных промптов (prefill) и генерации кода без выделения памяти под вторую вспомогательную модель.
  4. Устойчивость истории сообщений при сжатии длинной сессии.

Обычный квант IQ4_XS весит 17.466 GiB и оставляет слишком мало места под большой контекст, а переход на IQ3_XXS или IQ2_XXS бьёт по проекциям внимания и вызывает ошибки в именах аргументов и русских окончаниях.

Хирургическая сборка GGUF со смешанной точностью

Вместо равномерного сжатия всех матриц скрипт build_hyper_gguf.py собирает гибридный файл Nanbeige4.3-33B-Hyper-Q3K-IQ2XXS.gguf объёмом 16.712 GiB (~3.82 bpw, 366 тензоров) напрямую на уровне структуры GGUF без перекодирования через FP16:

  • 350 из 366 тензоров переносятся без потерь из качественного донора IQ4_XS.
  • 100% матриц ключей и значений внимания (attn_k.weight и attn_v.weight во всех 52 слоях) сохраняются в точности Q8_0.
  • 100% матриц запросов и выходной проекции внимания (attn_q.weight, attn_output.weight), а также понижающих проекций ffn_down.weight и критических слоёв blk.0..4, blk.24..27, blk.48..51 остаются в IQ4_XS и Q6_K.
  • Точечное сжатие до IQ2_XXS применяется ровно к 16 тензорам: расширяющим матрицам ffn_gate.weight и ffn_up.weight в восьми внутренних слоях (blk.17..20 и blk.31..34).

Такая раскладка экономит около 0.75 GiB видеопамяти относительно IQ4_XS, сохраняя 8-битные проекции внимания и точный выходной слой.

Три находки при профилировании llama-server на RTX 3090

Работа над моделью показала, что настройка рантайма llama.cpp даёт не меньший выигрыш, чем сама квантизация весов.

1. Симметричный KV-кэш q8_0 / q8_0 быстрее асимметричного q8_0 / q4_0 в два раза на prefill

Попытка сэкономить память через асимметричный кэш -ctk q8_0 -ctv q4_0 приводит к падению скорости обработки длинного промпта до 478 tok/s, так как в скомпилированном ggml-cuda нет специализированных векторных ядер FlashAttention для пары q8_0 + q4_0. Переход на симметричный 8-битный кэш -ctk q8_0 -ctv q8_0 включает быстрые ядра FlashAttention, поднимает скорость чтения промпта до 900-1115 tok/s и позволяет разместить 57 344 токена контекста на 4 параллельных слота в 23 342 MiB из 24 576 MiB доступной VRAM.

2. Спекулятивное декодирование без драфт-модели даёт 45-87 tok/s на коде и JSON

Запуск отдельной драфт-модели отнимает видеопамять у KV-кэша. Вместо неё в продакшен-конфигурации включён скользящий N-gram драфтер и сэмплинг на стороне GPU (--spec-type ngram-simple --spec-ngram-simple-size-n 4 --spec-ngram-simple-size-m 12 -bs --spec-draft-backend-sampling --cache-reuse 256). При нулевом расходе дополнительной памяти скорость генерации вырастает с базовых 31-34 tok/s на чистом рассуждении до 45-87 tok/s при написании кода, SQL-миграций, таблиц и JSON-вызовов, а суммарная пропускная способность на четырёх параллельных потоках достигает 54.4 tok/s.

3. Очистка прошлых блоков <think> вместо жёсткого лимита --reasoning-budget

Жёсткое ограничение --reasoning-budget в llama-server активирует грамматический фильтр на CPU, снижает скорость генерации и может оборвать ответ внутри блока размышлений до выдачи JSON-команды. Вместо этого используется флаг --no-reasoning-preserve: модель свободно додумывает текущий шаг, но сервер не возвращает старые блоки <think>...</think> в контекст следующих шагов агентного цикла. Коэффициент переиспользования префикса кэша в 15-шаговой сессии держится на уровне f_keep = 0.996.

Сводка проверенных показателей на одной RTX 3090

Параметр Проверенное значение
Размер гибридного файла v2-quality 16.712 GiB (~3.82 bpw, 366 тензоров)
Занятая видеопамять с контекстом 57 344 токенов (-np 4) 23 342 / 24 576 MiB VRAM
Скорость чтения промпта (prefill, -ctk q8_0 -ctv q8_0) 900-1115 tok/s
Скорость генерации текста и рассуждений (1 поток) 31.6-34.0 tok/s
Скорость генерации кода, SQL и JSON со спекуляцией ngram-simple 45.3-87.3 tok/s
Суммарная скорость на 4 параллельных потоках 54.4 tok/s

Что опубликовано в открытом доступе

В GitHub-репозитории проекта выложены скрипт сборки гибридных квантов build_hyper_gguf.py с четырьмя профилями (v2-quality, v1-balanced, v3-speed, v4-extreme), пайплайн дистилляции компактного 4-слойного драфтера (train_draft_nanbeige.py и build_draft_gguf.py), конфигурация systemd-сервиса для llama-server и пример настройки opencode.json. Готовые веса модели и imatrix-калибровка доступны на Hugging Face.