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

Ссылки на все части:
Часть 1. Общий план
Часть 2. Запуск llama‑cpp
Часть 3. Наполнение моделями
Часть 4. Запуск сервера генерации изображений
Часть 5. Open WebUI поверх llama.cpp
Часть 6. Конвертация моделей Hugging Face в GGUF
Часть 7. Финал. Офлайн‑развёртывание

Часть 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/ решает проблему переноса на машину без сети.

Комментарии (6)


  1. Timnet
    26.10.2026 15:29

    Спасибо за труд, актуально!
    Вот ещё бы нашлось в этом проекте место для средней видеокарты, типа 3060 8ГБ
    Думаю скорость работы выросла бы на порядок. И для многих это было бы актуально ввиду низкого порога входа на такое железо.


    1. AntonovPsy Автор
      26.10.2026 15:29

      Полагаю, вы правы. Но я как раз из тех у кого нет видеокарты (в принципе не нужна). Модели попробовал поднять под мелкие задачи, больше из любопытства.

      Наскольк о знаю llama-cpp умеет работать с gpu, потому осмелюсь полагать, что вполне реально развернуть подобное (в том числе с mmap) даже на небольшой видеокарте. Реальное потребление памяти большинства текстовых моделей (из тех, что использовал) меньше 2 Гб. Генерация изображений побольше ест, на этапе конвертации в картинку, те что оставил около 3-4 Гб. Это цифры реального потребления, резервируют в 2-3 раза больше rss.

      Полагаю попробовать вполне можно. В коде следующих частей нужно будет только убрать флаги явной отправки вычислений на cpu (они все подписаны). Тогда вполне вероятно, что пойдёт на gpu. Сам не пробовал, но в теории должно работать.


  1. Maverickfinn
    26.10.2026 15:29

    Здравствуйте, присоединяюсь к предыдущему комменту - карта с 10Гб видеопамяти куплена по случаю для именно локалки)))...


    1. AntonovPsy Автор
      26.10.2026 15:29

      Выше ответил )

      Это лишь моя догадка, сам не пробовал, но на gpu должно работать так же, с минимальными правками запуска (убрать флаги явной привязки к cpu).


  1. eugenk
    26.10.2026 15:29

    Привет ! Возможно в какой-то степени повторяю вопрос Тимофея. Вопрос такой. У меня ноутбук выпуска 2019-го года. С видеокартой nvidia 1650 Ti и 4 гигами видеопамяти. Скажите, использование такой видеокарты может дать хоть какое-то преимущество ?

    И второй вопрос. Можно ли с приемлемой производительностью использовать такую конфигурацию для обучения своих небольших моделей с нуля ? Несколько суток для меня было бы приемлемо. У меня очень специфическая задача. Чатбот мне не нужен. И данных для обучения я могу нагенерить сколько угодно.


    1. AntonovPsy Автор
      26.10.2026 15:29

      Доброго времени. Отвечу исходя из того, что знаю (я не специалист в области).

      1. Преимущество теоретически будет, видеокарта считает побыстрее. Но, это в теории и при условиях: она может запускать модели (поддерживается драйверами), хватит 4 Гб (на текстовые модели должно хватить, на картинки может не получиться). На практике не проверял.

      2. Для обучения моделей с нуля эта конфигурация не пригодна. Учить модель в gguf - невозможно (с нуля по крайней мере). Насколько знаю в llama-cpp можно дообучить модель (LoRA), но сам не пробовал. Для полного (pre-training) обучения нужно развернуть полную модель и учить ее. На видеокарте в 4 Гб ни одна из LLM не поднимется (модель плюс расходы обучения: оптимизатор, датасеты и прочее), может только самая маленькая или самописная пойдет. Если вы имели в виду mmap отдельно от этого стека - то использовать можно при обучении, но модель все равно полную придется держать в VRAM (веса, градиенты и прочее).