EnglishРусский Map

Глубокое погружение в локальные LLM - кванты, MoE-оффлоад, REAP, ik_llama, спекулятивное декодирование

title
Глубокое погружение в локальные LLM - кванты, MoE-оффлоад, REAP, ik_llama, спекулятивное декодирование
type
summary
summary
Большой разбор Хабра от Вячеслава: BF16, K/I-кванты, динамическое квантование, -fit/-cmoe/-ncmoe, прунинг REAP, ik_llama, MTP/EAGLE3, Linux против Windows
tags
llm, local-models, llama-cpp, quantization, moe
created
2026-05-13
updated
2026-05-13
lang
ru
source_updated
2026-05-13
translated
2026-09-01
translator
lllm/antigravity/gemini-3.7-flash-medium

Вторая статья Вячеслава на Хабре (1025132), опубликованная до статьи с тестами трёх моделей (1033808), но закладывающая концептуальную базу для неё. Если статья с тестами была бенчмарком в форме повествования, то эта - практическое руководство для оператора: почему BF16 победил FP16, чем отличаются K-кванты и I-кванты, что делает режим -fit (то, что раньше настраивалось вручную через --n-cpu-moe), почему квант Q3 может работать медленнее Q4 на одной и той же модели, что даёт REAP и в каких случаях ik_llama может или не может заменить llama.cpp.

Основные темы

Именование MoE и компромисс качества между Dense и MoE

Стандартное имя MoE выглядит как Qwen3.6-35B-A3B: мажорная.минорная версия модели, общее число параметров, число активных параметров. Больше активных параметров - выше качество, но ниже скорость (токенов/с). Dense-модели активируют всё; при одинаковом общем объёме параметров они "умнее", но работают значительно медленнее. См. mixture-of-experts.

Почему BF16, а не FP16

Нейросетевой аргумент в пользу сохранения 8-битной экспоненты из FP32 и урезания мантиссы: для обучения важен динамический диапазон, а не точность. Градиентный спуск заходит в порядки величин от $10^{-7}$ до $10^{-8}$; функции активации не могут возвращать бесконечность при взрывном росте значений; обратное распространение ошибки должно вносить мелкие правки. FP16 сужает экспоненту до 5 бит, и на практике обучение либо зависает (веса перестают меняться), либо разваливается в NaN. Решением стало смешанное обучение (Mixed Precision: FP32 + FP16), требующее больше памяти, чем чистый FP32. Настоящей победой стал формат BF16: он сохраняет 8-битную экспоненту FP32 и урезает мантиссу с 23 до 7 бит. Диапазон сохранён, размер уменьшен вдвое, обучение идёт штатно. Такова предыстория всех современных моделей с открытыми весами. См. bf16-vs-fp16.

Чем K-кванты отличаются от наивного Int4

Современная история квантования в llama.cpp - это вклад ikawrakow. Поверх базового алгоритма добавлены три вещи:

  • Блочное квантование. Модель делится на блоки; у каждого блока свой масштабный коэффициент (scale). Для неоднородных моделей вроде LLM это плюс, так как выбросы в весах не портят весь тензор.
  • Калибровка по imatrix. Датасет типичного использования, который активирует разные блоки. Блоки с сильным откликом квантуются менее агрессивно, остальные - сильнее.
  • Раздельные уровни квантования для attn и ffn. Механизм внимания (attn) определяет "интеллект" модели; если сохранить для attn более высокую точность, а ffn ужать сильнее, общее качество останется высоким.

K-кванты (Q4_K_M и т. д.) - статические и блочные (K-blocked). I-кванты (IQ4_XS) используют imatrix. Буквенные суффиксы (S, M, L, XL) показывают, насколько выше точность attn по сравнению с телом ffn.

UD-Q4_K_XL превосходит Q4_K_M; Q4_K_M ≈ UD-Q3_K_XL

