Локальная LLM с OpenAI-совместимым API: Ollama, llama.cpp или vLLM

Задача звучит просто: «поднять у себя локальную языковую модель и дёргать её по API из своего кода — так, чтобы не переписывать приложение под каждый движок». А дальше начинается развилка, на которой люди тонут. Ollama? llama.cpp? vLLM? Text-generation-webui? У каждого свои евангелисты, свои бенчмарки и своя интонация «да это же очевидно».

Хорошая новость в том, что все три серьёзных варианта решают одну и ту же задачу и все три отдают OpenAI-совместимый HTTP-эндпоинт — то есть ваш клиент (openai для Python, любой чат-UI, n8n, свой скрипт) подключается к ним одинаково, меняется только base_url. Плохая — что выбирать всё равно придётся, потому что они оптимизированы под разное.

Этот гайд — не «топ-3 лучших инструмента» (такие списки обычно пишут ради ссылок). Это разбор одной конкретной задачи тремя способами, с реальными командами из официальной документации, честными компромиссами и понятным ответом на вопрос «что взять именно мне». Разберём Ollama, llama.cpp и vLLM — по одному сценарию на каждый — а в конце сведём выбор в матрицу.

Info:

Для кого гайд: у вас есть машина с приличной видеокартой (или Mac на Apple Silicon, или хотя бы 16 ГБ ОЗУ для скромных моделей), и вы хотите гонять LLM локально — ради приватности, отсутствия платы за токены или просто контроля. Базовое знакомство с терминалом и Docker предполагается; глубоких знаний ML — нет.

Сначала — про память, иначе всё остальное бессмысленно

Прежде чем спорить о движках, надо понять одну вещь, об которую спотыкаются почти все новички: сколько памяти съест модель. Потому что самый частый провал — не «выбрал не тот движок», а «выбрал модель, которая не влезла».

Модели раздают в разной точности (квантовании). Полная точность (FP16) — это ~2 ГБ на каждый миллиард параметров. Никто дома так не запускает. На практике берут квантованные версии — чаще всего 4-битные, формат GGUF с суффиксом вроде Q4_K_M. Это компромисс: модель занимает вчетверо меньше, а качество проседает едва заметно.

Грубая прикидка, от которой можно плясать:

Important:

Ключевой принцип, который экономит часы боли: нужной памяти всегда чуть больше, чем весит файл модели. Сверху ложится KV-кэш — он хранит контекст и растёт вместе с длиной промпта и числом параллельных запросов. Планируйте с запасом 15–20% поверх веса файла, а для сервера на много пользователей — заметно больше.

Если модель не влезает в видеопамять целиком, её можно частично «сгрузить» в обычную ОЗУ (offload) — но тогда скорость падает в разы, потому что часть вычислений идёт на CPU. Влезла в VRAM целиком — быстро. Не влезла — терпимо или совсем медленно. Это и есть та ось, по которой ниже расходятся три подхода.

Подход 1. Ollama — когда важно «просто чтобы работало»

Сценарий: вы хотите поднять модель за пять минут, дёргать её из своего скрипта и не думать про флаги, форматы и сборку. Классика для домашнего сервера, прототипа, личного ассистента.

Ollama — это обёртка над движком инференса, которая берёт на себя всё: скачивание модели, выбор квантования, менеджмент памяти, запуск сервера. По духу — «Docker для LLM»: одна команда, и модель работает.

Установка в Docker (официальные команды из доки):

# CPU-only
docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

# NVIDIA GPU (нужен nvidia-container-toolkit)
docker run -d --gpus=all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama

# AMD GPU
docker run -d --device /dev/kfd --device /dev/dri -v ollama:/root/.ollama \
  -p 11434:11434 --name ollama ollama/ollama:rocm

Для NVIDIA перед этим один раз настраивается рантайм:

sudo nvidia-ctk runtime configure --runtime=docker
sudo systemctl restart docker

Запустить модель:

docker exec -it ollama ollama run llama3.2

