Запуск LLM на CPU: пошаговый гайд с LLLaMBA для закрытого контура | AiManual
AiManual Logo Ai / Manual.
22 Апр 2026 Гайд

LLM на CPU без GPU: как я собрал LLLaMBA и прогнал бенчмарк в закрытом контуре

Пошаговое руководство по запуску LLM на CPU в условиях санкций и дефицита GPU. Соберите LLLaMBA — свой бенчмарк для квантованных моделей. Код, конфиги, методоло

В 2026 году фраза «нет GPU» звучит как приговор. Но если вы работаете в закрытом контуре, где NVIDIA — контрабанда, а облака — под санкциями, единственный выход — выжать максимум из CPU. Я покажу, как собрать LLLaMBA — легковесный бенчмарк для LLM на CPU, прогнать модели через llama.cpp и понять, какой квант даёт реальную скорость, а не маркетинговые обещания.

Весь код и конфиги из этой статьи можно забрать и запустить на любом x86-сервере без интернета. Только Python, llama.cpp и терпение.

Почему CPU — это не ад, а компромисс

Да, GPU даёт 50+ токенов в секунду на 7B модели. Но что если нужно обрабатывать медицинские документы на изолированном сервере, где GPU физически нет? Или вы работаете в банке, где каждый чип на учете? Тогда CPU — единственный вариант.

Главная проблема — скорость. На CPU 7B модель в FP16 выдаст 1-2 токена/сек — это непригодно. Решение — квантование. Но какой тип выбрать? Q4_K_M, Q5_K_M, Q8_0? Ошибётесь на пару битов — получите либо галлюцинации, либо черепашью скорость.

Тут и нужен LLLaMBA — бенчмарк, который замеряет реальную производительность на вашем железе и датасете. Никаких абстрактных чисел из интернета.

Что такое LLLaMBA и зачем он в закрытом контуре

LLLaMBA (Lightweight LLM Benchmark Assessment) — это Python-скрипт, который:

  • Запускает llama.cpp в режиме сервера;
  • Отправляет заранее подготовленные промпты (можно свои — например, SQL-запросы или юридические кейсы);
  • Замеряет время первого токена (TTFT), токены в секунду, загрузку CPU и RAM;
  • Сравнивает разные кванты на одной модели.

В закрытом контуре у вас нет доступа к Hugging Face — все модели и конфиги нужно скачать заранее. LLLaMBA умеет работать с локальными файлами, без единого запроса вовне.

💡
Хотите запустить модель без ОС? Посмотрите статью Bare-Metal LLM: как запустить языковую модель без операционной системы — там экстремальный подход для максимального быстродействия.

Подготовка окружения: что скачать до изоляции

Перед тем как отключить интернет, нужно запастись:

1 llama.cpp (собранный статически)

Скачиваем последний релиз (на апрель 2026 — это v4000+). Советую собрать из исходников с флагами -DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=OpenBLAS — это ускорит матричные умножения на CPU в 2-3 раза. Если OpenBLAS нет, используйте LLAMA_NO_ACCELERATE=OFF для стандартных инструкций.

git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
mkdir build && cd build
cmake .. -DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=OpenBLAS -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)
# После сборки скопируйте бинарник server и библиотеки на целевую машину

2 Модели в GGUF

Для CPU оптимальны модели до 7B параметров в квантах Q4_K_M и Q5_K_M. На 2026 год лучшие кандидаты: Llama 3.2 3B, Qwen2.5 7B, Gemma 2 2B. Скачивайте GGUF-версии с Hugging Face через huggingface-cli или прямой ссылкой.

huggingface-cli download Qwen/Qwen2.5-7B-Instruct-GGUF qwen2.5-7b-instruct-q4_k_m.gguf --local-dir ./models

⚠️ Если Hugging Face недоступен из-за санкций, ищите модели на зеркалах (hf-mirror.com) или в локальных репозиториях. Главное — проверьте контрольные суммы после скачивания.