Замеры KLD (дивергенция Кульбака - Лейблера относительно базового BF16) на Qwen3.6-35B-A3B:

  • Классический Q4_K_M ≈ UD-Q3_K_XL (динамический квант Q3 на 4.4 ГБ меньше при примерно таком же качестве)
  • UD-Q4_K_XL обходит Q4_K_M, занимая на 1.2 ГБ больше на диске
  • UD-Q2_K_XL обходит IQ2_M при том же объёме в байтах

Это уточняет ранее зафиксированный вывод из llm-quantization - старое значение (UD-Q4_K_XL хуже Q4_K_M на Qwen MoE примерно в 5 раз) было получено при замере перплексии на WikiText-2, а не KLD относительно BF16. Эти две метрики могут давать противоположные результаты в одном и том же сравнении. Замер KLD от Вячеслава более свежий и учитывает специфику архитектуры.

Четыре создателя динамических квантов

  • Unsloth (UD-...-XL): сохраняет attn ближе к оригиналу, динамически квантует ffn. Выпустили схему Unsloth Dynamic 2.0.
  • Ubergarm (семейство IQ4_KS и IQK): собирает кванты специально под ik_llama, динамическое квантование.
  • Bartowski: стандартные имена вроде Q4_K_M, но со своей imatrix; калибровка ориентирована на английский язык и слабее работает на русском.
  • mradermacher (префикс i1): imatrix настроена под многоязычность.

Все четверо используют imatrix даже для "статических" K-квантов. Стандартный рецепт (настройки по умолчанию в ggml, ollama, LM Studio) остался позади.

См. страницу сущности unsloth.

-fit стал новым режимом по умолчанию

Главное изменение в эксплуатации: в llama.cpp теперь есть режим -fit (включён по умолчанию), который автоматически определяет тип модели (MoE или Dense) и выбирает между -ncmoe и -ngl. Память рассчитывается автоматически; можно указать --fit-target 1024, чтобы оставить свободным 1 ГБ, либо довериться значению по умолчанию. Тот же флаг в ветке на Reddit используется как -fitt 1536. Полную таблицу режимов см. в moe-cpu-offload.

Три режима: -ngl (выгрузка слоёв на GPU, лучше всего для Dense), -cmoe (полный оффлоад всех экспертов MoE на CPU, минимальный расход VRAM), -ncmoe N (частичный оффлоад N экспертных слоёв на CPU).

Почему Ollama в 3 раза медленнее llama.cpp

Под капотом Ollama использует движок GGML из llama.cpp, поэтому она могла бы включать -ncmoe для MoE-моделей. Но она этого не делает. Она использует -ngl для всего подряд: и для Dense, где ngl действительно уместен, и для MoE, где ngl частично забивает все 16 ГБ, оставляя GPU с эффективной утилизацией около 30%. Замеры на RTX 4060 16GB с Qwen3.6-35B-A3B Q4_K_M:

Движок Режим Скорость
ollama ngl 16 т/с
llama.cpp ncmoe (авто через -fit) 45 т/с

При контексте 32K разрыв увеличивается до 11 против 36 т/с (в 3.2 раза). LM Studio проигрывает похожим образом - и из-за выбора движка, и потому что загружает веса Vision, даже когда они не запрашиваются.

Почему UD-Q3_K_XL может быть медленнее UD-Q4_K_XL

Парадоксальное наблюдение: меньший по размеру квант может работать медленнее на гибридной связке CPU/GPU. Причина кроется в составе кванта. UD-Q3_K_XL поставляется с i-quant блоками; UD-Q4_K_XL целиком состоит из статических K-квантов. Для деквантования I-квантов при инференсе требуется примерно вдвое больше вычислений на CPU. Если меньший квант позволяет выгрузить больше слоёв на GPU, но узким местом остаются слои экспертов на CPU, более крупный квант выигрывает.

Воспроизведено на i7-14700 с -t 2 -cmoe: UD-Q4_K_XL выдал 25 т/с против 18 т/с у UD-Q2_K_XL на одной и той же модели Qwen3.6.

