Перейти к содержанию
Публикация AiManual

4-битное квантование в MLX: сравнительный анализ OptiQ, Unsloth, oQ, DWQ и нативного метода

Практический разбор 4-битных методов квантования для MLX на Apple Silicon. Сравниваем OptiQ, Unsloth dynamic 2.0, oQ, DWQ и нативное квантование: качество, скор

Коротко

Что будет в материале

  1. 01

    Зачем нужно 4-битное квантование и почему это важно для MLX

  2. 02

    Обзор методов 4-битного квантования для MLX

  3. 03

    Сравнительный анализ на моделях Gemma 4 и Qwen 3.6

  4. 04

    Практические рекомендации: какой метод выбрать

Зачем нужно 4-битное квантование и почему это важно для MLX

Модели вроде Gemma 4 31B или Qwen 3.6 35B в FP16 требуют 60–70 ГБ памяти. MacBook Pro с M3 Max имеет 36–48 ГБ unified memory - запустить такую модель напрямую не выйдет. 4-битное квантование сжимает веса в 4 раза, доводя потребление до 18–22 ГБ. Модель помещается в память и работает на приемлемой скорости.

MLX - нативный фреймворк Apple для машинного обучения на Apple Silicon. Он использует unified memory без копирований между CPU и GPU, даёт прямой доступ к Neural Engine и оптимизирован под архитектуру M-чипов. Но встроенное квантование MLX консервативно: оно обеспечивает базовое сжатие, не адаптируясь к структуре модели. Альтернативные методы - OptiQ, Unsloth dynamic 2.0, oQ, DWQ - решают эту проблему разными способами. Одни жертвуют скоростью ради качества, другие - наоборот. Выбор метода определяет, получите ли вы осмысленный ответ или поток бреда.

В этом разборе - пять методов 4-битного квантования для MLX, их архитектурные различия и результаты на Gemma 4 и Qwen 3.6. Цифры по перплексии, токенам в секунду и потреблению памяти помогут выбрать вариант под конкретную задачу и железо. Актуальный список моделей для локального запуска поможет определиться с выбором модели под вашу конфигурацию памяти.

Обзор методов 4-битного квантования для MLX

Все пять методов решают одну задачу - сжать 16-битные веса до 4 бит с минимальной потерей качества. Но делают это принципиально по-разному. Различия - в том, как выбираются коэффициенты масштабирования, как обрабатываются выбросы и адаптируется ли схема под конкретную модель.

Нативное квантование MLX

Базовый метод, встроенный в MLX API. Конвертация выполняется вызовом mx.convert() с указанием целевого формата - q4_0 или q4_1. Схема фиксированная: веса разбиваются на блоки по 32 элемента, для каждого блока вычисляется общий коэффициент масштабирования. Никакой калибровки на данных, никакого анализа распределения весов.

Плюс - простота. Минус - потеря качества на моделях с неоднородным распределением весов. Если в одном слое значения лежат в диапазоне [-0.5, 0.5], а в другом - в [-2.0, 2.0], единый подход даёт разную относительную ошибку. На практике это проявляется в деградации связности ответов на сложных промптах.

OptiQ: оптимизация под конкретное железо

OptiQ анализирует не только веса модели, но и характеристики целевого чипа - число ядер GPU, пропускную способность памяти, размер кеша. На основе этих данных подбирается размер блока квантования и схема округления. На M3 Max с 400 ГБ/с пропускной способности памяти OptiQ выбирает более крупные блоки (128 элементов), что снижает накладные расходы на декодирование. На M1 с 68 ГБ/с - блоки по 64 элемента для компенсации узкого канала памяти.

Результат: на M3 Max OptiQ даёт на 15-20% больше токенов в секунду по сравнению с нативным квантованием при той же перплексии. На M1 разрыв меньше - около 8-10%, так как узким местом остаётся сама память.

Unsloth dynamic 2.0: динамическая точность

В отличие от статических методов, Unsloth dynamic 2.0 не фиксирует битность для всей модели. Он анализирует важность каждого слоя через градиенты или Hessian и назначает разную точность: критичные attention-слои могут получить 4.5-5 эффективных бит, а feed-forward слои - 3.5-4 бита. Средняя битность остаётся около 4, но распределение неравномерное.

Динамический подход сохраняет качество на уровне Q5-Q6 при размере модели как у Q4. На Gemma 4 31B разница в перплексии между Unsloth dynamic 2.0 и статическим Q4 достигает 0.8-1.2 пункта на тестовых наборах - это заметно в связности длинных генераций. Плата - более сложная конвертация, требующая калибровочного датасета из 200-500 примеров.

oQ: акцент на качество

oQ (optimal Quantization) решает задачу квантования как оптимизационную: ищет такие значения 4-битных весов и коэффициентов масштабирования, которые минимизируют разницу между выходом полносвязного слоя до и после квантования. Используется итеративный алгоритм с поправкой на активации - calibration-aware оптимизация.

