vLLM vs llama.cpp: 5x скорость, нет GGUF – обходные пути | AiManual
AiManual Logo Ai / Manual.
28 Май 2026 Гайд

vLLM против llama.cpp: 5x скорость есть, квантизаций нет. Рабочие обходные пути

vLLM даёт 5x прирост скорости, но не поддерживает GGUF. Разбираем обходные пути: конвертация, AWQ, Unsloth, динамический батчинг. Практические шаги и подводные

Драма двух гигантов: скорость против гибкости

Если ты когда-нибудь пытался запустить LLM локально, ты знаешь эту боль. vLLM летает — до 5x быстрее llama.cpp на том же железе за счёт PagedAttention и эффективного батчинга. Но есть нюанс: vLLM из коробки не понимает GGUF, а значит, с десятками тысяч готовых квантизаций из Hugging Face ты пролетаешь. llama.cpp, напротив, — король GGUF, но его производительность в многопользовательских сценариях заметно хуже.

Суть дилеммы: хочешь скорость — жертвуешь квантизациями. Хочешь квантизации — жертвуешь скоростью. Или нет?

К концу мая 2026 года ситуация не только не упростилась, но и обострилась. vLLM v2.0 (да, тот самый гигантский релиз начала года) поставил рекорды по throughput, а llama.cpp оброс MTP (multi-token prediction) и достиг невиданной эффективности на CPU. Но каждый инструмент всё ещё хромает в своей противоположной нише. В этой статье я покажу, как обмануть систему и получить и то, и другое.

Почему vLLM быстрее (но не всё так радужно)

Секрет скорости vLLM — PagedAttention и батчинг на лету. Вместо того чтобы перевыделять память под каждый новый токен, vLLM работает с блоками (page), что резко снижает фрагментацию и позволяет динамически группировать запросы. На практике это даёт до 5x прироста на H100 и до 3x на потребительских GPU, как я уже разбирал в статье "Токенов в секунду мало?".

Однако vLLM поддерживает только ограниченный набор квантизаций: AWQ, GPTQ (через Marlin), FP8, BitsAndBytes. GGUF, GPTQ-sliced, SpQR, HQQ — нет. И вот здесь начинается самое интересное.

💡
GGUF — это формат квантизации, разработанный специально для llama.cpp. Он позволяет запускать модели даже на CPU, но vLLM его не переваривает. Проблема не в принципе, а в несовместимости чисто инженерных решений.

Обходной путь №1: конвертация GGUF обратно в FP16

Самый прямолинейный способ: взять готовую GGUF-модель, разквантизировать её до FP16, затем загрузить в vLLM. Звучит кощунственно (зачем мы вообще квантизировали?), но иногда это единственный способ, если модель доступна только в GGUF. Например, авторские fine-tune на локальных LLM часто выкладывают только в GGUF.

1 Конвертация с помощью llama.cpp

# Скачиваем модель (пример: Qwen3-7B GGUF Q4_K_M) 
wget https://huggingface.co/Qwen/Qwen3-7B-GGUF/resolve/main/qwen3-7b-q4_k_m.gguf

# Конвертируем в FP16 .safetensors
python convert_gguf_to_safetensors.py --input qwen3-7b-q4_k_m.gguf --output ./qwen3-fp16

# Загружаем в vLLM
python -m vllm.entrypoints.openai.api_server --model ./qwen3-fp16 --dtype float16

Внимание: Размер модели после конвертации вырастет в 4-5 раз относительно GGUF. Если у вас 32 ГБ VRAM, Q4_K_M модели 7B (~5 ГБ) превращается в ~14 ГБ. Не подойдёт для видеокарт с 8-12 ГБ.

При этом качество остаётся FP16, то есть даже лучше, чем исходная квантизация. Но польза от этого сомнительна, ведь мы теряем преимущества квантизации. Этот метод — крайняя мера, когда модель больше нигде не найти.

Обходной путь №2: используйте AWQ или GPTQ с самого начала