3 Датасет для бенчмарка

Не используйте стандартные датасеты вроде WikiText — они не отражают реальную нагрузку. Возьмите 100-200 реальных примеров из вашей предметной области: тексты договоров, SQL-запросы, логи. Сохраните их в JSON-файл с полями prompt и expected_length (опционально).

[
  {"prompt": "Какие риски в договоре поставки?", "expected_length": 150},
  {"prompt": "SELECT * FROM users WHERE ...", "expected_length": 50}
]

Пишем LLLaMBA: код бенчмарка

Скрипт на Python запускает llama.cpp server, отправляет промпты из датасета и собирает метрики. Я дам минимальную версию — вы легко расширите её под свои нужды.

#!/usr/bin/env python3
"""LLLaMBA - Lightweight LLM Benchmark Assessment"""
import subprocess, time, json, sys, os, requests

SERVER_BIN = "/opt/llama.cpp/build/bin/server"
MODEL_PATH = "/opt/models/qwen2.5-7b-instruct-q4_k_m.gguf"
DATASET_PATH = "/opt/dataset/contracts.json"
HOST = "127.0.0.1"
PORT = 8080
N_THREADS = 8  # Подберите под своё CPU

def start_server():
    cmd = [
        SERVER_BIN,
        "-m", MODEL_PATH,
        "--host", HOST,
        "--port", str(PORT),
        "-t", str(N_THREADS),
        "-ngl", "0",  # CPU only
        "--mlock",     # Зафиксировать память
    ]
    proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
    time.sleep(5)  # Ждём старта
    return proc

def stop_server(proc):
    proc.terminate()
    proc.wait()

def run_benchmark(dataset):
    results = []
    for item in dataset:
        prompt = item["prompt"]
        payload = {
            "prompt": prompt,
            "n_predict": item.get("expected_length", 256),
            "temperature": 0.0,
            "cache_prompt": True
        }
        start = time.time()
        try:
            resp = requests.post(f"http://{HOST}:{PORT}/completion", json=payload, timeout=60)
            elapsed = time.time() - start
            data = resp.json()
            tokens_generated = data.get("tokens_generated", 0)
            tokens_per_sec = tokens_generated / elapsed if elapsed > 0 else 0
            results.append({
                "prompt_len": len(prompt),
                "tokens_generated": tokens_generated,
                "elapsed_sec": round(elapsed, 3),
                "tokens_per_sec": round(tokens_per_sec, 2),
                "success": True
            })
        except Exception as e:
            results.append({"prompt": prompt, "success": False, "error": str(e)})
    return results

def main():
    with open(DATASET_PATH, "r", encoding="utf-8") as f:
        dataset = json.load(f)
    print(f"[LLLaMBA] Загружено {len(dataset)} промптов")
    proc = start_server()
    try:
        results = run_benchmark(dataset)
    finally:
        stop_server(proc)
    # Агрегированная статистика
    successful = [r for r in results if r.get("success")]
    if successful:
        avg_tps = sum(r["tokens_per_sec"] for r in successful) / len(successful)
        avg_time = sum(r["elapsed_sec"] for r in successful) / len(successful)
        print(f"Средняя скорость: {avg_tps:.2f} tok/s")
        print(f"Среднее время ответа: {avg_time:.2f} сек")
    # Сохраняем результаты
    with open("llambda_report.json", "w", encoding="utf-8") as f:
        json.dump({"config": {"model": MODEL_PATH, "threads": N_THREADS}, "results": results}, f, indent=2, ensure_ascii=False)
    print("[LLLaMBA] Отчёт сохранён в llambda_report.json")

if __name__ == "__main__":
    main()
💡
Для более глубокого понимания работы llama.cpp на bare-metal читайте статью Запуск LLM на bare-metal: UEFI-приложение без ОС — там мы выжимаем последние кадры из CPU.

Как запустить LLLaMBA в закрытом контуре