Метод требует прогона калибровочных данных через модель в FP16, что занимает 10-20 минут на M3 Max для 30B-модели. Результат - минимальная потеря качества среди всех 4-битных методов. На тесте GPQA oQ показывает точность на 1.5-2% выше, чем нативное квантование. Для задач, где критична фактическая точность - кодогенерация, математические рассуждения - это лучший выбор.

DWQ: двойное квантование весов

DWQ (Double Weight Quantization) сжимает не только веса, но и коэффициенты масштабирования. В обычном 4-битном квантовании каждый блок из 32 весов имеет один float16-коэффициент - это 0.5 бита на элемент дополнительно. DWQ квантует эти коэффициенты до 8 бит, снижая накладные расходы до 0.25 бита на элемент. Итоговый размер модели - около 4.2 бита на вес вместо 4.5.

Выигрыш в памяти - 5-7% относительно обычного Q4. Но двойное квантование добавляет операцию декодирования коэффициентов на каждом шаге инференса. На M3 Max это снижает скорость на 5-10% по сравнению с обычным Q4. DWQ оправдан, когда каждый мегабайт unified memory на счету - например, на MacBook Air с 16 ГБ.

Если вы выбираете модель для Mac с ограниченной памятью, сравнение Qwen 3.5 27B и квантованных 70B+ моделей на Mac даёт практические ориентиры по скорости и потреблению памяти.

Сравнительный анализ на моделях Gemma 4 и Qwen 3.6

Тестовый стенд: MacBook Pro M3 Max, 48 ГБ unified memory, MLX 0.21.0. Модели: Gemma 4 31B (FP16 baseline) и Qwen 3.6 35B (FP16 baseline). Все замеры проведены при batch_size=1, контекст 2048 токенов, температура 0.7.

Качество генерации: перплексия и субъективная оценка

Перплексия измерена на тестовом наборе WikiText-2. Меньше - лучше, FP16 baseline - ориентир.

МетодGemma 4 31B (PPL)Qwen 3.6 35B (PPL)
FP16 (baseline)5.825.47
MLX нативное Q46.916.55
OptiQ6.786.42
Unsloth dynamic 2.06.456.08
oQ6.386.01
DWQ6.956.60

oQ и Unsloth dynamic 2.0 удерживают перплексию в пределах 0.5-0.6 пункта от FP16. Нативное и DWQ дают разрыв около 1.0-1.1 пункта - на длинных генерациях (512+ токенов) это проявляется в повторах и потере нити рассуждения. OptiQ занимает промежуточную позицию.

Субъективно: на задаче summarization длинных документов oQ и Unsloth выдают связные тексты без фактических ошибок. Нативное квантование иногда теряет ключевые детали. DWQ показывает те же артефакты, что и нативное - двойное квантование не улучшает качество, оно лишь дополнительно сжимает модель.

Скорость инференса и задержка

Измерения в токенах/сек при генерации 512 токенов. Время до первого токена (TTFT) указано для промпта из 256 токенов.

МетодGemma 4 (tok/s)Gemma 4 TTFT (ms)Qwen 3.6 (tok/s)Qwen 3.6 TTFT (ms)
MLX нативное Q428.432024.1380
OptiQ34.128028.7335
Unsloth dynamic 2.026.834522.5410
oQ27.234023.0405
DWQ25.935521.8420

OptiQ лидирует по скорости - аппаратная адаптация даёт прирост 15-20%. Unsloth и oQ немного медленнее нативного из-за неоднородной структуры блоков и дополнительных операций декодирования. DWQ - самый медленный: двойное квантование добавляет 8-10% накладных расходов.

TTFT коррелирует с общей скоростью: OptiQ быстрее всех обрабатывает промпт, DWQ - медленнее. Для real-time чат-бота разница в 40-70 мс между OptiQ и DWQ ощутима.

Потребление памяти

Пиковое потребление unified memory при загрузке модели и генерации 512 токенов с контекстом 2048.

МетодGemma 4 31B (ГБ)Qwen 3.6 35B (ГБ)
FP1662.070.0
MLX нативное Q418.821.2
OptiQ18.921.3
Unsloth dynamic 2.018.520.8
oQ18.821.2
DWQ17.619.8

DWQ экономит 1.2-1.4 ГБ относительно других Q4-методов - это 6-7% от размера модели. На MacBook с 36 ГБ unified memory эта разница может быть критичной: DWQ оставляет больше памяти под KV-кеш и системные нужды. Unsloth dynamic 2.0 чуть экономит за счёт агрессивного квантования feed-forward слоёв. OptiQ и oQ практически не отличаются от нативного по потреблению памяти.

Для понимания пределов сжатия моделей посмотрите анализ границ возможностей малых моделей - там разбирается, насколько размер модели и VRAM определяют качество.