Первый запуск скачает модель, дальше она уже локально. А главное для нашей задачи — Ollama сразу поднимает HTTP-сервер на порту 11434 с двумя видами API: собственным и OpenAI-совместимым. Обращаетесь так:

from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")  # ключ любой
resp = client.chat.completions.create(
    model="llama3.2",
    messages=[{"role": "user", "content": "Объясни, что такое KV-кэш простыми словами"}],
)
print(resp.choices[0].message.content)

Тот же код, что вы писали бы для OpenAI, — меняется только base_url. В этом вся суть совместимости.

Success:

Берите Ollama, если: это домашний сервер или прототип; вы не хотите разбираться в квантовании и флагах; нужен один-два пользователя (по сути — вы сами); важна простота и быстрый старт. Для 90% личных сценариев этого хватает с головой.

Warning:

Где Ollama проседает: под нагрузкой. Он честно, но не блестяще держит много одновременных запросов — если вы делаете сервис на десятки параллельных пользователей, пропускная способность станет узким местом. И он абстрагирует детали, которые иногда нужно контролировать вручную (точный тип квантования, тонкая настройка памяти). Это цена простоты.

Подход 2. llama.cpp — когда нужен контроль и экзотическое железо

Сценарий: у вас нестандартное железо (старая карта, слабый GPU, Raspberry Pi, Intel Arc, что угодно), или вы хотите точно управлять квантованием и параметрами, или вам нужно выжать максимум из скромной машины. Тут за ширмой Ollama живёт как раз llama.cpp — и можно работать с ним напрямую.

llama.cpp — это «LLM inference in C/C++» с минимумом зависимостей и, пожалуй, самым широким в индустрии списком поддерживаемого железа: CUDA (NVIDIA), HIP (AMD), Metal (Apple Silicon), Vulkan, SYCL/OpenVINO (Intel), а также CANN, MUSA, OpenCL и прочая экзотика. Именно он умеет запускать модель там, где всё остальное отказывается.

Формат моделей — тот самый GGUF, а квантование поддерживается от 1,5 до 8 бит. Тонкий контроль над памятью и скоростью — это про него.

Скачать и запустить модель прямо из HuggingFace одной командой:

# интерактивный CLI
llama-cli -hf ggml-org/Qwen3.5-0.8B-GGUF

# OpenAI-совместимый сервер
llama-server -hf ggml-org/Qwen3.5-0.8B-GGUF

llama-server поднимает HTTP-эндпоинт (по умолчанию порт 8080) с OpenAI-совместимым API — подключаетесь к нему тем же клиентом, что и выше, поменяв base_url на http://localhost:8080/v1. Дополнительно у llama.cpp есть приятные штуки для разработчиков: GBNF-грамматики для строго структурированного вывода (заставить модель отвечать валидным JSON по схеме) и тонкие ручки под каждый бэкенд.

Note:

Практическая ценность GGUF в том, что на HuggingFace лежат тысячи уже квантованных моделей от сообщества (ищите репозитории с суффиксом -GGUF). Не нужно ничего конвертировать самому: выбрали нужный уровень квантования под свою память — и llama-server -hf <repo> его скачает.

Success:

Берите llama.cpp, если: у вас необычное или слабое железо; нужен контроль над квантованием и памятью; хочется структурированного вывода через грамматики; вы готовы потратить чуть больше времени на настройку в обмен на гибкость. Это выбор тех, кому «магия» Ollama мешает, а не помогает.

Подход 3. vLLM — когда важна пропускная способность

Сценарий: вы поднимаете не «ассистента для себя», а сервис, который обслуживает десятки и сотни параллельных запросов — внутренний инструмент для команды, бэкенд продукта, пакетная обработка. Тут правила игры меняются: важна не «скорость одного ответа», а сколько запросов в секунду держит машина.

vLLM — это движок, заточенный именно под высокую пропускную способность на серверных GPU. Его фишка — эффективное управление памятью и батчинг запросов, за счёт чего одна видеокарта обслуживает куда больше параллельных клиентов, чем наивный инференс.