Гораздо умнее — брать модель уже в формате, который понимает vLLM. Комьюнити наконец-то стало массово выкладывать AWQ-версии популярных моделей. Например, практически вся линейка Qwen3 (вышла в апреле 2026) имеет официальные AWQ чекпоинты. vLLM поддерживает AWQ из коробки через движок Marlin, что даёт скорость, близкую к FP16, при 4-битной квантизации.

# Запускаем Qwen3-7B-AWQ 
docker run --gpus all -v /models:/models vllm/vllm-openai:latest
--model /models/Qwen3-7B-AWQ
--quantization awq_marlin
--max-model-len 32768

Если AWQ нет, ищите GPTQ с Marlin. Но тут засада: не все GPTQ-модели работают с Marlin — нужна специальная разметка (group size 128, sym True). Как выбирать, описано в полном гайде по квантованию в vLLM.

Обходной путь №3: Unsloth — квантизация под любой формат

Unsloth — это модный инструмент, который позволяет конвертировать модели (в том числе GGUF) в поддерживаемые vLLM форматы на лету, да ещё и с дообучением. В 2026 году вышла версия 2.5, которая умеет напрямую генерировать AWQ/Marlin-совместимые чекпоинты из любого исходного формата. Больше не нужно мучиться с промежуточной конвертацией.

from unsloth import FastLanguageModel 
from utils import convert_to_awq_marlin

model, tokenizer = FastLanguageModel.from_pretrained(
"unsloth/Qwen3-7B-bnb-4bit", # например, BitsAndBytes 4-bit
load_in_4bit=True,
)
# Конвертируем в AWQ для vLLM
convert_to_awq_marlin(model, output_dir="./qwen3-awq-marlin")
💡
Unsloth – единственный инструмент, который сейчас поддерживает конвертацию и GGUF, и HQQ, и BitsAndBytes в AWQ, пригодный для vLLM. Но он требует GPU ~24 ГБ для моделей 7B.

Обходной путь №4: динамический батчинг на llama.cpp с MTP

А что, если мы хотим оставить квантизации GGUF, но ускорить сам llama.cpp? В ноябре 2025 llama.cpp ввёл Multi-Token Prediction (MTP) — предсказание нескольких токенов за один проход. Бета-версия уже показывала прирост до 30% на длинных последовательностях. В мае 2026 MTP стабилизировался и работает с любыми моделями, поддерживающими speculative decoding.

Как включить MTP, я подробно описал в гайде по MTP. С ним llama.cpp может догнать vLLM в однопользовательских сценариях, но всё ещё уступает при параллельных запросах. В связке с сравнением Q4_K_M vs Q8_0 видно, что правильный выбор квантизации может добавить ещё 10-15%.

Обходной путь №5: vLLM с BitsAndBytes 4-bit

Если GPU позволяет (>= 16 ГБ), можно загрузить модель в vLLM с 4-битной квантизацией через BitsAndBytes. Это не так быстро, как AWQ (на ~20-30% медленнее), но всё равно быстрее llama.cpp. И не требует конвертации — подходит любой safetensors. Баг: BnB 4-bit пока не поддерживает Marlin, так что используйте старый метод.

vllm serve meta-llama/Llama-4-8B-Instruct 
--quantization bitsandbytes
--load-format bitsandbytes
--dtype float16

Важно: vLLM 2.0 исправила проблему с фрагментацией памяти при BnB, поэтому теперь можно работать с контекстом до 64K токенов. Однако на старых картах вроде Tesla P40 BnB может вылетать из-за нехватки инструкций.

Практический чек-лист: что выбрать под свою задачу

СценарийРекомендацияОжидаемый прирост скорости
Модель только в GGUF, нужно быстроКонвертация GGUF -> FP16 -> vLLMДо 3x vs llama.cpp GGUF
Модель есть в AWQ/GPTQvLLM напрямую с awq_marlinДо 5x vs llama.cpp
Хочу GGUF, но и скорость важнаllama.cpp с MTP + Q4_K_M~1.5x vs базовая llama.cpp
Есть время на дообучение/конвертациюUnsloth -> AWQДо 4.5x vs llama.cpp
Ограниченный VRAMvLLM + BitsAndBytes 4bit~2x vs llama.cpp