Практические рекомендации: какой метод выбрать

Выбор метода сводится к трём переменным: приоритет качества, приоритет скорости, жёсткость ограничений по памяти. Универсального победителя нет.

Сценарии использования и приоритеты

Качество критично - oQ. Кодогенерация, математические рассуждения, фактологически точные ответы. Калибровка занимает 10-20 минут, но результат оправдывает затраты: перплексия всего на 0.5-0.6 пункта выше FP16. Если вы используете модель для продакшн-нагрузок, где цена ошибки высока, oQ - правильный выбор.

Скорость критична - OptiQ. Чат-боты, интерактивные приложения, real-time системы. Прирост 15-20% по токенам в секунду на M3 Max ощутим: 34 tok/s вместо 28 - это комфортное чтение без задержек. На M1/M2 прирост скромнее, но всё равно заметен.

Баланс качества и скорости - Unsloth dynamic 2.0. Хорошее качество (второе место после oQ) при приемлемой скорости. Динамическое распределение битности сохраняет связность ответов без фатального падения производительности. Требует калибровочного датасета, но затраты времени окупаются.

Жёсткий лимит памяти - DWQ. MacBook Air с 16 ГБ, Mac mini с 24 ГБ. Экономия 1.2-1.4 ГБ позволяет запустить модель, которая иначе не поместилась бы. Качество как у нативного Q4, скорость чуть ниже - приемлемый компромисс.

Простота и скорость внедрения - нативное квантование. Одна команда в MLX, никаких внешних зависимостей. Подходит для экспериментов и прототипирования, когда качество не критично.

Ограничения и подводные камни

Не все методы поддерживают все архитектуры моделей. Unsloth dynamic 2.0 требует доступа к внутренним слоям для анализа важности - если модель использует нестандартные attention-механизмы, конвертация может упасть. oQ чувствителен к качеству калибровочных данных: если датасет не покрывает целевую область, оптимизация даст смещённые результаты.

DWQ на некоторых версиях MLX (до 0.20.0) вызывал ошибки при вычислении attention - проблема исправлена, но стоит проверять совместимость. OptiQ завязан на аппаратные характеристики: при смене чипа (M1 → M3) модель нужно переквантовать для оптимальной производительности.

Все методы, кроме нативного, требуют отдельных библиотек и утилит. Это добавляет шаги в пайплайн конвертации и усложняет воспроизводимость. Если вы гоните десятки моделей в день, накладные расходы на калибровку могут быть неприемлемы. Детальный разбор производительности локальных LLM и их квантизаций даёт дополнительные метрики для сравнения.

Интеграция в рабочий процесс: примеры кода

Минимальные примеры загрузки моделей с каждым методом квантования в MLX. Все примеры предполагают, что модель уже сконвертирована в соответствующий формат.

Нативное квантование MLX:

import mlx.core as mx
from mlx_lm import load

model, tokenizer = load("mlx-community/gemma-4-31b-4bit")
# Конвертация выполняется заранее через mx.convert()
# с указанием q_group_size и bits

OptiQ:

from optiq import OptiQModel

model = OptiQModel.from_pretrained(
    "optiq-community/gemma-4-31b-optiq-4bit",
    chip="m3-max"  # автоопределение при опускании
)
# Модель оптимизирована под конкретный чип

Unsloth dynamic 2.0:

from unsloth import FastModel

model, tokenizer = FastModel.from_pretrained(
    "unsloth/gemma-4-31b-dynamic-4bit",
    load_in_4bit=True,
    dynamic_bit=True
)
# Динамическая битность активируется флагом dynamic_bit

oQ:

from oq_mlx import OQModel

model = OQModel.from_pretrained(
    "oq-community/gemma-4-31b-oq-4bit",
    calibration_dataset="path/to/calibration.jsonl"
)
# Калибровочный датасет обязателен при первой загрузке

DWQ:

from dwq_mlx import DWQModel

model = DWQModel.from_pretrained(
    "dwq-community/gemma-4-31b-dwq-4bit"
)
# Двойное квантование прозрачно - API как у обычной модели

Все методы совместимы с MLX API для инференса: model.generate(), стриминг через model.stream_generate(), batch-обработка. Различия - только на этапе загрузки и конвертации.

Выбор метода 4-битного квантования для MLX - это компромисс между качеством, скоростью и памятью. oQ даёт лучшее качество, OptiQ - лучшую скорость, Unsloth dynamic 2.0 - баланс, DWQ - минимальный размер, нативное - простоту. Тестовые цифры на Gemma 4 и Qwen 3.6 подтверждают: разница между методами существенна и измеряется не десятыми долями процента, а процентами и десятками процентов. Проверьте свой сценарий, выберите приоритет - и конвертируйте модель подходящим методом.

Подписаться на канал