Запуск в Docker (официальная команда):

docker run --runtime nvidia --gpus all \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  --env "HUGGING_FACE_HUB_TOKEN=<токен>" \
  -p 8000:8000 \
  --ipc=host \
  vllm/vllm-openai:latest \
  --model mistralai/Mistral-7B-v0.1

Разберём важные флаги, потому что на них спотыкаются:

  • --gpus all — доступ к видеокартам;
  • --ipc=hostобязательно (или --shm-size): vLLM использует PyTorch, а тот шарит данные между процессами через разделяемую память; без этого флага при тензорном параллелизме всё встанет;
  • том с кэшем HuggingFace, чтобы не качать модель заново при каждом рестарте;
  • порт 8000 — на нём поднимается OpenAI-совместимый сервер.

Полезные параметры движка, которые задаются после имени образа:

  • --gpu-memory-utilization — какую долю VRAM занять (по умолчанию агрессивно; понижают, если карта делится с другими задачами);
  • --max-model-len — максимальная длина контекста (прямо влияет на расход памяти под KV-кэш);
  • --tensor-parallel-size — размазать одну большую модель на несколько GPU;
  • квантование — поддерживаются AWQ, BitsAndBytes, GGUF и другие форматы.

Подключение — снова тот же OpenAI-клиент на http://localhost:8000/v1. В этом и красота: вы можете разрабатывать на Ollama, а в проде поставить vLLM, и клиентский код не изменится.

Warning:

Цена производительности vLLM — требовательность. Он рассчитан на серверные NVIDIA-GPU и Linux, куда капризнее к окружению, чем Ollama, и на слабой одиночной карте его преимущество попросту негде проявить. Для «одного пользователя дома» это из пушки по воробьям: сложнее в настройке, а выигрыша от батчинга нет, потому что батчить нечего.

Матрица выбора

Сведём всё в одну картину. Вопрос не «какой движок лучший» — правильного ответа тут нет, — а «какой под мой сценарий».

Что у вас Берите Почему
Домашний сервер, прототип, 1–2 пользователя Ollama Одна команда, ноль возни, сразу OpenAI API
Слабое/необычное железо, Mac, нужен контроль llama.cpp Максимум бэкендов, тонкое квантование, грамматики
Сервис на десятки+ параллельных запросов vLLM Батчинг и пропускная способность на серверных GPU
Не знаете, с чего начать Ollama Начните с простого; переехать на vLLM позже — это смена base_url
Important:

Главная мысль всего гайда: раз все три отдают OpenAI-совместимый API, выбор движка — обратимое решение. Начните с Ollama, упрётесь в потолок по нагрузке — перенесёте прод на vLLM, и клиентский код не заметит подмены. Не парализуйте себя выбором «на всю жизнь» на старте: меняется одна строчка с адресом.

Пара оговорок напоследок

Чтобы не оставлять ложного ощущения, что «локально = бесплатно и без компромиссов». Локальная модель уровня 7–14B заметно слабее топовых облачных — это надо принять как данность, а не бороться с этим квантованием. Электричество и амортизация железа — тоже деньги, просто размазанные и невидимые. И приватность «модель у меня» реальна только если весь ваш пайплайн локальный: подключили внешний инструмент или логирование в облако — и приватность утекла там.

При этом для множества задач (черновики, классификация, суммаризация, работа с чувствительными данными, автономность без интернета) локальный запуск — абсолютно рабочая история. Просто выбирайте движок под сценарий, а модель — под свою память, а не наоборот.

Источники

Связанное на форуме: Gemma 4 26B в 2 ГБ ОЗУ на MacBook Air и Qwen3.8-Max: открытая 27B-версия.

Question:

А вы на чём остановились для локального инференса — Ollama, llama.cpp, vLLM или что-то ещё (LM Studio, text-generation-webui)? И какая связка «модель + квантование + железо» оказалась для вас золотой серединой по скорости и качеству?