- BrainTools - https://www.braintools.ru -
llama.cpp — это низкоуровневый фреймворк с большим количеством настроек. Поднять REST API, загрузить модель и сделать первый запрос здесь так же просто, как и в Ollama, а вот набор параметров и вариаций настроек гораздо больше. Статья подготовлена по мотивам публикации Local LLM Optimization [1]. Мы подготовили полный перевод публикации, который появится в блоге позже.
Кроме llama.cpp есть еще ряд инструментов для запуска LLM, в таблице ниже разобрали несколько из них.
|
Инструмент |
Для чего лучше всего подходит |
Примечания |
|
llama.cpp |
Настройка производительности, полный контроль над флагами, любое оборудование |
Сборка из исходников; ориентирован на работу из командной строки (CLI) |
|
Ollama |
Нулевая конфигурация, управление моделями, Docker |
Внутри использует llama.cpp; ограниченные возможности тонкой настройки |
|
LM Studio |
Настольный GUI, Windows/macOS, просмотр моделей, локальный API, совместимый с OpenAI |
Хороший пользовательский интерфейс; поддерживает серверные/безголовые сценарии, JIT-загрузку, TTL и автоматическую выгрузку моделей |
|
vLLM |
Продакшн-сервинг для многих пользователей, непрерывная пакетная обработка (continuous batching) |
Разработан для работы при полном заполнении VRAM; не подходит для гибридных конфигураций на потребительском оборудовании |
|
exllamav2 |
Максимальная скорость для плотных моделей |
Только CUDA; отлично подходит для моделей, которые полностью помещаются в VRAM |
|
mlx |
Apple Silicon |
Только macOS; использует унифицированную память [2]; не поддерживает CUDA |
llama.cpp [3] — это высокопроизводительный фреймворк для запуска больших языковых моделей, написанный на C/C++. («LLM inference in C/C++»), репозиторий проекта.
Его ключевые преимущества:
Поддержка множества архитектур (LLaMA, Mistral, Qwen, Falcon и др.)
Эффективная реализация квантования (GGUF-формат)
Работа как на CPU, так и на GPU (CUDA, Metal, Vulkan)
Встроенные инструменты для бенчмаркинга и профилирования
Ряд инструментов llama.cpp по аналогии с CLI Ollama и другими фреймворками решают конкретные задачи. В нашей статье рассмотрим базовые, особенно llama-server и llama-bench.
|
Инструмент |
За что отвечает |
Когда использовать |
|
llama-server |
Запускает веб-сервер с API для обработки запросов от других приложений |
Для постоянной работы, интеграции в чат-боты и веб-сервисы |
|
llama-bench |
Измеряет скорость генерации токенов и производительность модели |
Для тестирования и сравнения моделей или настроек железа |
|
llama-fit-params |
Автоматически подбирает параметры (контекст, слои GPU) под видеопамять |
Если не знаете настройки и хотите избежать ошибки [4] Out of Memory |
|
llama-cli |
Выполняет разовый запуск: запрос → ответ → завершение работы |
Для быстрых тестов, скриптов и работы из терминала |
Для запуска нам понадобится виртуальная машина с GPU. В нашем случае мы выбрали почасовую прерванную GPU от Selectel [5].
Характеристики виртуальной машины:
8 vCPU, 32 ГБ RAM, 200 ГБ SSD
1 × RTX 4090 (24 ГБ VRAM)
Ubuntu 24.04 LTS 64-bit, GPU Driver 580 (Open)
Локация: Москва / ru-7b
После запуска сервера и перехода в терминал выполняем следующие команды:
Каждый инструмент решает задачу, поднять REST API (llama-server), провести тестирование оптимальных параметров размера контекста вход и выход (llama-bench).
Команды выполняются в терминале:
1. Скачать проект
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp
mkdir build && cd build
2. Собрать исполняемые файлы
# Указываем путь к CUDA-компилятору
export CUDACXX=/usr/local/cuda/bin/nvcc
cmake ..
-DCMAKE_BUILD_TYPE=Release
-DGGML_CUDA=ON
-DLLAMA_CURL=ON
-DGGML_CUDA_FA=ON # Flash Attention для ускорения
-DCMAKE_CUDA_ARCHITECTURES=89 # Архитектура для RTX 40xx
cmake --build . --config Release
--target llama-server llama-bench llama-cli --parallel
mkdir -p ./models
wget -O ./models/Qwen3.5-9B_Q4_k_m.gguf
"https://huggingface.co/SandLogicTechnologies/Qwen3.5-9B-GGUF/resolve/main/Qwen3.5-9B_Q4_k_m.gguf"
После того как модель скачана, запускаем HTTP-сервер для взаимодействия через API:
./bin/llama-server
-m ./models/Qwen3.5-9B_Q4_k_m.gguf
--host 0.0.0.0
--port 8089
-c 2048
-ngl 99
--jinja
|
Параметр |
Описание |
|
|
Размер контекста — длина “памяти” модели в токенах. Чем больше значение, тем длиннее диалог или документ она способна обработать. Однако это увеличивает потребление памяти и замедляет инференс. Для большинства задач хватает 4096–8192. |
|
|
Количество слоев нейросети, загружаемых в видеопамять (GPU). Остальные слои будут работать на CPU. Чтобы достичь максимальной скорости, установите значение равным общему числу слоев модели (или укажите 999). Для слабых GPU можно снизить число, чтобы часть вычислений ушла на CPU. |
|
|
Включает поддержку шаблонов Jinja для правильной разметки диалогов (токены system/user/assistant). Без этого флага модель может “не понять” структуру чата и отвечать некорректно. |
|
Параметр |
Описание |
|
|
Количество потоков CPU для вычислений. По умолчанию — все доступные ядра. Можно ограничить, чтобы не нагружать систему. |
|
|
Количество потоков для обработки батчей (промптов). Обычно меньше основного числа потоков. |
|
|
Размер батча для обработки промптов. Влияет на скорость обработки входящего запроса. |
|
|
Размер микро-батча. Меньший размер экономит память, но может снизить скорость. |
|
|
Хранить кеш контекста в формате FP32 (точнее, но требует больше памяти). По умолчанию — FP16. |
|
|
Отключить memory-mapping. Может ускорить загрузку на некоторых системах ценой увеличения RAM. |
|
|
Включить оптимизацию для NUMA-систем (многопроцессорные конфигурации). |
|
|
Количество параллельных запросов, которые сервер может обрабатывать одновременно. |
|
|
Метод масштабирования RoPE (для контекстов длиннее, чем обучалась модель). Варианты: |
|
|
Коэффициент масштабирования частот RoPE (обычно < 1 для длинных контекстов). |
|
|
Формат логов: |
|
|
Включить сбор метрик производительности. |
|
|
Использовать Flash Attention (ускоряет обработку длинных контекстов, требует поддержки GPU). |
После того как мы подняли LLM API, наши сервисы готовы отправлять на него запросы. llama-server предоставляет два основных эндпоинта:
Поддерживает структурированные диалоги с разделением ролей (system/user/assistant):
curl http://0.0.0.0:8089/v1/chat/completions
-H "Content-Type: application/json"
-d '{
"model": "qwen3.5-9b",
"messages": [
{"role": "system", "content": "Ты — эксперт по ИИ. Отвечай кратко и понятно."},
{"role": "user", "content": "Объясни, что такое квантование модели, простыми словами."}
],
"temperature": 0.7,
"max_tokens": 300,
"stream": false
}'
curl http://0.0.0.0:8089/completion
-H "Content-Type: application/json"
-d '{
"model": "qwen3.5-9b",
"prompt": "Hello world, generate the world!",
"temperature": 0.7,
"max_tokens": 300,
"stream": false
}'
Выбор эндпоинта: первый подходит для полноценных чат-интерфейсов, второй — для быстрых одноразовых запросов.
Воспользуемся llama-bench, чтобы подобрать оптимальный размер батча. В цикле прогоняем модель с разными значениями -ub (micro-batch size):
for ub in 128 256 512 1024; do
./bin/llama-bench
-m ./models/Qwen3.5-9B_Q4_k_m.gguf
-p 2048 -n 128
-b 1024 -ub "$ub"
-ngl 99
-ctk q8_0 -ctv q8_0
-fa on
done
|
Параметр |
Значение |
Что означает |
|
|
|
Путь к модели (Qwen 3.5, 2B параметров, квантизация Q4_K_M) |
|
|
2048 |
Prompt tokens — длина входного промта (сколько токенов подается на вход) |
|
|
128 |
Generated tokens — сколько новых токенов модель должна сгенерировать |
|
|
1024 |
Batch size для обработки промта (фиксирован) |
|
|
128/256/512/1024 |
Micro-batch size для генерации — меняется в цикле |
|
|
99 |
Количество слоев в GPU (99 = все слои, так как их меньше) |
|
|
q8_0 |
Квантизация кэша для ключей (8-бит) |
|
|
q8_0 |
Квантизация кэша для значений (8-бит) |
|
|
on |
Flash Attention включена (экономит память и ускоряет) |
|
Метрика |
Описание |
|
pp2048 (Prefill) |
Обработка входящего промта длиной 2048 токенов. Модель “читает” и анализирует ваш запрос — скорость обработки промта (вход) |
|
tg128 (Token Generation) |
Генерация ответа (128 новых токенов). Модель “пишет” ответ по одному токену за раз — скорость генерации (выход) |
В нашем примере цель — показать базовую логику [6] применения текстовой модели для компании, в дальнейшем можно обернуть это в агента и так же запустить в контуре компании.
Важно отметить, что при этой реализации, данные остаются во внутреннем контуре и личная информация по задачам и доступам остается в компании.
Реализуем следующую логику:
Ввод
Есть ли базовые параметры в задаче
Если есть, то оформить в .md
Если нет, то указать, чего нет
Примеры задач, которые можно направить для обработки текстовой модели:
Собрать фичу — нужно смержить ветку feature/new-dashboard в дев. Там новый график аналитики, проверьте, чтобы все подтягивалось.
Допилить задачку по другой задаче — @Петр, ты вчера фиксил баг с экспортом отчетов? Там остался косяк с кодировкой CSV, посмотри, пожалуйста, сегодня.
Фикс — @Анна, упал тест на продакшне по авторизации, глянь в логах, похоже на таймаут.
Тестирование — после всех правок прогоняем регресс по модулю оплаты, я выкачу билд к 16:00.
import requests
url = "http://0.0.0.0:8089/completion"
# bad
msg_from_telegram = """
Нужно смержить ветку feature/new-dashboard в дев.
Там новый график аналитики, проверьте, чтобы все подтягивалось.
"""
# ok
msg_from_telegram = """
Нужно смержить ветку feature/new-dashboard в дев.
Там новый график аналитики, проверьте, чтобы все подтягивалось.
Василий (+79876543210) отвечает за задачу
Сроки ASAP в понедельник 1 августа 2026
"""
prompt = f"""
Extract task params from input
- name
- deadline
- author
if prams exists format task, if not exists return comment no param in text
Input: {msg_from_telegram}
Return ONLY markdown, no explanations, by Russian language
Output format:
markdown
# name
description
- author
- deadline
"""
payload = {
"model": "qwen3.5-9b",
"prompt": prompt,
"temperature": 0.5,
"max_tokens": 200,
"stream": False,
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
if response.status_code == 200:
result = response.json()
print(response)
print(result['content'])
else:
print(f"Error: {response.text}")
llama.cpp предоставляет мощный инструментарий для запуска LLM на локальном оборудовании с полным контролем над производительностью. В ходе работы мы:
Собрали фреймворк с поддержкой CUDA и Flash Attention
Развернули REST API с моделью Qwen3.5-9B
Провели бенчмаркинг для подбора оптимальных параметров (-ub, -ngl)
Интегрировали модель в бизнес-задачу по извлечению параметров
Дальнейшие шаги: обертка в агента с автономным выполнением задач и интеграция в CI/CD пайплайны компании.
А вы уже пробовали самостоятельно запускать LLM-модель для локального контура? Какими фреймворками пользовались?
Автор: MaDeLa
Источник [7]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/32936
URLs in this post:
[1] Local LLM Optimization: https://carteakey.dev/blog/local-inference/local-llm-optimization/
[2] память: http://www.braintools.ru/article/4140
[3] llama.cpp: https://github.com/ggml-org/llama.cpp
[4] ошибки: http://www.braintools.ru/article/4192
[5] Selectel: https://selectel.ru/services/cloud/servers/gpu/
[6] логику: http://www.braintools.ru/article/7640
[7] Источник: https://habr.com/ru/articles/1057528/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1057528
Нажмите здесь для печати.