- BrainTools - https://www.braintools.ru -

Запуск и оптимизация локальной LLM с llama.cpp

Автор статьи - Даниил Г., Python-разработчик

Автор статьи – Даниил Г., Python-разработчик

Вступление

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

Логотип фреймворка

Логотип фреймворка

llama.cpp [3] — это высокопроизводительный фреймворк для запуска больших языковых моделей, написанный на C/C++. («LLM inference in C/C++»), репозиторий проекта.

Его ключевые преимущества:

  • Поддержка множества архитектур (LLaMA, Mistral, Qwen, Falcon и др.)

  • Эффективная реализация квантования (GGUF-формат)

  • Работа как на CPU, так и на GPU (CUDA, Metal, Vulkan)

  • Встроенные инструменты для бенчмаркинга и профилирования

Инструменты llama.cpp

Ряд инструментов llama.cpp по аналогии с CLI Ollama и другими фреймворками решают конкретные задачи. В нашей статье рассмотрим базовые, особенно llama-server и llama-bench.

Инструмент

За что отвечает

Когда использовать

llama-server

Запускает веб-сервер с API для обработки запросов от других приложений

Для постоянной работы, интеграции в чат-боты и веб-сервисы

llama-bench

Измеряет скорость генерации токенов и производительность модели

Для тестирования и сравнения моделей или настроек железа

llama-fit-params

Автоматически подбирает параметры (контекст, слои GPU) под видеопамять

Если не знаете настройки и хотите избежать ошибки [4] Out of Memory

llama-cli

Выполняет разовый запуск: запрос → ответ → завершение работы

Для быстрых тестов, скриптов и работы из терминала


Сборка llama.cpp

Для запуска нам понадобится виртуальная машина с 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

После запуска сервера и перехода в терминал выполняем следующие команды:

Шаг 1. Сборка llama-server, llama-bench и llama-cli

Каждый инструмент решает задачу, поднять 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

Шаг 2. Скачивание LLM-модели (Qwen3.5-9B_Q4_k_m.gguf)

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"

Запуск llama-server (REST API)

После того как модель скачана, запускаем 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

Разбор ключевых параметров

Параметр

Описание

-c (--ctx-size)

Размер контекста — длина “памяти” модели в токенах. Чем больше значение, тем длиннее диалог или документ она способна обработать. Однако это увеличивает потребление памяти и замедляет инференс. Для большинства задач хватает 4096–8192.

-ngl (--n-gpu-layers)

Количество слоев нейросети, загружаемых в видеопамять (GPU). Остальные слои будут работать на CPU. Чтобы достичь максимальной скорости, установите значение равным общему числу слоев модели (или укажите 999). Для слабых GPU можно снизить число, чтобы часть вычислений ушла на CPU.

--jinja

Включает поддержку шаблонов Jinja для правильной разметки диалогов (токены system/user/assistant). Без этого флага модель может “не понять” структуру чата и отвечать некорректно.

Дополнительные параметры для тонкой настройки

Параметр

Описание

-t (--threads)

Количество потоков CPU для вычислений. По умолчанию — все доступные ядра. Можно ограничить, чтобы не нагружать систему.

-tb (--threads-batch)

Количество потоков для обработки батчей (промптов). Обычно меньше основного числа потоков.

-b (--batch-size)

Размер батча для обработки промптов. Влияет на скорость обработки входящего запроса.

-ub (--ubatch-size)

Размер микро-батча. Меньший размер экономит память, но может снизить скорость.

--memory-f32

Хранить кеш контекста в формате FP32 (точнее, но требует больше памяти). По умолчанию — FP16.

--no-mmap

Отключить memory-mapping. Может ускорить загрузку на некоторых системах ценой увеличения RAM.

--numa

Включить оптимизацию для NUMA-систем (многопроцессорные конфигурации).

-np (--parallel)

Количество параллельных запросов, которые сервер может обрабатывать одновременно.

--rope-scaling

Метод масштабирования RoPE (для контекстов длиннее, чем обучалась модель). Варианты: linear, yarn.

--rope-freq-scale

Коэффициент масштабирования частот RoPE (обычно < 1 для длинных контекстов).

--log-format

Формат логов: text, json или none.

--metrics

Включить сбор метрик производительности.

-fa (--flash-attn)

Использовать Flash Attention (ускоряет обработку длинных контекстов, требует поддержки GPU).

Запрос к модели

После того как мы подняли LLM API, наши сервисы готовы отправлять на него запросы. llama-server предоставляет два основных эндпоинта:

1. /v1/chat/completions — совместимый с OpenAI API

Поддерживает структурированные диалоги с разделением ролей (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
  }'

2. /completion — запрос для генерации

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

Воспользуемся 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

Что означают параметры

Параметр

Значение

Что означает

-m

./models/Qwen3.5-9B_Q4_k_m.gguf

Путь к модели (Qwen 3.5, 2B параметров, квантизация Q4_K_M)

-p 2048

2048

Prompt tokens — длина входного промта (сколько токенов подается на вход)

-n 128

128

Generated tokens — сколько новых токенов модель должна сгенерировать

-b 1024

1024

Batch size для обработки промта (фиксирован)

-ub "$ub"

128/256/512/1024

Micro-batch size для генерации — меняется в цикле

-ngl 99

99

Количество слоев в GPU (99 = все слои, так как их меньше)

-ctk q8_0

q8_0

Квантизация кэша для ключей (8-бит)

-ctv q8_0

q8_0

Квантизация кэша для значений (8-бит)

-fa on

on

Flash Attention включена (экономит память и ускоряет)

Что измеряет llama-bench

Метрика

Описание

pp2048 (Prefill)

Обработка входящего промта длиной 2048 токенов. Модель “читает” и анализирует ваш запрос — скорость обработки промта (вход)

tg128 (Token Generation)

Генерация ответа (128 новых токенов). Модель “пишет” ответ по одному токену за раз — скорость генерации (выход)


Пример использования на задаче компании

В нашем примере цель — показать базовую логику [6] применения текстовой модели для компании, в дальнейшем можно обернуть это в агента и так же запустить в контуре компании.

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

Реализуем следующую логику:

  1. Ввод

  2. Есть ли базовые параметры в задаче

    1. Если есть, то оформить в .md

    2. Если нет, то указать, чего нет

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

  • Собрать фичу — нужно смержить ветку 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 на локальном оборудовании с полным контролем над производительностью. В ходе работы мы:

  1. Собрали фреймворк с поддержкой CUDA и Flash Attention

  2. Развернули REST API с моделью Qwen3.5-9B

  3. Провели бенчмаркинг для подбора оптимальных параметров (-ub, -ngl)

  4. Интегрировали модель в бизнес-задачу по извлечению параметров

Дальнейшие шаги: обертка в агента с автономным выполнением задач и интеграция в 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

www.BrainTools.ru

Rambler's Top100