Это общее правило: если вы упираетесь в CPU на экспертных слоях, тип кванта важнее его размера. K-кванты выигрывают у I-квантов, когда накладные расходы на деквантование становятся узким местом.

UD-Q2_K_XL способен на большее, чем принято считать

Расхожее мнение о том, что кванты Q2 и Q3 "непригодны для использования", основано на статических квантах. Динамические Q2 и SOTA-кванты вроде IQ2_KS вполне работоспособны. Qwen3.6-35B-A3B в UD-Q2_K_XL (12.3 ГБ) целиком влезает в 4060 16 GB со скоростью 68 т/с и с первой попытки генерирует процедурный клон Minecraft с помощью qwen-code в роли агента: разрушение блоков, несколько биомов, течение воды, процедурная графика - примерно за 3 часа агентной правки кода.

REAP - прунинг экспертов

REAP (Router-weighted Expert Activation Pruning) отсекает наименее активных экспертов из MoE на основе калибровочного датасета под целевой домен. Типичные объёмы усечения: 20%, 50%, 75%. Такие варианты именуются Qwen3.6-28B-REAP20-A3B-GGUF (20% экспертов удалено, 3B активных параметров осталось). Усечение на 20% в Qwen 3.6 сохраняет большую часть возможностей для агентного программирования: Вячеслав успешно расширил клон Minecraft (добавил пещеры, алмазы, генерацию дома), используя REAP-версию. При этом качество русского языка заметно падает: калибровочный датасет REAP сфокусирован на программировании на английском, поэтому нецелевые навыки деградируют первыми. Модель забывает, кто такой Чапаев.

REAP также позволяет уместить крупные MoE-модели в доступный объём RAM: превращение GLM-5.1 744B-A40B -> 444B-A14B экономит 40% диска и активных вычислений. См. reap-expert-pruning.

Обзор спекулятивного декодирования

Четыре механизма предсказания нескольких токенов за один прямой проход (forward pass); статья служит оглавлением для speculative-decoding:

  • Draft-модель. Использование небольшой родственной модели для предсказания следующих токенов; большая модель проверяет их батчем. Пример из практики: Gemma-4 31B (62 т/с) + draft-модель Gemma-4 E2B -> 97 т/с на задачах написания кода (принятие черновика ~55%). Обязателен параметр --parallel 1 (в автоматическом режиме резервируется в 4 раза больше памяти).
  • MTP (Multi-Token Prediction). Дополнительные блоки, обучаемые вместе с моделью и предсказывающие на несколько токенов вперёд. Впервые появились в DeepSeek V3/R1. PR #22673 в llama.cpp добавляет их поддержку для Qwen 3.6 и Gemma 4.
  • EAGLE3. Работает без draft-модели и MTP-головы; использует легковесную авторегрессионную голову, принимающую скрытые состояния (hidden states). PR #18039 в llama.cpp.
  • ngram-mod. Чисто математический черновик без нейросети. Лучше всего подходит для сценариев с активным повторным использованием текста - например, при редактировании одного участка кода, когда остальная часть не меняется. --spec-type ngram-mod.

Ускорение обработки промпта

Когда модель выгружена на CPU через cmoe, обработка промпта (Prompt Processing, PP) идёт медленно. Решение: увеличить размер батча. Параметры -ub 4096 -b 4096 поднимают скорость PP с 93 до 475 токенов/с на Qwen3.6 с -ncmoe 24. Скорость генерации (TG) при этом не меняется. Это важно знать для агентных задач, где модель постоянно перечитывает исходные файлы.

ik_llama не является прямой заменой

ikawrakow отделился от ggerganov, сделал форк llama.cpp под названием ik_llama.cpp и выпускает SOTA-кванты IQK вместе с агрессивными оптимизациями PP. Сравнение компромиссов:

