GGUF vs MLX раунд 2: 5 рантаймов, 2 модели и почему Ollama медленнее на 37%
Второй раунд сравнения GGUF и MLX на Apple Silicon. Пять рантаймов, две модели, bf16-фикс — и неожиданный вывод: узкое место не движок, а обвязка вокруг него.
Две недели назад в r/LocalLLaMA вышел пост, где MLX оказался медленнее GGUF. Сообщество разнесло методологию: неудачная модель, сломанный prompt caching, bf16 на чипе без нативной поддержки bf16. Автор принял критику и провёл второй раунд — с учётом всех замечаний. Результаты переворачивают первоначальные выводы и показывают, где на самом деле теряется производительность.
Условия теста
Железо: M1 Max 64 ГБ.
Две модели:
- Gemma 12B QAT — компактная, хорошо оптимизированная
- Qwen3 30B-A3B — MoE-модель, 30 млрд параметров с активацией 3 млрд
Пять рантаймов: LM Studio (GGUF через llama.cpp), llama.cpp скомпилированный из исходников с Metal, oMLX (MLX-рантайм с продвинутым кэшированием), LM Studio (MLX-бэкенд), Ollama (GGUF через llama.cpp).
Четыре сценария: креативное письмо, классификация документов, ops-агент на 8 поворотов, стресс-тест prefill на 8K контексте.
bf16→fp16: фикс, который меняет картину
M1 и M2 не имеют нативной поддержки bf16. MLX-модели в bf16 на этих чипах работают с пенальти, особенно на prefill. Конвертация через mlx_lm.convert занимает меньше минуты, потери качества нет, а prefill ускоряется на 40–70%. На M3 и новее это не нужно — там bf16 нативный.
После этого фикса разница между GGUF и MLX на Qwen3 30B-A3B сократилась до однозначных цифр.
Цифры: Qwen3 30B-A3B (ops-агент, eff tok/s)
Сравнение по эффективному tok/s на сценарии ops-агент:
- Креативное письмо: MLX bf16 — 53.7, MLX fp16 — 52.7, GGUF Q4_K_M — 56.1
- Классификация: MLX bf16 — 26.4, MLX fp16 — 32.8, GGUF — 33.7
- Ops-агент (8 поворотов): MLX bf16 — 35.7, MLX fp16 — 38.4, GGUF — 41.7
- Prefill stress (8K): MLX bf16 — 6.0, MLX fp16 — 8.6, GGUF — 7.6
Генерация: 58 tok/s GGUF против 55–56 MLX. Тот самый разрыв «57 vs 29» из первого теста? Это была модель, не движок.
Рантаймы на ops-агенте
- LM Studio (llama.cpp GGUF): 41.7 eff tok/s
- llama.cpp (compiled): 41.4 eff tok/s
- oMLX: 38.0 eff tok/s
- Ollama (llama.cpp GGUF): 26.0 eff tok/s (−37%)
Три ключевых вывода
1. Рантайм важнее движка
LM Studio и скомпилированный llama.cpp — 41.7 vs 41.4 tok/s. LM Studio не добавляет overhead. Но Ollama, использующий тот же llama.cpp, отстаёт на 37%.
Это не проблема GGUF. Это проблема Go-обвязки Ollama. Тот же движок, тот же формат весов, но промежуточный слой съедает больше трети производительности. Удобство имеет цену.
2. oMLX решает проблему кэширования, а не скорости MLX
oMLX показал себя в 2.2 раза быстрее LM Studio MLX на мультитурновых сценариях с Qwen3. Но на Gemma 12B, где кэширование LM Studio работает корректно, разница исчезла.
oMLX — это фикс для конкретного бага (mlx-lm#903), а не универсальное ускорение MLX. Если ваша модель не страдает от проблем с prompt caching, разница минимальна.
3. «4-бит» ≠ «4-бит»
GGUF Q4_K_M и MLX 4-bit — разные вещи. K-quants в GGUF распределяют биты адаптивно: чувствительные слои получают больше точности. MLX квантует равномерно.
llama.cpp измерил 4.7-кратную разницу в perplexity между равномерным Q4_0 и адаптивным Q4_K_M на 7B модели. Проект JANG-Q работает над адаптивной квантизацией для MLX, но пока это преимущество GGUF.
Где всё это оставляет каждый рантайм
LM Studio + GGUF — для повседневной работы. Лучшие кванты, без воркэраундов, стабильная скорость.
oMLX — для мультитурновых агентных сценариев с MLX-моделями, особенно мультимодальными вроде Qwen 3.5. Кэширование помогает на длинных сессиях.
Ollama — удобен для быстрого старта. Если производительность критична — 37% overhead серьёзная плата за `ollama run`.
Итог
Когда видите жалобы «MLX медленный» или «GGUF быстрее» — первый вопрос другой. Не «какой движок?», а «какой рантайм и какая модель?».
Первый тест показал разницу 2× между движками. Второй показал: разница была артефактом конкретной модели и конфигурации. После фиксов реальный разрыв — однозначные проценты. Зато разница между рантаймами на одном движке — 37%. Узкое место не там, где его ищут.