Руководство по сборке локального AI-стека. Часть 1

—

от автора

Руководство по сборке локального AI-стека

Часть 1. Описание задачи и общий план работ

Что мы собираем

Локальный стек для работы с большими языковыми моделями (LLM) и генерации изображений, который:

  • Работает полностью офлайн — ни одного запроса в облака, ни одной внешней зависимости во время работы.

  • Использует только CPU — без видеокарт, без CUDA, без драйверов. Всё считается на процессоре, с mmap для экономии RAM.

  • Запускается на Debian 12 x86_64 (целевая система), но не привязан к конкретному железу — на другой машине с тем же дистрибутивом развернётся из той же папки.

  • Доступен из локальной сети — с аутентификацией, чтобы домашние или коллеги в офисе могли пользоваться, но без правки конфигов каждый раз.

  • Переживает перезагрузки и обновления — модели и пакеты лежат в папке проекта, а не размазаны по системе.

Из чего состоит стек

Три независимых компонента, каждый со своим портом и своей ролью:

Компонент

Что делает

Порт

Доступ

llama.cpp (llama-server)

Инференс LLM: чат, саммари, перевод, код

10000

только 127.0.0.1

Open WebUI

Веб-интерфейс с логином, историей чатов, настройкой моделей

8080

0.0.0.0 (LAN)

stable-diffusion.cpp (sd-server)

Генерация изображений

8888

0.0.0.0 (LAN)

Почему именно так:

  • llama-server слушает только localhost — снаружи к нему не подключиться напрямую. Это безопасность: даже если кто-то в LAN узнает порт 10000, он не достучится.

  • Open WebUI — единственная «дверь» с аутентификацией. Он ходит к llama-server по 127.0.0.1:10000, а пользователи ходят к нему по LAN_IP:8080.

  • sd-server — отдельный сервис, не связанный с чатом. У него свой UI и свой порт. Если картинки не нужны — его можно не запускать.

Что понадобится

Железо:

  • CPU (любой x86_64, чем больше ядер — тем быстрее; 4+ ядра комфортно).

  • RAM: минимум 8 ГБ для моделей до 10B (с mmap и лимитом), 16+ ГБ — если хочется запускать модели 20B+ или несколько сервисов одновременно.

  • Диск: 60–80 ГБ свободного места (модели + venv + offline_packages). SSD/NVMe настоятельно рекомендуется для скорости, но и на HDD работает (медленно).

  • Сеть: для первичной сборки нужен интернет, для работы — нет.

Софт:

  • Debian 12 (bookworm) x86_64.

  • Python 3.11 (идёт в комплекте).

  • git, cmake, build-essential, python3-venv, python3-pip.

  • Интернет только на этапе сборки — потом всё офлайн.

Общий план работ

Руководство разбито на пять шагов. Каждый шаг — самостоятельный, можно остановиться и проверить результат, прежде чем идти дальше.

Шаг 1. Запуск llama.cpp на тестовой модели.

  • Собираем llama.cpp из исходников (один раз).

  • Качаем компактную модель (Qwen3.5-2B-Q4_K_M).

  • Запускаем llama-server с mmap и лимитом памяти.

  • Проверяем, что чат работает, и понимаем, как устроены ключевые флаги (--load-mode, --no-repack, --cache-type-k/v, --reasoning).

  • Учимся правильно раскладывать модели: обычные .gguf — в корень models/, мультимодальные (с mmproj) — в отдельные подпапки.

Шаг 2. Наполнение моделями.

  • Скачиваем набор моделей под разные задачи: универсальный чат, кодинг, ролевое общение, русский язык, vision (OCR).

  • Раскладываем по папкам с учётом mmproj.

  • Делаем HTML-шпаргалку web/models.html — статическую страницу с описанием моделей, их сильных/слабых сторон и рекомендаций «какая модель для какой задачи». Она открывается в браузере локально, без сервера.

Шаг 3. Запуск сервера генерации изображений (stable-diffusion.cpp).

  • Собираем stable-diffusion.cpp из исходников.

  • Разбираемся, что для изображений нужен не один файл, а три: диффузионная модель (.gguf или .safetensors), VAE (декодер в пиксели) и текстовый энкодер (LLM, который понимает промпт).

  • Раскладываем по папкам: модели — в models/media/, VAE — в models/media/vae/<модель>/, LLM — в models/ (общие с текстовым стеком).

  • Запускаем sd-server на порту 8888 с веб-UI (web/index.html).

Шаг 4. Добавление Open WebUI поверх llama.cpp.

  • Ставим Open WebUI в тот же venv, что и всё остальное (общая папка).

  • Настраиваем его через start_webui.py: отключаем Ollama, отключаем телеметрию, включаем веб-поиск (DuckDuckGo, если есть сеть), подключаем к llama-server через 127.0.0.1:10000.

  • Секреты (API-ключ llama и сессионный ключ WebUI) храним в .secrets (chmod 600), генерируем один раз через init_secrets.sh.

  • Запускаем через оркестратор run_webui.sh: он поднимает llama-server в фоне, ждёт готовности, потом запускает WebUI, и корректно останавливает оба по Ctrl+C.

  • Первый пользователь, зарегистрировавшийся в WebUI, становится админом; регистрация после этого закрывается.

Шаг 5. Офлайн-развёртывание и перенос.

  • Собираем offline_packages/ — все Python-wheels, нужные для venv (включая CPU-версию PyTorch).

  • Фиксируем версии в requirements.lock.

  • Пишем README.md с инструкцией «как развернуть с нуля на другой машине».

  • Опционально: упаковка в LXC (обсудили, но решили не делать — слишком много возни ради того, что venv и так решает).

Что в итоге получится

После прохождения всех шагов у вас будет:

  • Рабочий чат с LLM на http://<LAN_IP>:8080 — с логином, историей, настройкой параметров моделей.

  • Родной UI llama.cpp на http://127.0.0.1:8080 (если запускать run_llama_mmap.sh отдельно) — для отладки и сравнения.

  • Генератор картинок на http://<LAN_IP>:8888 — с промптом, размером и шагами.

  • Шпаргалка web/models.html — какая модель для какой задачи.

  • Папка offline_packages/ — для развёртывания на другой машине без интернета.

  • Полное понимание, как это всё устроено, и возможность добавлять новые модели, менять лимиты памяти, переключать режимы (router / single, reasoning on/off).

Что важно понять до начала

  1. Всё на CPU — это иногда медленно. 3–15 минут на ответ большой модели, 5–10 минут на картинку. mmap и лимиты памяти делают процесс предсказуемым, но не быстрым.

  2. mmap — ключевая технология. Модель не загружается в RAM целиком; ядро подгружает страницы по требованию и вытесняет неиспользуемые. Это позволяет запускать 20-гиговую модель на 10 ГБ RAM — медленно, но работает.

  3. Open WebUI — это «поверх» llama.cpp, а не замена. Родной UI llama.cpp остаётся доступен (на localhost), а WebUI добавляет аутентификацию и управление моделями.

  4. Офлайн — это не «нет интернета вообще». На этапе сборки интернет нужен (скачать исходники, модели, пакеты). После сборки — не нужен. offline_packages/ решает проблему переноса на машину без сети.

ссылка на оригинал статьи https://habr.com/ru/articles/1099472/