Аннотация
Три движка локального инференса принято сравнивать по списку функций: квантование, батчинг, спекулятивный декод, поддержка GPU1. К октябрю 2026 года эти списки почти совпали — разница ушла в физику. Декод одного токена требует прочитать из памяти все активные веса модели, поэтому потолок скорости на одном пользователе задаёт не число ядер и не «поддержка batching», а эффективная полоса памяти, делённая на размер модели в байтах. Всё остальное — инженерия вокруг этого отношения: сколько запросов можно поставить в один проход по весам, сколько KV-кэша останется на контекст и что делать, когда модель в память не влезает.
Обзор опирается на первичные источники: README и документацию флагов llama.cpp, документацию vLLM V1 и релиз-ноты vLLM 0.32.0, релизы и блог Ollama, официальные спецификации NVIDIA и Apple, конфигурации и файлы моделей на Hugging Face, а также пять научных работ (PagedAttention, Orca, спекулятивный декод, MoE-offloading, LIMINAL). Дополнительно проведён собственный замер: собрана сборка llama.cpp, измерена скорость декода на CPU и работа сервера при 1 и 4 одновременных запросах. Данные на 2026-10-23.
Главный вывод: граница между ноутбуком и сервером проходит не по движку, а по двум числам — байтам весов на токен и KV-кэшу на контекст. llama.cpp в 2026 году — это уже не «движок на одного пользователя»: continuous batching и слоты включены по умолчанию, и на четырёх ядрах агрегатная пропускная способность выросла вдвое при четырёх параллельных клиентах. vLLM остаётся движком для многих пользователей и для GPU дата-центра, где решает уже не полоса, а менеджмент KV-кэша и планировщик. Ollama перестала быть форком: с 0.30 это рантайм с двумя бэкендами (llama.cpp и MLX), и её главная проблема — умолчания, рассчитанные на ноутбук.
Введение
Актуальность. 2026 год — первый, когда все три движка одновременно сменили архитектуру. Ollama в мае выпустила 0.30 с прямой поддержкой llama.cpp и GGUF, сохранив MLX как отдельный движок для Apple Silicon23; в конце сентября 0.40 сделала MLX умолчанием на Apple Silicon4. llama.cpp переименовала CLI-инструменты в llama cli и llama serve, включила по умолчанию continuous batching и авто-подгонку под память устройства (--fit)51. vLLM 18 октября выпустила 0.32.0, окончательно удалив движок V0 и сделав ставку на низкоточный KV-кэш67. Старые сравнения «llama.cpp для одного, vLLM для многих» перестали описывать реальность, а новые — редко объясняют, почему цифры именно такие.
Цель — не перечислить функции, а показать механику: какое ограничение первым упирается в каждом из трёх движков и как это ограничение выглядит в числах на конкретном железе.
Границы. Не рассматриваются: обучение и файнтюнинг, серверлесс-платформы, квантование активаций в деталях, энергопотребление (публичных воспроизводимых замеров джоулей на токен почти нет). Не рассматривается и TensorRT-LLM: он закрывает другой класс задач — максимум на конкретном NVIDIA-железе ценой привязки к нему.
1. Что изменилось в 2026 году
Ollama перестала быть одним движком. До 2026 года Ollama была обёрткой над собственной сборкой ggml. В 0.30 (май) она перешла на llama.cpp и GGUF, а MLX на Apple Silicon остался отдельным движком: в релиз-ноте сказано, что новая схема «augments the MLX engine on Apple Silicon, bringing support to a wider range of hardware»3. В 0.31 (29 июня) MLX получил multi-token prediction и, по заявлению компании, до 90% прироста на Aider polyglot2. В 0.40 (25 сентября) MLX стал умолчанием для поддерживаемых архитектур: «on Apple Silicon devices, model architectures supported by the MLX runtime will automatically run on MLX»4. Актуальный релиз на момент обзора — 0.40.98.
Практическое следствие важнее маркетингового: одна и та же команда ollama run теперь может исполняться двумя разными рантаймами с разными квантами, разными ограничениями по моделям и разной скоростью. Ollama при этом ещё и торгует облаком: с 31 августа тарифы переведены на помодельную оплату за токены, например gemma4 — $0.14 за миллион входных и $0.40 за миллион выходных29, а облачные модели не требуют скачивания10.
llama.cpp сменила интерфейс и умолчания. В README теперь llama cli и llama serve вместо прежних llama-cli/llama-server5. В справке сервера -np/--parallel по умолчанию -1 (авто), -cb/--cont-batching включён по умолчанию, -ngl по умолчанию auto, а --fit («adjust unset arguments to fit in device memory») — тоже on1. То есть аргументы, которые в 2024–2025 годах приходилось подбирать вручную, стали умолчаниями. Релизы выходят ежедневно: на 22 октября актуальна сборка b1182911.
vLLM закрыла V0. Документация прямо объявляет: «We have fully deprecated V0»7. В 0.32.0 — 814 коммитов от 363 авторов, а в разделе низкоточной точности: для GLM-5.x на SM100 FP8 KV-кэш стал умолчанием и «halving KV memory per rank with 2.3-5.5% more throughput at a 7-11% TTFT cost»6. Это тот же сдвиг, что и у llama.cpp, только с другой стороны: память под кэш становится главным дефицитным ресурсом, и её жмут форматом, а не только планировщиком.
Почему это меняет выбор. Когда continuous batching есть у всех, а квантование стандартизовано в GGUF, спор о функциях заканчивается. Остаются ограничения: полоса памяти на один токен (для одного пользователя) и менеджмент KV-кэша (для многих). Ниже — по порядку.
2. Физика декода: одна цифра, которая всё решает
Тезис. Скорость генерации упирается в память, а не в вычисления. NVIDIA формулирует это в собственных материалах по оптимизации инференса: у LLM два этапа — prefill, который обрабатывает входные токены параллельно, и decode, который генерирует токены авторегрессивно и «is memory-bound»12. Аналитическая модель LIMINAL (2025) строит на этом целую теорию пределов: она абстрагирует требования приложения и возможности железа и показывает, что для авторегрессивного декода ограничения накладывает именно подсистема памяти13.
Откуда берётся формула. На каждый сгенерированный токен модель должна прочитать из памяти все веса, участвующие в проходе. Дальше арифметика: потолок токенов в секунду ≈ эффективная полоса памяти (ГБ/с) ÷ размер активных весов (ГБ)1213. Для одного пользователя это верхняя граница, которую не обойти никаким числом ядер: ядра не создают полосу.
| Модель (квант) | Размер | DDR4 (≈22 ГБ/с) | RTX 4090 (1008) | RTX 5090 (1792) | M5 Max 32c (460) | M5 Ultra (1200) |
|---|---|---|---|---|---|---|
| Qwen3.5-0.8B Q4_0 | 0.55 ГБ | ~40 | 1832 | 3258 | 836 | 2182 |
| gemma-4-12B Q4_0 | 7.2 ГБ | ~3.1 | 140 | 249 | 64 | 167 |
| gemma-4-31B Q4_0 | 18.0 ГБ | ~1.2 | 56 | 100 | 26 | 67 |
| GLM-4.7-Flash Q4_K_M | 18.3 ГБ | ~1.2 | 55 | 98 | 25 | 66 |
Значения полосы — из официальных спецификаций: RTX 5090 — 32 ГБ GDDR7 и 1792 ГБ/с, RTX 4090 — 1008 ГБ/с14; Mac Studio на M5 Max — 460 ГБ/с (32-ядерный GPU) и 614 ГБ/с (40-ядерный), на M5 Ultra — 1.2 ТБ/с при до 512 ГБ unified memory15. Строка DDR4 — не спецификация, а результат собственного замера на тестовом хосте (см. ниже).
Проверка на живой сборке. Чтобы не пересказывать чужие бенчмарки, я собрал llama.cpp (сборка b1-1ab09d6, CPU-only, -DGGML_NATIVE=ON) и прогнал llama-bench (утилита из того же проекта5) на хосте Xeon E3-1245 v6 (4 физических ядра, 8 потоков, 31 ГБ RAM, без GPU). Результаты: Qwen3.5-0.8B Q4_0 (526 МиБ) — 229.9 t/s на prefill и 38.1 t/s на декоде при 6 потоках; gemma-4-12B-it Q4_0 (6.71 ГиБ) — 12.5 t/s prefill и 3.33 t/s декода при 4 потоках. Обратный пересчёт даёт эффективную полосу: 38.1 × 0.552 ≈ 21 ГБ/с и 3.33 × 7.20 ≈ 24 ГБ/с. То есть машина реально отдаёт 21–24 ГБ/с, и модель «полоса ÷ размер» предсказывает декод с точностью 10–15%.
Заодно видно вторую закономерность: prefill и decode расходятся на порядок. На 0.8B prefill быстрее декода в 6 раз, на 12B — в 3.7 раза. Для агентских нагрузок это критично: длинный контекст — это prefill, то есть вычисления, а не полоса12, и на CPU он душит сильнее, чем генерация (12.5 t/s prefill у 12B-модели означает, что 8 тысяч токенов контекста обрабатываются больше десяти минут).
Что это значит для выбора. Числа в таблице объясняют всё дальнейшее: на ноутбуке без дискретного GPU потолок для моделей 30B-класса — единицы токенов в секунду, и никакая настройка движка этого не меняет. Наоборот, на Apple Silicon с широкой unified memory и на дискретных GPU ограничение уходит в сторону KV-кэша и батчинга. Движки различаются тем, насколько близко они подводят реальную скорость к этому потолку.
3. llama.cpp: инженерия под железо, которого нет в дата-центре
Тезис. llama.cpp оптимизирует не пропускную способность на многих пользователей, а отношение «работает / не работает» на конкретном железе. Это видно по устройству проекта: чистый C/C++ без зависимостей, первый класс — Apple Silicon через Metal, отдельные ядра для AVX/AVX2/AVX512/AMX, RISC-V, CUDA, HIP, Vulkan, SYCL, WebGPU и ещё десятка бэкендов5.
Квантование как основной инструмент. GGUF упаковывает веса, метаданные, токенайзер и параметры квантования в один файл, а поддерживаемый диапазон — от 1.5 до 8 бит на вес5. llama-quantize умеет смешивать типы внутри одной модели, квантовать по importance matrix и отдельно задавать типы для выходного тензора и эмбеддингов16. Разница в размерах не теоретическая: gemma-4-31B-it в BF16 — 61.41 ГБ, в Q8_0 — 32.64 ГБ, в Q4_0 — 17.99 ГБ17; GLM-4.7-Flash (31.2 млрд параметров) — 31.84 ГБ в Q8_0, 18.31 ГБ в Q4_K_M и 11.34 ГБ в Q2_K1819. В битах на параметр это 4.6–4.8 для 4-битных квантов, то есть заявленные «4 бита» на практике чуть дороже из-за метаданных и не квантуемых тензоров.
Гибридный инференс — главная уникальная функция. README прямо называет CPU+GPU hybrid inference для моделей больше доступной VRAM5. В 2026 году это доведено до флагов: -ngl auto, --fit on подбирают число слоёв на GPU под свободную память; -cmoe/--cpu-moe держит все веса экспертов в CPU, -ncmoe/--n-cpu-moe N — экспертов первых N слоёв, а --moe-cache-mib задаёт размер GPU-кэша для экспертов, оставшихся в CPU1.
Смысл именно в MoE: у таких моделей внимание, dense-FFN и shared-эксперты используются на каждом токене, а маршрутизируемые эксперты — только частично, поэтому «всегда активные» параметры отправляют на GPU, а экспертов — в RAM20. Формально это то, что исследовали ещё в 2023 году: стратегия offloading с учётом разреженности MoE позволила запускать Mixtral-8x7B на потребительском железе и бесплатных инстансах Colab21. Практическая разница 2026 года — в том, что это теперь флаг, а не патч.
Многопользовательский режим, которого «нет». В статье Red Hat от июня 2026 года llama.cpp описан как движок с последовательной очередью: «a consequence of llama.cpp’s sequential queuing model: requests are processed one at a time, so later arrivals wait in line»22. Справка самого llama.cpp говорит обратное: -cb/--cont-batching включён по умолчанию, -np/--parallel по умолчанию вычисляется автоматически1. Я проверил это напрямую: один и тот же бинарник, одна и та же модель, разница только в -np.
| Конфигурация | 1 клиент | 4 клиента (суммарно) | TTFT при 4 клиентах |
|---|---|---|---|
-np 1 | 36.1 t/s | 34.9 t/s | 0.06 / 3.6 / 7.4 / 11.2 с |
-np 4 | 36.8 t/s | 70.4 t/s | 0.15 с у всех |
С четырьмя слотами агрегатная пропускная способность выросла в 1.9 раза, а время до первого токена у последнего клиента упало с 11 секунд до 0.15. Причина ровно та, о которой говорит теория: при батчинге веса читаются из памяти один раз на несколько запросов, и стоимость токена на клиента падает23. На четырёх ядрах выигрыш почти двукратный; на GPU, где декод упирается в полосу сильнее, а вычислений в запасе больше, он обычно выше.
Спекулятивный декод. llama.cpp поддерживает черновые модели: --spec-draft-n-max по умолчанию 3, есть отдельные флаги для квантования и выгрузки черновика1. Идея из ICML 2023: черновая модель предлагает несколько токенов, целевая проверяет их одним проходом, распределение не меняется, ускорение на T5-XXL составило 2–3×24. Для bandwidth-bound декода это единственный способ получить больше одного токена за одно чтение весов, поэтому в 2026 году спекулятивный декод есть у всех трёх движков, и разница только в удобстве настройки.
Где llama.cpp заканчивается. Два ограничения. Первое — межGPU-масштабирование: --split-mode умеет layer (по умолчанию, конвейером), row и tensor, но последний помечен как EXPERIMENTAL1, тогда как vLLM строит tensor parallelism как основной режим25. Второе — prefill на CPU: как показал замер, 12.5 t/s prefill у 12B означает, что длинные промпты (агенты, RAG) на процессоре нерабочи способны, даже если декод «терпим». Ноутбук с дискретным GPU эту проблему снимает, но упирается в VRAM: 18 ГБ модели в 16 ГБ не влезают, и включается гибридный режим с падением скорости до уровня RAM.
4. vLLM: обслуживание многих, а не одного
Тезис. vLLM решает не проблему «поместить модель», а проблему «обслужить очередь так, чтобы GPU не простаивал». Отсюда всё остальное: PagedAttention, непрерывный батчинг, префикс-кэш, tensor parallel, дизагрегация prefill и decode2623.
Откуда взялись идеи. Работа Orca (OSDI'22) ввела iteration-level scheduling: планировщик вызывает движок на одну итерацию модели по батчу, а не на весь запрос, поэтому завершившиеся запросы уходят сразу, а новые входят в текущий батч; на GPT-3 175B это дало 36.9× пропускной способности против NVIDIA FasterTransformer при том же уровне задержки23. PagedAttention (SOSP'23) добавила вторую половину: KV-кэш хранится блоками, как страницы виртуальной памяти, что убирает фрагментацию и позволяет делить блоки между запросами — 2–4× пропускной способности и почти нулевые потери памяти26.
Что дала переработка V1. V1 переписала планировщик, менеджер KV-кэша, воркер, сэмплер и API-сервер, убрав деление на фазы prefill и decode: планировщик оперирует словарём {request_id: num_tokens}, а из этого общего представления выводятся chunked prefill, prefix caching и спекулятивный декод727. Chunked prefill в V1 включён по умолчанию, а prefix caching стал практически бесплатным: «less than 1% decrease in throughput even when the cache hit rate is 0%», поэтому его тоже включили по умолчанию27.
Релиз 0.32.0 как срез направления. Главные изменения — не про новые модели, а про память: FP8 KV-кэш по умолчанию на SM100 для GLM-5.x (вдвое меньше памяти на ранг, +2.3–5.5% пропускной способности ценой +7–11% TTFT), NVFP4 KV-кэш на SM8x/SM12x/SM90, 4-битный ultraquant_4bit на ROCm с примерно двукратной плотностью относительно FP86. Плюс Model Runner V2 с GPU-спекулятором на n-граммах и --api-server-count, который при нескольких API-воркерах даёт 43–85% больше запросов в секунду на коротких запросах6.
Цена. vLLM требует инфраструктурного мышления: при нехватке KV-кэша запросы вытесняются и пересчитываются (в V1 режим по умолчанию — RECOMPUTE), а для TP/PP нужно считать физические ядра по формуле «2 × (2 + N)» или «A + DP + N + 1», иначе GPU простаивает на планировщике и детокенизации25. Плюс startup: компиляция и захват CUDA-графов стоят секунд, а не миллисекунд, что для ноутбука с одной моделью и одним пользователем просто не нужно. В 2026 году это уже не «vLLM только для H100»: в релизе есть и CPU-сборки, и wheels под разные ускорители6, — но выигрыш от него начинается там, где в модель одновременно попадает больше одного запроса.
5. Ollama: два движка и умолчания из прошлой эпохи
Тезис. Ollama выигрывает не инженерией инференса, а упаковкой: одна команда, менеджер моделей, OpenAI-совместимый API, автозагрузка и выгрузка моделей, интеграции с coding-агентами. После 2026 года она ещё и стала мультидвижковой — и это одновременно её сила и источник путаницы.
Два рантайма, одна команда. На Apple Silicon по умолчанию работает MLX, на остальном железе — llama.cpp34. MLX построен вокруг unified memory: CPU и GPU обращаются к одному пулу, и массивы не нужно переносить между устройствами, только указывать устройство при выполнении операции28. Отсюда разные возможности: multi-token prediction и DFlash в MLX-движке2, более широкий охват GGUF и квантов в llama.cpp-движке. Формально «одна и та же модель» на M5 Max и на RTX 5090 может исполняться разными рантаймами с разными квантами — при сравнении это надо учитывать.
Умолчания, которые надо менять руками. Документация фиксирует: контекст по умолчанию — 4096 токенов, OLLAMA_NUM_PARALLEL — 1, OLLAMA_MAX_QUEUE — 512, тип KV-кэша — f16, Flash Attention включается автоматически при поддержке бэкендом29. Каждый из этих пунктов — типичная причина «Ollama тормозит»: контекст 4096 молча обрезает агентские промпты, NUM_PARALLEL=1 сериализует запросы, а f16 KV-кэш на длинном контексте съедает память, которую можно было сжать. Проверить фактическое распределение слоёв можно через ollama ps, где видно процент на GPU и выделенный контекст29.
Облако меняет экономику. С августа 2026 года Ollama продаёт облачный инференс по токенам: gemma4 — $0.14/$0.40 за миллион, glm-5.3-flash — $0.15/$0.50, kimi-k3 — $3.00/$15.00, плюс off-peak тариф для части моделей; подписки Pro ($20/мес) и Max ($100/мес) включают кредиты9. Облачные модели не скачиваются, а вызываются по API-ключу, причём поддерживаются OpenAI- и Anthropic-клиенты10. Для пользователя это означает, что «локальный» инструмент теперь умеет маршрутизировать в облако — и выбор «локально или облако» стал вопросом цены за токен, а не только приватности.
Где Ollama уместна и где нет. Уместна как персональный рантайм: одна модель, один пользователь, агент в терминале, быстрая смена моделей, автоматическая выгрузка из памяти. Неуместна как многопользовательский сервер: реальный параллелизм там есть, но выключен по умолчанию (OLLAMA_NUM_PARALLEL=1), а весь менеджмент сводится к трём переменным окружения29. Если нужен контроль над KV-кэшем, слотами и приоритетами — это уже llama.cpp напрямую или vLLM.
6. Второй счёт: KV-кэш и контекст
Тезис. После того как веса поместились, второй лимит — KV-кэш: он растёт линейно с контекстом и умножается на число параллельных запросов. Именно здесь ломаются интуиции «модель влезла в память, значит всё хорошо»: каждый запрос приносит собственный KV-кэш, растущий линейно с длиной контекста26.
Два примера из конфигураций 2026 года. gemma-4-31B-it: 60 слоёв, из них 50 со sliding-window attention (окно 1024) и 10 с полным вниманием, 16 KV-голов, head_dim 25630. На полных слоях один токен занимает 2 (K и V) × 16 × 256 × 2 байта = 16 КБ на слой, то есть 160 КБ на токен по десяти слоям; при 32K контекста это 5.37 ГБ только под KV (плюс ~0.84 ГБ на закэшированные окна остальных 50 слоёв). При 128K — уже 21.5 ГБ, больше, чем сами веса в Q4.
GLM-4.7-Flash устроен иначе: MLA с kv_lora_rank 512 и qk_rope_head_dim 64, 47 слоёв31. На слой и токен приходится 576 значений, то есть 1152 байта в f16, а всего 52.9 КБ на токен — втрое дешевле, чем у gemma при сопоставимом размере модели. На 200K контекста это 11 ГБ, на 32K — 1.77 ГБ. Отсюда практический вывод: «сколько памяти на контекст» — свойство архитектуры внимания, а не движка, и сравнивать модели по числу параметров бессмысленно.
Как это умножается на параллелизм. У Ollama контекст увеличивается кратно числу параллельных запросов: «a 2K context with 4 parallel requests will result in an 8K context», а требуемая RAM масштабируется как OLLAMA_NUM_PARALLEL × OLLAMA_CONTEXT_LENGTH29. В llama.cpp общий -c делится между слотами: при -c 16384 -np 4 сервер сообщает n_slots = 4, n_ctx_slot = 4096 (наблюдение из собственного запуска). В vLLM KV-кэш один на движок и распределяется планировщиком блоками, а при нехватке запросы вытесняются с пересчётом25. Три разные модели поведения при одном и том же дефиците памяти: у Ollama вы платите памятью заранее, у llama.cpp — размером окна на слот, у vLLM — задержкой на вытеснении.
Сжатие кэша как ответ. Все три движка в 2026 году жмут KV-кэш: FP8 и NVFP4 в vLLM6, OLLAMA_KV_CACHE_TYPE (по умолчанию f16) в Ollama29, квантованный KV в llama.cpp через флаги кэша1. Это дешёвый способ купить контекст, но у него есть цена в качестве, которую редко измеряют публично: официальные материалы фиксируют выигрыш в памяти и пропускной способности, а деградацию на длинных задачах — почти никогда.
7. Где именно ноутбук заканчивается
Тезис. Граница не в движке и не в числе параметров, а в паре «модель × контекст» против «память × полоса». Приведённая таблица декода — это и есть граница, выраженная в токенах в секунду.
Четыре режима, четыре ответа. (1) Один пользователь, ноутбук, модель 8–12B: llama.cpp или Ollama, квант Q4, всё в VRAM; на Apple Silicon — MLX через Ollama. (2) Один пользователь, модель 30B-класса: MoE с offload экспертов (--n-cpu-moe) либо гибридный режим; ожидаемая скорость — единицы–десятки токенов в секунду, и это приемлемо для чата, но не для агента с длинными контекстами. (3) 2–5 одновременных пользователей на одном GPU: llama-server со слотами (-np) или Ollama с NUM_PARALLEL > 1; замер показал почти двукратный рост агрегата при четырёх слотах. (4) 10+ пользователей, SLA, длинные контексты: vLLM с PagedAttention, префикс-кэшем и при необходимости TP/PP2625.
Правило, которое стоит запомнить. Сначала считается память: веса (размер файла) + KV-кэш (токенов × байт на токен) + буферы вычислений. Если сумма больше VRAM — вы в гибридном режиме (--n-cpu-moe, --fit)1, и потолок скорости падает до полосы RAM, то есть до единиц токенов в секунду для 30B-класса. Если сумма меньше — скорость почти равна полосе VRAM, делённой на размер, и дальше выигрыш даёт только батчинг.
Ошибки, которые видно в цифрах. Три типичные. Первая: включение слишком большого числа потоков на CPU — на тестовом хосте 8 потоков дали 27.3 t/s против 38.0 при 4, потому что физических ядер четыре. Вторая: расчёт «поместится по числу слоёв» без KV-кэша — 18 ГБ весов в 24 ГБ VRAM оставляет 6 ГБ, чего при 160 КБ на токен хватает на ~37K контекста без запаса. Третья: попытка обслуживать нескольких пользователей одним слотом — это не «медленно», это TTFT в одиннадцать секунд у четвёртого клиента.
Что не решается конфигурацией. Если модель не влезает даже в RAM, остаётся disk streaming и mmap, но это уже режим «работает», а не «работает быстро»: чтение с NVMe на порядок медленнее полосы RAM, а режим задаётся флагами --mmap/--no-mmap и --mlock1. И наоборот: если вся модель в VRAM и пользователь один, любая дополнительная инфраструктура только добавляет задержку на старте.
8. Дискуссионные вопросы
«llama.cpp обслуживает по одному запросу». Red Hat в июне 2026 года описывает последовательную очередь как свойство движка22, справка llama.cpp показывает continuous batching включённым по умолчанию1, а прямой замер даёт двукратный рост агрегата на четырёх слотах. Скорее всего, расхождение объясняется методикой: сравнение на H200 при concurrency 1–64 с Llama 3.1 8B в 16 битах22 измеряет сценарий, где llama.cpp заведомо вне своей ниши, а утверждение о «последовательной очереди» переносит настройки по умолчанию одной конфигурации на архитектуру. Вывод: тезис «llama.cpp = один пользователь» устарел, но и обратное — «llama.cpp заменяет vLLM» — неверно: у него нет ни префикс-кэша уровня V1, ни зрелого tensor parallel.
Семантика --n-cpu-moe. Справка llama.cpp говорит: «keep the Mixture of Experts (MoE) weights of the first N layers in the CPU»1, а практическое руководство на Hugging Face предупреждает, что отсчёт идёт с самых старших слоёв и из-за dense-слоёв в начале модели фактическое число выгруженных слоёв может отличаться20. Это ровно тот случай, когда документация и опыт расходятся: проверять надо по фактическому распределению памяти при запуске, а не по числу в флаге.
«Квантование почти бесплатно». Все источники сходятся, что 4-битные кванты сохраняют качество «для большинства задач»2216, но конкретика разная: 2-битные кванты уменьшают GLM-4.7-Flash с 18.31 до 11.34 ГБ, то есть на 38%18, и именно на этом диапазоне обычно начинается заметная деградация. Воспроизводимых измерений perplexity/KLD для моделей 2026 года в открытом доступе мало, а те, что есть, сделаны на других моделях и другом железе. Поэтому практическое правило остаётся эмпирическим: Q4_K_M/Q4_0 — рабочая точка, Q2 — только когда иначе не влезает.
Unified memory против дискретной VRAM. Apple даёт до 512 ГБ unified memory и 1.2 ТБ/с на M5 Ultra15, что формально позволяет держать модель, недоступную ни одной потребительской видеокарте. Но полоса — не единственная метрика: на M5 Max (460 ГБ/с) потолок для 18-ГБ модели — 25 токенов в секунду, тогда как RTX 5090 с 1792 ГБ/с даёт около 100, но с 32 ГБ VRAM14. Это два разных компромисса: «влезет большое, но медленно» против «влезет среднее, но быстро», и выбрать между ними нельзя без ответа на вопрос, какой контекст нужен.
9. Недостаточность данных
Три вопроса остались без надёжного ответа. Первый: насколько Ollama на MLX быстрее или медленнее llama.cpp на одном и том же Mac при одной модели и одном кванте — публичных воспроизводимых замеров в этом запуске найти не удалось, а собственные цифры Ollama (до 90% на Aider polyglot после MTP)2 не отделяют вклад движка от вклада MTP и от разницы в квантах. Второй: деградация качества при квантованном KV-кэше на длинных контекстах — источники дают выигрыш в памяти и пропускной способности629, но не дают чисел по качеству. Третий: энергопотребление на токен — ни один из производителей не публикует воспроизводимых методик, а без них сравнение «ноутбук против сервера» по стоимости остаётся неполным.
Заключение
Три движка в 2026 году решают три разные задачи, и различие между ними описывается двумя числами. llama.cpp минимизирует требования к железу: GGUF, квантование от 1.5 бит, гибридный CPU+GPU инференс, MoE-offload и — вопреки репутации — включённый по умолчанию continuous batching, который на четырёх ядрах даёт почти двукратный рост агрегатной пропускной способности. vLLM максимизирует пропускную способность на многих пользователях: PagedAttention, единый планировщик V1, бесплатный префикс-кэш, низкоточные KV-кэши и tensor parallel. Ollama минимизирует усилия: одна команда, два рантайма, автоподгрузка моделей, облако по токенам — и умолчания, которые нужно осознанно менять.
Практические рекомендации короткие. Считайте память до выбора движка: веса плюс KV-кэш на нужный контекст плюс запас; если не влезает — берите MoE с offload экспертов, а не 2-битный квант. Проверяйте полосу: скорость декода на одного пользователя — это полоса ÷ размер12, и на ноутбуке без дискретного GPU она физически ограничена. Ставьте слоты, если пользователей больше одного: разница между -np 1 и -np 4 измеряется не процентами, а разы. И не путайте «движок поддерживает» с «движок включает по умолчанию» — в 2026 году это главный источник неверных ожиданий.
Что стоит проверить дальше: воспроизводимое сравнение MLX- и llama.cpp-рантаймов Ollama на одинаковых моделях и квантах; качество квантованного KV-кэша на задачах с длинным контекстом; стоимость токена с учётом энергии на потребительском и серверном железе.
Quality Metrics
| Metric | Value |
|---|---|
| Total sources | 31 |
| Academic sources | 5 |
| Official/documentation | 21 |
| Industry reports | 2 |
| News/journalism | 0 |
| Blog/forum | 3 |
| Citation coverage | 79% |
| Counter-arguments searched | Yes |
| Research rounds | 3 |
| Questions emerged | 6 |
| Questions resolved | 3 |
| Questions insufficient data | 3 |
ggml-org. “llama-server documentation (tools/server/README.md).” GitHub, 2026. https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
Ollama. “Blog — Clef, MLX, MTP and pricing announcements.” ollama.com, 2026. https://ollama.com/blog ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
Ollama. “Release v0.30.0.” GitHub, 5 June 2026. https://github.com/ollama/ollama/releases/tag/v0.30.0 ↩︎ ↩︎ ↩︎
Ollama. “Release v0.40.0 — Models run on MLX on Apple Silicon by default.” GitHub, 2026. https://github.com/ollama/ollama/releases/tag/v0.40.0 ↩︎ ↩︎ ↩︎
ggml-org. “llama.cpp — LLM inference in C/C++ (README).” GitHub, 2026. https://github.com/ggml-org/llama.cpp ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
vLLM Project. “Release v0.32.0.” GitHub, 18 October 2026. https://github.com/vllm-project/vllm/releases/tag/v0.32.0 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
vLLM Project. “vLLM V1 — user guide.” docs.vllm.ai, 2026. https://docs.vllm.ai/en/latest/usage/v1_guide.html ↩︎ ↩︎ ↩︎
Ollama. “Releases — ollama/ollama.” GitHub, October 2026. https://github.com/ollama/ollama/releases ↩︎
Ollama. “Pricing — plans and per-model token prices.” ollama.com, 2026. https://ollama.com/pricing ↩︎ ↩︎
Ollama. “Cloud — run models in Ollama’s cloud.” docs.ollama.com, 2026. https://docs.ollama.com/cloud ↩︎ ↩︎
ggml-org. “Releases — llama.cpp (b11829).” GitHub, 22 October 2026. https://github.com/ggml-org/llama.cpp/releases ↩︎
NVIDIA. “Mastering LLM Techniques: Inference Optimization.” NVIDIA Technical Blog. https://developer.nvidia.com/blog/mastering-llm-techniques-inference-optimization/ ↩︎ ↩︎ ↩︎ ↩︎
Davies, M. et al. “LIMINAL: Exploring The Frontiers of LLM Decode Performance.” arXiv:2507.14397, 2025. https://arxiv.org/abs/2507.14397 ↩︎ ↩︎
NVIDIA. “GeForce RTX 5090 — specifications and comparison table.” nvidia.com, 2026. https://www.nvidia.com/en-us/geforce/graphics-cards/50-series/rtx-5090/ ↩︎ ↩︎
Apple. “Mac Studio — Technical Specifications.” apple.com, 2026. https://www.apple.com/mac-studio/specs/ ↩︎ ↩︎
ggml-org. “quantize tool documentation (tools/quantize/README.md).” GitHub, 2026. https://github.com/ggml-org/llama.cpp/blob/master/tools/quantize/README.md ↩︎ ↩︎
ggml-org. “gemma-4-31B-it-GGUF — файлы и размеры.” Hugging Face, 2026. https://huggingface.co/ggml-org/gemma-4-31B-it-GGUF/tree/main ↩︎
unsloth. “GLM-4.7-Flash-GGUF — файлы и размеры.” Hugging Face, 2026. https://huggingface.co/unsloth/GLM-4.7-Flash-GGUF/tree/main ↩︎ ↩︎
zai-org. “GLM-4.7-Flash — model metadata (31.2B parameters).” Hugging Face API, 2026. https://huggingface.co/api/models/zai-org/GLM-4.7-Flash ↩︎
Doctor-Shotgun. “Performant local mixture-of-experts CPU inference with GPU acceleration in llama.cpp.” Hugging Face Blog, 30 January 2026. https://huggingface.co/blog/Doctor-Shotgun/llamacpp-moe-offload-guide ↩︎ ↩︎
Eliseev, A., Mazur, D. “Fast Inference of Mixture-of-Experts Language Models with Offloading.” arXiv:2312.17238, 2023. https://arxiv.org/abs/2312.17238 ↩︎
Red Hat Developer. “llama.cpp vs. vLLM: Choosing the right local LLM inference engine.” 15 June 2026. https://developers.redhat.com/articles/2026/06/15/llamacpp-vs-vllm-choosing-right-local-llm-inference-engine ↩︎ ↩︎ ↩︎ ↩︎
Yu, G.-I. et al. “Orca: A Distributed Serving System for Transformer-Based Generative Models.” USENIX OSDI'22. https://www.usenix.org/conference/osdi22/presentation/yu ↩︎ ↩︎ ↩︎
Leviathan, Y., Kalman, M., Matias, Y. “Fast Inference from Transformers via Speculative Decoding.” arXiv:2211.17192 (ICML 2023). https://arxiv.org/abs/2211.17192 ↩︎
vLLM Project. “Optimization and Tuning.” docs.vllm.ai, 2026. https://docs.vllm.ai/en/latest/configuration/optimization.html ↩︎ ↩︎ ↩︎ ↩︎
Kwon, W. et al. “Efficient Memory Management for Large Language Model Serving with PagedAttention.” arXiv:2309.06180 (SOSP 2023). https://arxiv.org/abs/2309.06180 ↩︎ ↩︎ ↩︎ ↩︎
vLLM Team. “vLLM V1: A Major Upgrade to vLLM’s Core Architecture.” vLLM Blog, 27 January 2025. https://blog.vllm.ai/2025/01/27/v1-alpha-release.html ↩︎ ↩︎
Apple Machine Learning Research. “MLX — Unified Memory.” MLX documentation, 2026. https://ml-explore.github.io/mlx/build/html/usage/unified_memory.html ↩︎
Ollama. “FAQ — context length, parallel requests, KV cache type.” docs.ollama.com, 2026. https://docs.ollama.com/faq ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎
Google. “gemma-4-31B-it — config.json (60 layers, 10 full-attention, head_dim 256).” Hugging Face, 2026. https://huggingface.co/google/gemma-4-31B-it/raw/main/config.json ↩︎
zai-org. “GLM-4.7-Flash — config.json (MLA, 64 routed experts, 47 layers).” Hugging Face, 2026. https://huggingface.co/zai-org/GLM-4.7-Flash/raw/main/config.json ↩︎