llama.cpp против Ollama: что выгоднее и когда
Спор «llama cpp или ollama» выглядит как выбор между двумя движками, но выбираете вы между движком и продуктом вокруг него: Ollama считает теми же ядрами ggml. Разница почти не в скорости — она в том, кто управляет контекстом, потоками и обновлениями, и во что это обходится в эксплуатации. Ниже — граница выбора, команды сборки, точные тексты ошибок и расчёт сервера.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Короткий ответ: где проходит граница
Разложите решение на три вопроса — и выбор займёт минуту.
- Сколько у вас моделей. Нужно держать чат на 8B, мелкую модель для классификации и эмбеддинги, переключаясь между ними по требованию, — берите Ollama. Один процесс
llama-serverобслуживает ровно одну модель, и мультимодельность придётся собирать самому. - Насколько важен контроль над сборкой и флагами. Нужны поддержка только что вышедшей архитектуры, квантованный KV-кэш, точный
--parallel, сборка под конкретные инструкции процессора — это llama.cpp. Ollama прячет половину этих ручек за умолчаниями. - Кто будет это обслуживать. Ollama ставится одной командой, обновляется пакетом, сама скачивает модели и переживает перезагрузку без вашего участия. llama.cpp — это бинарник, который вы собрали, юнит systemd, который вы написали, и обновление руками.
Короче: Ollama выгоднее, когда моделей много, а времени мало; llama.cpp — когда модель одна, а требования к ней жёсткие. И честно: разницы в токенах в секунду при одинаковой модели, квантовании и числе потоков вы почти не увидите — внизу один и тот же ggml.
И сразу отсечём ложную развилку: ни один из них не про высокий параллелизм. Если к модели постоянно приходит десяток одновременных запросов, ответ не «llama.cpp», а vLLM с видеокартой — разбор в статье Ollama против vLLM.
Что вы на самом деле сравниваете
llama.cpp — проект ggml-org: библиотеки ggml плюс исполняемые файлы. После переименования 2024 года они называются llama-cli, llama-server, llama-bench, llama-quantize и лежат в build/bin/. Инструкции с ./main и ./server устарели: таких бинарников больше нет.
Семантических версий у llama.cpp нет. Релиз — это номер сборки вида b10154, и выходит их по нескольку в день. Следствие: «последняя версия» у вас и у автора инструкции — разные сборки, а флаги между ними меняются. Свежий пример — --flash-attn, который из переключателя стал принимать on, off и auto.
Ollama — сервер на Go с реестром моделей, CLI и HTTP-API, версии обычные, вида 0.33.x. Долгое время это была обвязка вокруг llama.cpp, но формулировка «Ollama — это просто llama.cpp» уже неточна: часть моделей обслуживает её собственный движок поверх ggml, минуя код llama.cpp. Отсюда расхождение в наборе поддерживаемых архитектур: «в llama.cpp эта модель уже работает» не гарантирует, что она работает в Ollama, и наоборот.
Лицензия у обоих MIT — юридических поводов выбирать нет. А языки разные, и это заметно: Ollama — один бинарник на Go без зависимостей, llama.cpp — C++, который надо собрать под вашу систему.
| llama.cpp | Ollama | |
|---|---|---|
| Что это | движок и набор бинарников | сервер с реестром моделей |
| Установка | сборка через cmake или готовый архив | install.sh, deb-репозиторий, Docker |
| Версионирование | номер сборки bNNNNN | 0.33.x |
| Моделей на процесс | одна | несколько, с выгрузкой по таймауту |
| Формат моделей | файлы .gguf как есть | blob-хранилище с манифестами |
| Авторизация в API | --api-key из коробки | нет, только через обратный прокси |
| Порт по умолчанию | 8080, слушает 127.0.0.1 | 11434, слушает 127.0.0.1 |
| Веб-интерфейс | встроенный, отключается --no-webui | нет, ставится отдельно |
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверУстановка и обновление: одна команда против cmake
Ollama ставится так, и на этом всё:
curl -fsSL https://ollama.com/install.sh | sh
systemctl status ollama
ollama pull qwen2.5:7b
Скрипт заводит пользователя ollama, кладёт юнит в /etc/systemd/system/ollama.service и включает автозапуск; модели уезжают в /usr/share/ollama/.ollama/models.
llama.cpp собирается из исходников. На чистой Ubuntu 24.04 нужен полный набор зависимостей:
apt update && apt install -y build-essential cmake git libcurl4-openssl-dev
git clone https://github.com/ggml-org/llama.cpp && cd llama.cpp
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release -j "$(nproc)"
Две ошибки, на которых спотыкаются практически все.
Забытый libcurl. Скачивание моделей по -hf встроено в общий код, и без заголовков curl конфигурация просто падает:
CMake Error at common/CMakeLists.txt:90 (message):
Could NOT find CURL (missing: CURL_LIBRARY CURL_INCLUDE_DIR)
Лечится либо apt install libcurl4-openssl-dev, либо флагом -DLLAMA_CURL=OFF, если модели вы кладёте на диск руками.
Illegal instruction после переезда. По умолчанию сборка идёт с GGML_NATIVE=ON — под инструкции того процессора, на котором вы собирали. Пока машина та же, всё хорошо; после живой миграции на узел с более старым CPU или переноса бинарника получаете:
Illegal instruction (core dumped)
Ни строчки объяснения, ни лога. Если бинарник переезжает между машинами, собирайте с -DGGML_NATIVE=OFF и явным набором расширений вроде -DGGML_AVX2=ON: потеря скорости — единицы процентов.
Собирать не обязательно: готовые архивы лежат в релизах (llama-b10154-bin-ubuntu-x64.zip — распаковать и запускать, если glibc не старше сборочной), есть официальный образ ghcr.io/ggml-org/llama.cpp:server, и тогда обновление сводится к смене тега.
Обновление — самая недооценённая статья расходов. Ollama обновляется повторным запуском install-скрипта, юнит и модели остаются на месте. llama.cpp — вручную: git pull, пересборка (на 4 vCPU несколько минут под полной загрузкой), подмена бинарника. Раз в квартал терпимо, раз в неделю — уже работа.
Деталь про наш каталог: Ollama есть в apps.maatrix.io и разворачивается автоматически при заказе сервера, доступы приходят в кабинет. llama.cpp в каталоге нет — сервер приезжает чистым, и вы ставите её по командам выше: одного «правильного» набора флагов сборки у неё не существует.
Модели: файлы GGUF против blob-хранилища
llama.cpp работает с обычными файлами. Скачали .gguf с Hugging Face — указали путь в -m. Есть и встроенная загрузка:
./build/bin/llama-server -hf bartowski/Qwen2.5-7B-Instruct-GGUF:Q4_K_M -c 8192
Ollama хранит модели иначе: содержимое лежит в blobs/ под именами sha256-... без расширения, состав описан манифестом в manifests/registry.ollama.ai/library/. Тег qwen2.5:7b — указатель, который может переехать на другую сборку; воспроизводимо выглядит qwen2.5:7b-instruct-q4_K_M.
Отсюда ловушка с диском. Если вы уже держите GGUF-файлы для llama.cpp и импортируете те же модели в Ollama, ollama create не ссылается на файл, а копирует его в своё хранилище: 5 ГБ весов превращаются в 10 ГБ. На 40–60 ГБ NVMe три-четыре такие пары упираются в no space left on device быстрее, чем кажется.
Работает и обратный, более полезный трюк. Ollama печатает реальный путь к весам, и его можно скормить llama.cpp — без повторной загрузки и без дубликата:
ollama show --modelfile qwen2.5:7b | awk '/^FROM/{print Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
; exit}'
# /usr/share/ollama/.ollama/models/blobs/sha256-2bada8a74506...
./build/bin/llama-server -m "$(ollama show --modelfile qwen2.5:7b | awk '/^FROM/{print Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
; exit}')" \
-c 8192 -t 8 --host 127.0.0.1 --port 8080
Так вы сравниваете два сервера на одном и том же файле — и заодно снимаете вопрос «перекладывания» моделей при переходе с одного инструмента на другой.
Где хранить — тоже разница. У Ollama путь меняется переменной OLLAMA_MODELS, и задать её надо до первой загрузки, иначе блобы придётся переносить руками. У llama.cpp вопроса нет: файл лежит там, где вы его положили. Про выбор квантования — отдельный разбор в статье Какое квантование выбрать для Llama.
Скорость и память: чего ждать на CPU
Главное принять: на одинаковых входных условиях они считают примерно одинаково. Ниже — наш замер на AMD EPYC 9554, 16 vCPU (8 физических ядер плюс гипертреды), Ollama 0.33.1, qwen2.5:7b в Q4_K_M, контекст 4096.
| Потоков | Обработка промпта, ток/с | Генерация, ток/с |
|---|---|---|
| 2 | 12,6 | 5,7 |
| 4 | 31,0 | 7,6 |
| 16 | 68,0 | 7,4 |
| 32 | 10,9 | 0,35 |
Два вывода, одинаково верных для обоих инструментов. Первый: генерация выходит на полку уже на четырёх потоках — 7,6 против 7,4 на шестнадцати, разница в пределах погрешности. Упирается она не в процессор, а в пропускную способность памяти: на каждый токен читаются все веса целиком. Обработка промпта, наоборот, честно растёт до числа физических ядер — это матричные операции.
Второй: 32 потока на 16 vCPU дают обвал в двадцать раз, до 0,35 токена в секунду. Потоки вытесняют друг друга с ядер, и модель отвечает по три секунды на токен. Ставить -t или num_thread «с запасом» нельзя. Подробнее — в статье Ollama не использует все ядра CPU.
Разброс по моделям на том же стенде при 16 потоках больше, чем разброс между инструментами:
| Модель, Q4_K_M | Генерация, ток/с | Занято по ollama ps |
|---|---|---|
| qwen2.5:3b | 34,1 | 2,2 ГБ |
| llama3.1:8b | 12,8 | 5,6 ГБ |
| mistral:7b | 12,1 | 5,0 ГБ |
| gemma2:9b | 8,8 | — |
| qwen2.5:7b | 7,4 | 5,1 ГБ |
Обратите внимание: «7B» само по себе не говорит ничего — mistral:7b быстрее qwen2.5:7b почти вдвое. И третью колонку читайте правильно: ollama ps показывает не веса, а всю занятую память — веса плюс KV-кэш и вычислительные буферы. Для 7B в Q4_K_M это ~4,7 ГБ весов и ещё несколько сотен мегабайт сверху при контексте 4096.
А вот управление потоками различается ощутимо. У llama.cpp это флаги запуска: -t 8 на генерацию и -tb 16 отдельно на обработку промпта — обе полки забираются сразу. У Ollama переменной окружения для потоков нет вовсе: num_thread задаётся через PARAMETER в Modelfile, поле options в API или /set parameter. Строка OLLAMA_NUM_THREAD=16 в юните не даст ничего — сервис её молча проигнорирует.
Мерить на своём железе удобнее штатным бенчмарком llama.cpp — ни клиента, ни сервера он не требует:
./build/bin/llama-bench -m ~/models/qwen2.5-7b-instruct-q4_k_m.gguf -p 512 -n 128 -t 8
# столбцы: model | size | params | backend | threads | test | t/s
# строка pp512 — обработка промпта, tg128 — генерация
Контекст, слоты и эксплуатация: где различия становятся дорогими
Самая недооценённая разница — семантика контекста, и на ней теряют память обе стороны, но по-разному.
В llama.cpp -c — это общий бюджет KV-кэша на все слоты. Запустили -c 32768 -np 4 — каждый запрос получит по 8192 токена, а не по 32768. Логика против интуиции, зато память предсказуема: сколько попросили, столько и заняли; поведение регулируется флагом --kv-unified.
В Ollama num_ctx — это контекст на слот, и он умножается. OLLAMA_NUM_PARALLEL=4 при num_ctx 8192 означает запрос кэша на 32768 токенов, независимо от того, пользуется ли кто-то слотами сейчас. Отсюда классическое «поставил 8 на всякий случай — получил нехватку памяти на ровном месте». Плюс своя логика умолчаний: контекст выбирается по доступной памяти, и без видеокарты это обычно 4096 — модель с окном 128k молча работает в 4k, пока вы не скажете обратное.
Когда контекст всё-таки кончается, llama-server отвечает не молчанием, а конкретным HTTP 400:
{"error":{"code":400,"type":"invalid_request_error",
"message":"the request exceeds the available context size. try increasing the context size or enable context shift"}}
Сдвиг контекста в свежих сборках выключен и включается флагом --context-shift. Ollama обрежет начало диалога сама — удобнее, но вы не узнаете, что модель забыла системный промпт.
Дальше — четыре вещи, которые решают в проде:
- Держать ли модель в памяти. Ollama выгружает её через 5 минут простоя, и следующий запрос ждёт повторной загрузки весов с диска; лечится
OLLAMA_KEEP_ALIVE=-1.llama-serverдержит модель постоянно — это и плюс (нет холодных стартов), и минус (память занята круглосуточно). - Авторизация. У llama-server есть
--api-key, и без заголовкаAuthorization: Bearerзапрос не пройдёт. У Ollama её нет: открытый наружу порт 11434 — это чужие люди, гоняющие ваш процессор. Оба слушают localhost, и это правильно: наружу только через Nginx с TLS, плюсufw deny 11434/tcpиufw deny 8080/tcp. - Несколько моделей. У Ollama это данность:
OLLAMA_MAX_LOADED_MODELSи автовыгрузка. У llama.cpp — процесс на модель, разные порты и своя маршрутизация сверху либо прокси вроде llama-swap. Если моделей три, а памяти на одну, выбор сделан за вас. - Юнит systemd вы пишете сами. Минимальный рабочий вариант для llama-server:
[Unit]
Description=llama.cpp server
After=network-online.target
[Service]
User=llama
ExecStart=/opt/llama.cpp/build/bin/llama-server \
-m /opt/models/qwen2.5-7b-instruct-q4_k_m.gguf \
-c 8192 -np 2 -t 8 -tb 16 --host 127.0.0.1 --port 8080 \
--api-key-file /etc/llama/apikey --no-webui --metrics
Restart=always
RestartSec=3
LimitMEMLOCK=infinity
[Install]
WantedBy=multi-user.target
Диагностика тоже разная. curl -s 127.0.0.1:8080/health отдаёт {"status":"ok"}, при загрузке весов — 503 с "message":"Loading model"; /props показывает фактический n_ctx, /slots (с флагом --slots) — состояние слотов, /metrics — метрики Prometheus. У Ollama аналог скромнее: ollama ps.
Какой сервер брать в MAATRIX
Оба на VPS без видеокарты упираются в одно — в пропускную способность памяти, а не в процессор. Конфигурация считается от модели, а не от инструмента.
Честный минимум: 2 vCPU, 8 ГБ RAM, 60 ГБ NVMe. Сюда помещается модель на 7–8B в Q4_K_M (около 5 ГБ весов плюс кэш) с контекстом 4096–8192 и одним слотом. Ограничение называю прямо: 7–13 токенов в секунду, ответ на абзац идёт секунд десять-пятнадцать. Для бота, классификатора, суммаризации по расписанию — нормально, для живого чата — раздражает. Вторую модель рядом не положить: вытеснит первую.
Комфортный вариант: 4–8 vCPU, 16 ГБ RAM, 100 ГБ NVMe. Обработка промпта ускоряется кратно (полка по ядрам есть на генерации, а на промпте — нет), помещаются две модели сразу или одна 9B с контекстом побольше, остаётся место под сборку. Держать оба инструмента параллельно стоит только здесь: на 8 ГБ они выбивают друг друга по памяти.
Что не надо покупать. Гнаться за числом vCPU бессмысленно: 32 потока на 16 ядрах дают падение в двадцать раз, а не прирост — деньги лучше уходят в объём и скорость памяти. А десятки одновременных запросов или ответ быстрее секунды — уже не CPU-сценарий, а сервер с видеокартой; расчёт памяти под разные модели есть в статье Сколько RAM нужно для Ollama.
Локация — Великобритания, Лондон. Причина прикладная: веса с Hugging Face, релизы llama.cpp и реестр Ollama тянутся с зарубежных зеркал, и из Лондона это идёт на полной скорости канала. Для аудитории в Европе задержка минимальна, для российской добавляется 40–60 мс RTT — на фоне 7–13 токенов в секунду это незаметно. Если сервис работает только на Россию и трогает персональные данные, берите российскую локацию: там решает 152-ФЗ, а не скорость.
Оплата — картой российского банка, по СБП, криптовалютой или токеном MAAT; иностранная карта не нужна. Сервер выдаётся с чистой Ubuntu 24.04 или Debian 13. Ollama можно выбрать из каталога apps.maatrix.io и получить готовый сервис сразу, а llama.cpp собрать поверх — командами из третьей секции.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Правда, что Ollama — просто обёртка над llama.cpp и работает медленнее?
Раньше была обёрткой, сейчас часть моделей обслуживает её собственный движок поверх ggml. Медленнее она не работает: при одинаковой модели, квантовании и числе потоков разница теряется в погрешности. Замечаемое отставание обычно объясняется умолчаниями — контекстом 4096 и выгрузкой модели через 5 минут простоя.
Можно ли отдать llama.cpp модель, скачанную через Ollama?
Да, и это лучший способ не хранить веса дважды: путь к блобу печатает ollama show --modelfile <модель> | awk '/^FROM/{print $2; exit}', дальше он идёт в -m. Обратное направление хуже: ollama create копирует ваш GGUF в своё хранилище.
Что выбрать, если нужен только OpenAI-совместимый API для одного приложения?
llama.cpp: llama-server даёт /v1/chat/completions, ключ через --api-key и точный контроль над -c, -np и потоками. Ollama тут добавляет лишь удобство обновлений — а один процесс с одной моделью вы обновите и руками.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.