Перейти к содержанию
Публикация AiManual

llama.cpp: как один разработчик сделал большие языковые модели доступными на обычном CPU

llama.cpp запускает LLM на обычном CPU — без GPU и облачных сервисов. Разбираем, как собрать и запустить llama-cli и llama-server, какие кванты (Q4_0, Q4_K_M, Q

Коротко

Что будет в материале

  1. 01

    Что такое llama.cpp и почему это важно

  2. 02

    История создания: от идеи до сообщества

  3. 03

    Технические основы: как llama.cpp достигает эффективности на CPU

  4. 04

    Как запустить llama.cpp: минимальный пример

Что такое llama.cpp и почему это важно

Коротко: llama.cpp — библиотека с открытым исходным кодом на C/C++ для инференса больших языковых моделей (LLM) на обычном CPU, без GPU и облачных сервисов. Модель на 7B, которая в FP16 занимает около 13 ГБ, в 4-битном квантовании ужимается примерно до 4 ГБ — этого достаточно, чтобы запустить её на машине с 8 ГБ оперативной памяти.

Создал проект Георгий Герганов в марте 2023 года после утечки весов LLaMA. До llama.cpp запуск моделей уровня 7B требовал видеокарты с 16–24 ГБ памяти. Библиотека снизила порог входа: LLaMA 7B заработала на ноутбуке с 8 ГБ оперативной памяти.

Зачем это нужно разработчику? Локальный инференс решает три задачи: конфиденциальность данных, отсутствие абонентской платы за API и независимость от облачных провайдеров. llama.cpp стала катализатором для целой волны локальных AI-приложений - от чат-ботов до офлайн-переводчиков. Проект показал, что CPU-инференс может быть практичным, если правильно работать с памятью и точностью вычислений.

Для тех, кто уже использует llama.cpp в продакшене, полезно посмотреть LLaMA.cpp Windows Manager - инструмент для визуального управления запущенными моделями на Windows с профилями запуска и OpenAI-совместимым API.

История создания: от идеи до сообщества

Мотивация: запустить LLaMA на MacBook

Георгий Герганов хотел запустить LLaMA на своём MacBook M1 без внешнего GPU. Существовавшие на тот момент решения требовали мощных видеокарт и сложной настройки CUDA. Он начал писать код на C++ для эффективного использования CPU: минимум зависимостей, прямой контроль над памятью, поддержка SIMD-инструкций Apple Silicon.

Техническая задача была конкретной: уместить модель 7B в ограниченную оперативную память MacBook и получить приемлемую скорость генерации. Решение пришло через квантование весов - снижение точности с 16 бит до 4 бит. Это уменьшало размер модели в 3–4 раза без катастрофической потери качества.

Первые результаты и реакция сообщества

Уже через несколько недель проект набрал тысячи звёзд на GitHub. Разработчики увидели, что локальный запуск LLM перестал быть привилегией владельцев GPU-кластеров. Появились форки, контрибьюторы и первые обёртки. Сообщество быстро сформировалось вокруг идеи доступного инференса: люди делились бенчмарками, добавляли поддержку новых архитектур и оптимизировали код под разные платформы.

llama.cpp стал ответом на запрос сообщества: простой, быстрый, без лишних зависимостей инструмент, который работает на том железе, что уже есть у разработчика. Команда проекта продолжает развивать его - например, вышло нативное macOS-приложение llama.app с управлением моделями из строки меню и автоматическим запуском API-сервера.

Технические основы: как llama.cpp достигает эффективности на CPU

Квантование: уменьшаем размер модели без значительной потери качества

Квантование - это процесс снижения точности весов модели. Стандартные веса LLM хранятся в 16-битном формате (FP16). llama.cpp позволяет конвертировать их в 4-битные или 5-битные целочисленные представления. Модель 7B в FP16 занимает около 13 ГБ, а в 4-битном квантовании - примерно 4 ГБ. Вычисления с целыми числами выполняются быстрее на CPU, а меньший объём данных снижает нагрузку на подсистему памяти.

В llama.cpp реализованы несколько методов квантования: Q4_0, Q4_1, Q5_0, Q5_1, Q8_0 и другие. Они отличаются балансом между размером, скоростью и качеством. Q4_0 - самый быстрый и компактный, Q5_1 даёт чуть лучшее качество ценой большего размера. Выбор метода зависит от задачи: для черновиков и быстрых ответов хватит Q4_0, для точных ответов на сложные вопросы лучше Q5_1 или Q8_0.

Отдельно стоит семейство K-квантов (Q4_K_M, Q5_K_M и другие): схема кодирования там аккуратнее, и при близком размере файла они обычно дают лучший баланс качества и объёма, чем «старые» Q4_0 и Q5_0. Именно поэтому Q4_K_M и Q5_K_M так часто оказываются значениями по умолчанию в готовых GGUF-сборках.

КвантПримерный размер модели 7BОриентир по качествуТипичный сценарий
Q4_0~4 ГББазовое, потери заметны на сложных задачахСлабое железо, черновики, быстрые ответы
Q4_K_M~4,4 ГБЗаметно лучше Q4_0 при близком размереРабочий дефолт, когда памяти 8–16 ГБ
Q5_K_M~5,3 ГБЕщё аккуратнее, если памяти хватаетЗадачи, где важна точность ответа
Q8_0~7,2 ГББлизко к FP16Точные задачи при достаточном объёме памяти

Размеры округлены и приведены для моделей класса 7B: фактический объём GGUF-файла зависит от архитектуры, словаря и версии конвертера. Это ориентиры для выбора кванта, а не результаты замеров — качество и скорость на конкретной модели и железе могут отличаться.

Квантование SmoothQuant, о котором мы писали ранее, решает проблему выбросов в активациях и позволяет сжимать модели до 8-битных представлений без значительной потери качества - это смежный подход, который также работает на CPU-инфраструктуре.

Оптимизация вычислений: SIMD, многопоточность и эффективное использование кэша

llama.cpp использует SIMD-инструкции процессора для параллельной обработки данных. На x86 это AVX2 и AVX-512, на ARM - NEON. Эти инструкции позволяют выполнять несколько операций за один такт, что критично для матричных умножений в трансформере.

Многопоточность распределяет нагрузку по ядрам CPU. Библиотека разбивает вычисления на независимые блоки и обрабатывает их параллельно. Эффективное использование кэша уменьшает задержки при доступе к весам модели: данные, к которым часто обращаются, держатся в быстрой памяти процессора.

Отдельный пример - Project Zero, CPU-only движок инференса LLM на чистом C99, который достигает 36.25 токен/с на Intel Xeon и обходит bitnet.cpp в 1.8 раза. Это показывает, насколько далеко можно продвинуть CPU-оптимизацию, если писать код без лишних абстракций.

Форматы GGML и GGUF: эволюция хранения моделей

GGML - исходный формат файлов для llama.cpp. Он хранил квантованные веса и параметры модели в бинарном виде. Со временем формат стал узким местом: не хватало метаданных, сложно было добавлять новые архитектуры, не было обратной совместимости.

GGUF заменил GGML. Новый формат более гибкий: поддерживает метаданные, версионирование и обратную совместимость. Конвертация моделей из PyTorch в GGUF выполняется скриптами из репозитория llama.cpp. Большинство современных моделей на Hugging Face уже доступны в GGUF - это стандарт де-факто для локального инференса.

Как запустить llama.cpp: минимальный пример

Схема простая: собираем библиотеку из исходников, берём готовую модель в GGUF (или конвертируем свою) и запускаем её либо через llama-cli для быстрой проверки, либо через llama-server, если модель нужна приложению. Конкретные версии здесь не важны — ниже минимальный набор команд.

Сборка. Исходники лежат в репозитории llama.cpp на GitHub; предполагается, что вы уже склонировали его и находитесь в его каталоге:

cmake -B build
cmake --build build --config Release -j

Запуск модели в консоли — llama-cli:

./build/bin/llama-cli -m models/model.gguf -p "Объясни, что такое квантование" -n 256 -t 8

Флаги здесь минимальные: -m — путь к GGUF-файлу, -p — промпт, -n — число генерируемых токенов, -t — количество потоков CPU. По потокам есть практическое правило: обычно имеет смысл ориентироваться на число физических ядер, а не на число логических.

Если модель нужна не вам в терминале, а приложению, поднимаем llama-server — он отдаёт HTTP-сервер с OpenAI-совместимым эндпоинтом /v1/chat/completions:

./build/bin/llama-server -m models/model.gguf --host 127.0.0.1 --port 8080 -c 4096 -t 8

Флаг -c задаёт размер контекста: чем он больше, тем больше памяти уходит на KV-кэш, поэтому на слабом железе значение стоит подбирать, а не выставлять «на максимум». Так как API совместим с OpenAI, к серверу подойдут любые клиенты, умеющие работать с кастомным base URL.

Наборы флагов и имена бинарников в llama.cpp периодически меняются, поэтому перед запуском стоит сверяться с README в репозитории — команды выше показывают логику, а не зафиксированный навсегда синтаксис.

Производительность и ограничения llama.cpp

Скорость генерации на разных процессорах

Дальше — ориентировочные цифры, которые встречаются в отчётах пользователей. Это не результаты замеров редакции, а порядок величин: реальная скорость зависит от модели, кванта, числа потоков и пропускной способности памяти, и на разных CPU она может отличаться в разы.

Типичные ориентиры такие: Apple M1 Max с моделью LLaMA 7B в Q4 — порядка 10 токенов в секунду; Ryzen 9 с AVX2 — около 15 токенов/с; RTX 3090 на той же модели — около 50 токенов/с. Разрыв с GPU существенный, но для многих задач скорости CPU достаточно.

Более крупные модели работают медленнее. LLaMA 13B в Q4 на M1 Max даёт порядка 5–6 токенов/с, а 70B требует уже около 40 ГБ оперативной памяти и выдаёт единицы токенов в секунду даже на мощном CPU. Это граница практической применимости: 70B на CPU - это скорее эксперимент, чем рабочий инструмент.

Ограничения: что llama.cpp не может

llama.cpp не поддерживает обучение моделей - только инференс. Нет распределённого инференса: нельзя размазать модель по нескольким машинам. Поддержка некоторых архитектур ограничена: Mamba и другие не-трансформерные модели появляются с задержкой или не появляются вовсе.

Кому стоит смотреть в другую сторону:

  • Интерактивные приложения с жёстким SLA по задержке. Скорость генерации на CPU ниже, чем на GPU, и время ответа хуже — для чата с жёстким лимитом это критично.
  • Обучение и файнтюнинг. Библиотека умеет только инференс; для дообучения нужны другие инструменты.
  • Мультимашинный инференс. Штатно размазать одну модель по нескольким узлам по сети не получится.
  • Модели 70B+ на обычных ноутбуках. В 4-битном квантовании им нужно порядка 40 ГБ оперативной памяти — на портативной машине такой запуск не укладывается в разумные рамки.

Если вы сравниваете интерфейсы для локальных LLM, посмотрите обзор llama-server, Open WebUI и SillyTavern - там разобраны API, потребление ресурсов и практические примеры на Python.

Экосистема llama.cpp: интеграции и практическое применение

Популярные обертки и приложения

Ollama - простой CLI для запуска моделей одной командой. Он автоматически скачивает GGUF-файлы, управляет версиями и предоставляет REST API. LM Studio - графический интерфейс для Windows, macOS и Linux: выбор модели, настройка параметров, чат-интерфейс. llama-cpp-python - Python-биндинги для интеграции llama.cpp в свои проекты: от скриптов до веб-сервисов.

text-generation-webui - веб-интерфейс с поддержкой множества бэкендов, включая llama.cpp. Он удобен для экспериментов: переключение моделей, параметров генерации, режимов работы. Каждый инструмент решает свою задачу: Ollama для быстрого старта, LM Studio для визуальной работы, llama-cpp-python для программистов.

Примеры использования в реальных проектах

Локальные чат-боты для конфиденциальных данных - медицинские записи, юридические документы, внутренняя переписка - работают без отправки данных в облако. Офлайн-помощники на устройствах без стабильного интернета: полевые заметки, бортовые системы, изолированные среды. Встраивание в мобильные приложения через llama.cpp на Android: модель работает прямо на телефоне, без сервера.

Практические сценарии использования локальных LLM мы разбирали в отдельной статье - от медицинского анализа до персонального тьютора с реальными кейсами сообщества.

Сравнение с альтернативами: когда выбирать llama.cpp

llama.cpp против GPU-инференса

llama.cpp работает на любом современном CPU, бесплатен и не требует специального оборудования. Минус - скорость ниже, чем на GPU. GPU-инференс через PyTorch или vLLM быстрее в 3–10 раз, но требует видеокарту с большим объёмом памяти и настройку CUDA.

Выбор зависит от задачи. Для прототипирования, офлайн-приложений и работы с конфиденциальными данными llama.cpp на CPU - практичное решение. Для продакшена с высокой нагрузкой и жёсткими требованиями к задержке GPU-инференс оправдан, несмотря на стоимость.

llama.cpp против облачных API

Локальный запуск через llama.cpp даёт полный контроль над моделью, конфиденциальность данных и отсутствие абонентской платы. Минус - нужно поддерживать инфраструктуру: обновлять модель, следить за производительностью, решать проблемы совместимости.

Облачные API вроде OpenAI или Anthropic проще в использовании и масштабировании, но создают зависимость от провайдера и требуют оплаты за каждый запрос. Для долгосрочных проектов с предсказуемой нагрузкой локальный инференс часто выгоднее.

Если вы ищете CPU-only решение с максимальной производительностью, обратите внимание на Project Zero - движок на чистом C99 с производительностью 36.25 токен/с на Intel Xeon и поддержкой BitNet и Bonsai-27B.

Заключение: влияние llama.cpp на индустрию и будущее локального инференса

llama.cpp демократизировал доступ к большим языковым моделям. Запуск LLM на обычном ноутбуке перестал быть техническим подвигом и стал рутинной задачей. Это стимулировало развитие локальных AI-приложений: чат-боты, ассистенты, офлайн-переводчики, инструменты для работы с документами.

Проект снизил зависимость от облачных сервисов и показал, что CPU-инференс может быть практичным при грамотной оптимизации. Будущее llama.cpp - дальнейшая оптимизация вычислений, поддержка новых архитектур и улучшение инструментов для разработчиков. Локальный инференс продолжит развиваться, и llama.cpp останется одним из ключевых инструментов этого направления.

Что читать дальше

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