llama.cpp ik_llama
Кванты MXFP4 полная частичная (в 2-3 раза медленнее)
Vulkan / видеокарты AMD полная запускается, но очень медленно
AVX-512 / процессоры Intel хорошо лучше
PP на длинном контексте падает быстрее держится дольше
Квантование KV-кэша в Q6 нет да
Новые кванты IQK нет да

IQ4_KS на Qwen3.5 показал замер KLD примерно в 3 раза лучше, чем Q4_K_M того же размера, и не уступает UD-Q4_K_XL по качеству при экономии около 1 ГБ. На больших моделях выигрыш по объёму суммируется: экономия 20-30 ГБ критична, если вы пытаетесь уместить GLM-5.1 или DeepSeek V3.2 в 192 ГБ RAM.

Компромисс в поддержке: над ik_llama работает один человек. Оптимизации не переносятся ни в основную llama.cpp, ни обратно. См. ik-llama-cpp.

Linux против Windows и выгрузка на iGPU

Для серии RTX 50 правильным тулчейном является CUDA 13.1: Windows по умолчанию ставит CUDA 12, и разница ощутима. CachyOS (Linux) освобождает около 2-3 ГБ по сравнению с Windows как за счёт более лёгкого окружения рабочего стола, так и потому, что модель общей памяти Windows при превышении лимита VRAM незаметно скидывает данные в RAM. Это приводит к падению скорости на порядок, создавая впечатление "сегодня ничего не работает".

Оффлоад на iGPU: если в процессоре есть встроенная графика, переключите мониторы на неё, а дискретную видеокарту выделите чисто под инференс. Это освободит те самые 2-3 ГБ, которые съедают Windows, браузер и мессенджеры. В Windows 10 настройка находится по пути "Параметры -> Дисплей -> Настройки графики -> Добавить приложение -> Энергосбережение (GPU)"; в Windows 11 есть выпадающий список для выбора GPU по умолчанию для каждого приложения.

Список моделей 2026 года

Рекомендации Вячеслава на начало 2026 года:

Для дома (одна потребительская видеокарта на 16 ГБ):

  • Gemma 4 (E2B/E4B/26B-A4B/31B)
  • Qwen 3.5 (восемь вариантов от Dense на 0.8B до MoE на 122B-A10B)
  • Qwen 3.6 (35B-A3B и теперь 27B Dense)

Для продвинутых рабочих станций (home+):

  • MiniMax-M2.7
  • Step-3.5-Flash
  • GLM-5.1
  • Mistral-Small-4-119B-2603
  • Kimi-K2.6

Только вышли, пока без GGUF:

  • Tencent Hy3-preview
  • DeepSeek-V4-Pro / V4-Flash

Qwen3.6 35B-A3B и 27B показывают разные результаты в бенчмарках: MoE-версия заметно лучше в программировании, но уступает в общих знаниях по фреймворку IKP (см. incompressible-knowledge-probes). Gemma 4 26B-A4B, по оценке Вячеслава, "в программировании сильно хуже" версии Dense 31B, что подтверждает компромиссную природу архитектуры даже внутри одного семейства моделей.

Связи

  • local-llm-16gb-vram-tests - сопутствующая статья с тестами от того же автора. Данная статья служит теоретической базой, та - экспериментом.
  • mixture-of-experts - дополнено результатами IKP по соотношению общего и активного числа параметров
  • llm-quantization - обновлено историей BF16, вычислительной стоимостью K- и I-квантов и списком четырёх создателей динамических квантов
  • moe-cpu-offload - обновлено разбором режимов -fit / -cmoe / -ncmoe
  • speculative-decoding - семейство методов, описанных в разделе "Обзор спекулятивного декодирования"
  • reap-expert-pruning - отдельный концепт REAP
  • ik-llama-cpp - форк
  • llama-cpp - основной проект, обновлена ссылка на режим -fit
  • unsloth - самый известный создатель динамических квантов
  • bf16-vs-fp16 - выбор между экспонентой и мантиссой
  • reddit-qwen3-6-mtp-12gb - практическая ветка, где используются операционные знания из этой статьи