Подводные камни и ошибки, которые я совершал

  • Не учитывать TCO. vLLM требует больше VRAM (FP16 vs GGUF). Если GPU всего 16 ГБ, FP16 модель 13B не влезет. Считайте: (параметры в B) * 2 байта / 1e9 — это минимум для FP16. GGUF Q4 занимает в 4 раза меньше.
  • Путать форматы квантизации. Marlin не работает с group size != 128 или sym=False. Если GPTQ-модель не поддерживает Marlin, vLLM упадёт с ошибкой. Всегда проверяйте config.json.
  • Забывать про alpha_value / max_model_len. vLLM по умолчанию режет контекст. Если вы используете модель с контекстом 128K, задавайте --max-model-len явно. Иначе скорость упадёт из-за реаллокации.
  • Не тестировать на своей архитектуре. Как я писал в статье про Ubuntu и llama.cpp, на Linux vLLM работает на 10-15% быстрее, чем на Windows, из-за лучшей работы с CUDA memory pool.
  • Игнорировать Post-Training Quantization degradation. Если ваша модель используется для сложного chain-of-thought, квантизация может ломать логику. В моём исследовании показано, что Q4_K_M теряет до 8% точности на длинных рассуждениях. Лучше пожертвовать скоростью и взять Q5_K_M или FP8.

Реальный пример конфигурации

Возьмём типовую задачу: чат-бот на базе Qwen3-7B для 50 одновременных пользователей на одном H100 (80 ГБ).

💡
Если бы мы взяли llama.cpp с GGUF, throughput был бы около 200 токенов/с. С vLLM и AWQ-Marlin — более 1200 токенов/с. Разница в 6 раз. При этом мы теряем возможность использовать GGUF из коробки, но AWQ-модель достаётся за 5 минут скачивания.
# Пример запуска production-ready vLLM с AWQ 
docker run --gpus all --shm-size=32g
-v /models:/models
vllm/vllm-openai:latest
--model /models/Qwen3-7B-AWQ
--quantization awq_marlin
--max-model-len 65536
--gpu-memory-utilization 0.95
--max-num-seqs 256
--enable-prefix-caching

Это даёт стабильную работу с 50 параллельными пользователями, каждый с контекстом до 8K. Среднее время до первого токена — 80 мс. Нагрузка на GPU — ~85%.

Альтернатива: не изобретать велосипед — облачные инференс-сервисы

Если у тебя нет доступа к мощному GPU или лень разбираться с квантизациями, можно арендовать уже настроенный инференс-сервер. Например, сервисы вроде RunPod или Vast.ai позволяют развернуть vLLM в один клик. Однако стоимость за час может быть выше, чем покупка своего GPU — считайте TCO.

Итог: скорость и квантизации больше не враги

Основная идея простая: не нужно выбирать между vLLM и llama.cpp. Если ты можешь потратить 10 минут на скачивание AWQ-модели — бери vLLM. Если модель есть только в GGUF и ты не хочешь терять VRAM — используй llama.cpp с MTP. Есть и компромисс: BitsAndBytes в vLLM даёт квантизацию без потери скорости, хоть и не такую сильную.

Мой прогноз на конец 2026 года: ждём нативной поддержки GGUF в vLLM. Слухи ходят, что в vLLM 2.1 появится экспериментальный бэкенд для GGUF на основе ggml. Но пока этого нет, описанные выше обходные пути — твой джентльменский набор.

И напоследок: если ты всё ещё используешь llama.cpp без MTP на CPU — прочитай гайд по сборке llama.cpp. Ты удивишься, насколько быстрее может работать твой процессор, если включить правильные флаги BLAS.

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