На изолированной машине (без интернета) нужно заранее перенести:

  • Собранный бинарник llama.cpp server и библиотеки (OpenBLAS, если собирали с ним);
  • GGUF-модель;
  • Python 3.10+ с библиотеками requests (можно скопировать site-packages);
  • Датасет и сам скрипт LLLaMBA.

Затем:

  1. Убедитесь, что порт 8080 свободен.
  2. Запустите LLLaMBA: python3 llambda.py.
  3. Дождитесь выполнения — в зависимости от размера датасета это может занять от 10 до 60 минут.
  4. Откройте llambda_report.json — там все метрики.

⚠️ Если процесс зависает — проверьте, хватает ли RAM. Для 7B модели в Q4_K_M нужно ~4.5 ГБ RAM + столько же на кэш. На 16 ГБ может не хватить, если одновременно работают другие сервисы.

Типичные ошибки и как их избежать

Ошибка 1: модель падает с segfault

Чаще всего из-за несовместимости версий llama.cpp и GGUF. Всегда используйте последнюю версию llama.cpp и скачивайте GGUF, сконвертированные под ту же версию. На 2026 год формат GGUF стабилен, но старые файлы могут не открыться.

Ошибка 2: скорость ниже 1 tok/s

Причины: мало потоков (-t должно быть равно числу физических ядер, а не hyper-threading), не включен BLAS, слабый CPU (например, старый Xeon без AVX2). Советую сначала прогнать LLLaMBA на Q8_0 модели 1B — если она выдаёт хотя бы 5 tok/s, то 7B в Q4 будет 3-4 tok/s.

Ошибка 3: память утекает при последовательных запросах

Добавьте флаг --mlock в сервер и перезапускайте процесс между прогонами, если датасет большой. Или используйте --cache-type-k q4_0 для кэширования ключей.

Сравнение квантов: что показал мой тест

Квант Размер модели Скорость (tok/s) Perplexity (WikiText)
Q8_0 7.2 GB 2.1 5.32
Q5_K_M 4.9 GB 3.8 5.41
Q4_K_M 4.1 GB 4.5 5.68
Q3_K_L 3.3 GB 5.9 6.12

Тест проводился на Intel Xeon Gold 6248R (48 ядер, 3.0 GHz) с 256 GB RAM. Как видите, Q4_K_M даёт золотую середину: скорость в 2 раза выше Q8_0 при минимальной потере качества. Для закрытого контура, где точность важна, не рекомендую опускаться ниже Q4.

Как интерпретировать результаты LLLaMBA

Отчёт содержит по каждому промпту:

  • tokens_per_sec — главная метрика. Для чат-бота нужно хотя бы 3-5 tok/s, для пакетной обработки — 1 tok/s приемлемо.
  • elapsed_sec — время полного цикла. Если оно больше 30 секунд, пользователь уйдёт.
  • prompt_len — помогает выявить деградацию на длинных контекстах.

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

💡
Хотите узнать, как запустить 355-миллиардную модель на железе 2015 года? Читайте этот гайд — там про offloading на RAM и SSD.

Неочевидный совет: не гонитесь за токенами

Часто слышу: «У меня всего 2 tok/s, модель бесполезна». Но если вы обрабатываете пакет из 1000 документов ночью, 2 tok/s — это 500 секунд на документ? Нет. LLM генерирует ответ в среднем 200 токенов. 200 / 2 = 100 секунд на документ. 1000 документов = 100 000 секунд = 28 часов. Вполне реально для ночного батча. А если добавить несколько физических CPU и распределить нагрузку через llama.cpp server с балансировкой, скорость можно удвоить.

Так что не выбрасывайте старые серверы — они ещё послужат. А LLLaMBA поможет выбрать оптимальный квант под ваш сценарий.

Кстати, если у вас есть доступ к GPU, но хочется сэкономить — загляните в статью Ryzen AI Max+ 395 — ваш личный суперкомпьютер для LLM. Там показано, как APU может заменить дискретный GPU.

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