Мы с вами подобрались к заключительной части статьи-инструкции об организации распределённого инференса и шардирования LLM в домашних условиях. Мы уже запустили модель Gemma 3 и протестировали API, самое время настроить авторизацию и удобный веб-интерфейс для взаимодействия с нашей моделью. Им станет бесплатный Open WebUI.
В конце статьи попросим домашнюю LLM подвести итоги всей проделанной работы, а также поговорим о планах по развитию проекта.

Если вы не читали прошлые части статьи, стоит начать с них. В первой части мы настраиваем GPU и проброс в Proxmox, развёртываем Kubernetes-кластер, устанавливаем GPU Operator и KubeRay Operator. Во второй — пишем скрипт для vLLM и обеспечиваем доступ к нему через Ray Serve, а также запускаем модель Gemma 3 в KubeRay.
Настройка авторизации и интеграция с Open WebUI
Давайте рассмотрим, как развернуть Open WebUI — бесплатный веб-интерфейс для взаимодействия с LLM. Я дам краткий обзор Open WebUI и покажу, как связать его с нашим Ray-кластером, чтобы общаться с моделью через OpenAI-совместимый API.
Краткий обзор Open WebUI
Open WebUI — это веб-приложение, которое упрощает работу с большими языковыми моделями. Проект распространяется бесплатно под лицензией MIT, его код открыт. Благодаря Open WebUI пользователи могут:
отправлять сообщения к модели в формате диалога;
сохранять сессии диалога, чтобы возвращаться к ним и продолжать;
настраивать параметры инференса — температуру, длину вывода, top_k, top_p и другие;
управлять пользователями и ролями — регистрация, назначение роли admin/user.
Open WebUI поддерживает различные бэкенды для обработки запросов:
Ray Serve (через OpenAI-совместимый эндпойнт);
Ollama (локальные модели);
внешние OpenAI API (например, официальный OpenAI, Azure и Anthropic);
Pipelines (экспериментальные функции с LangChain и так далее).
Для дополнительного функционала можно активировать плагины, например Pipelines. Плагины позволяют загружать и обрабатывать документы в форматах PDF, DOCX и других с помощью тулкита Apache Tika. Также возможны интеграция с Langfuse и поддержка метода Retrieval Augmented Generation (RAG), что расширяет возможности работы с моделями.
Open WebUI поддерживает двустороннюю коммуникацию в реальном времени через WebSocket, что нужно для реализации «стримингового» ответа модели. Кроме того, пользователи могут одновременно вести несколько диалогов с разными моделями благодаря поддержке мультисессий.
Развёртывание Open WebUI через Helm
Основной Helm-чарт
Open WebUI предлагает официальный Helm-чарт, позволяющий:
запускать StatefulSet или Deployment (на выбор) с несколькими репликами;
настраивать Ingress, Redis (для WebSocket), PVC (хранение данных), авторизацию и так далее.
Пример установки:
helm repo add open-webui https://helm.openwebui.io
helm install open-webui open-webui/open-webui -f ap-values.yaml
Здесь ap-values.yaml — пример моих настроек.
Основные параметры:
nameOverride: "web-ui"
# ollama, pipelines, tika — опциональные модули, обычно отключены, если не нужны.
ollama:
enabled: false
pipelines:
enabled: false
tika:
enabled: false
# Может использоваться встроенный Redis для WebSocket.
websocket:
enabled: true
manager: redis
redis:
enabled: true
# Глобальный Redis-кластер (можно отключить или настроить внешний).
redis-cluster:
enabled: true
fullnameOverride: open-webui-redis
auth:
enabled: false
replica:
replicaCount: 3
# Настройки реплик Open WebUI.
replicaCount: 2
image:
repository: ghcr.io/open-webui/open-webui
tag: ""
pullPolicy: "IfNotPresent"
# Ингресс, используемый для доступа извне.
ingress:
enabled: true
class: "external-ingress"
annotations:
cert-manager.io/cluster-issuer: regru-letsencrypt-prod
nginx.ingress.kubernetes.io/websocket-services: "web-ui"
host: "ai.example.com"
tls: true
existingSecret: "ai-example-com-https-cert"
# Хранилище.
persistence:
enabled: true
size: 10Gi
accessModes:
- ReadWriteMany
storageClass: "ceph-fs-nvme-sc"
# Ключевая переменная — куда «проксировать» OpenAI API.
openaiBaseApiUrl: "https://openai-api.example.com/v1"
openaiBaseApiUrls:
- "https://openai-api.example.com/v1"
extraEnvVars:
- name: ENABLE_OPENAI_API
value: "True"
- name: DEFAULT_MODELS
value: "Gemma-3-12b"
- name: WEBUI_NAME
value: "AI.example.com"
- name: WEBUI_URL
value: "https://ai.example.com"
- name: DEFAULT_LOCALE
value: "ru"
- name: RAG_EMBEDDING_ENGINE
value: "openai"
- name: ENABLE_LOGIN_FORM
value: "True"
- name: OPENAI_API_KEY
valueFrom:
secretKeyRef:
name: openai-api-key
key: api-key
Настройки Ingress
host:
ai.example.com
— имя домена, с которого будет доступен интерфейс;annotations — можно указать аннотации для автоматического получения TLS-сертификата через cert-manager (например,
cert-manager.io/cluster-issuer: regru-letsencrypt-prod
);class —
external-ingress
, если используете свой внешний Ingress.
Провайдер Let's Encrypt для reg.ru
У меня хостинг reg.ru и для Let's Encrypt-сертификатов я использую DNS01-Challenge. Помогает мне в этом вебхук для certmanager’а от ребят из «Фланта» regru-letsencrypt-prod. Для его работы необходимо добавить соответствующие аннотации и создать ClusterIssuer, который будет взаимодействовать с reg.ru API для получения сертификатов.
Параметры окружения (extraEnvVars)
ENABLE_OPENAI_API: True
— чтобы включить работу Open WebUI с OpenAI-протоколами.DEFAULT_MODELS:
— указываем «Gemma-3-12b» как модель «по умолчанию» на интерфейсе.WEBUI_URL:
— внешний URL, чтобы ссылки и формы корректно формировались.OPENAI_API_KEY:
— если требуется ключ, который Open WebUI будет передавать при работе с внешним OpenAI API или вашим Ray API.
Полный список переменных окружения.
Интерфейс и основные блоки
Настройки модели
При первом запуске Open WebUI (допустим, https://ai.example.com
) вы увидите главный экран со списком чатов и настройки. В настройках задаются:
Base URL для OpenAI-протокола (
openaiBaseApiUrl
или несколько URL вopenaiBaseApiUrls
);модель по умолчанию;
API-ключ, если требуется.
Вот экран с настройками модели, где мы задаём URL до нашего API и ключ к нему:

Создание диалога и сохранение истории
Пользователь кликает «New Chat», выбирает модель, задаёт системное сообщение (System Prompt), после чего общается с LLM в режиме реального времени. Open WebUI в свою очередь отправляет запрос на POST /v1/chat/completions
и получает стриминг-ответ, если включена функция stream.
Диалоги Open WebUI хранит в своей базе данных. По умолчанию это SQLite внутри контейнера или на PVC. Пользователи могут переключаться между чатами, а также возвращаться к старым чатам, продолжать или просматривать их.
Управление пользователями и ролями
Роль Admin
При развёртывании можно назначить — либо создать при первом запуске — учётную запись администратора. Администратор имеет право:
подтверждать регистрацию других пользователей;
назначать им роли — user, admin, guest;
настраивать общие параметры приложения.
Регистрация
Если ENABLE_LOGIN_FORM=true
, тогда гости могут зайти на страницу /login
и зарегистрироваться. Для этого понадобится ввести email и пароль. После гость попадёт в статус Pending, и админ сможет его активировать.
Это позволяет разграничить доступ к инференсу, так как LLM-вычисления дорого обходятся по ресурсам.
Пример инференса
1. Open WebUI развёрнут с ingress.host=ai.example.com
.
2. Ray Serve с моделью Gemma-3-12b доступен по https://openai-api.example.com/v1
.
3. В настройках Open WebUI или в ap-values.yaml
прописали:
openaiBaseApiUrl: "https://openai-api.example.com/v1"
extraEnvVars:
- name: DEFAULT_MODELS
value: "Gemma-3-12b"
4. Авторизация: проходим логин в Open WebUI как админ или обычный пользователь.
5. Выбираем модель Gemma-3-12b, задаём вопрос и получаем ответ, который приходит из Ray Serve (vLLM):

Дополнительные возможности:
LangChain Pipelines — можно активировать
pipelines.enabled=true
и подключать LangChain, Tika, инструменты для анализа документов.Ollama — если требуется локальный бэкенд Ollama, можно включить
ollama.enabled=true
. Но в нашем случае используется Ray Serve.Redis Cluster — при больших нагрузках лучше включить Redis Cluster (replicaCount > 3), чтобы WebSocket-соединения хранились надёжно.
Вывод приложения в интернет и защита с помощью CDN
Content Delivery Network (CDN) располагает точками присутствия (POP) по всему миру, что позволяет ей эффективно обрабатывать запросы пользователей к вашему домену, например ai.example.com
.
При обращении пользователя запрос проходит через CDN, которая может арендовать каналы связи и направлять трафик по оптимальным маршрутам. Также CDN помогает защищаться от DDoS-атак, особенно на уровнях L3 и L4, и может выступать в роли прокси-сервера, скрывая реальный IP-адрес вашего кластера. В функционал CDN также входит поддержка WebSocket, что важно для работы Open WebUI, где чат может работать в режиме реального времени.
Пример сервиса CDN EdgeCenter предоставляет следующие возможности:
Роутинг трафика и кэш, что пригодится, если есть статические компоненты.
Вариант WAF-модуля, защищающего от классических веб-атак (OWASP Top 10).
Настройки геоблокировки. Например, можно запретить доступ из конкретных регионов.
Как это работает
Настраиваем DNS:
Доменное имя
ai.example.com
указывает на CDN (A/CNAME-запись).
Настраиваем CDN-конфигурацию:
Указываем backend-адрес —
<LoadBalancer IP>
или<Ingress IP>
вашего кластера.Включаем WebSocket pass-through, чтобы чат работал.

Активируем WAF, чтобы фильтровать вредоносные запросы.

CDN + TLS:
CDN может взять на себя создание TLS-сертификатов.
При этом внешний мир видит IP CDN, а не ваш кластер.
Преимущества
Сокрытие реального IP: усложняет атаки на прямой адрес.
Защита от DDoS: CDN-провайдер может отсеивать интенсивный нежелательный трафик.
WAF: блокирует SQL-инъекции, XSS и другие угрозы из топ-10 OWASP.
Контроль: некоторые CDN/WAF-решения дают гибкие правила (Rate Limiting, геоблок, ограничения по User-Agent).
Промежуточные итоги
Open WebUI даёт удобный UI для GPT-подобных моделей, поддерживает OpenAI-стиль запросов, сохраняет чаты, имеет встроенную авторизацию.
Настройки через Helm позволяют масштабировать количество реплик, подключать разные модули, настраивать TLS и persistence.
Гибкая авторизация (роль admin, pending users) и возможность дополнительно использовать JWT на стороне Ray Serve (двойная защита).
CDN и WAF помогают безопасно публиковать интерфейс наружу, скрывая IP-адрес кластера, фильтруя вредоносные запросы.
Заключение, сгенерированное домашней LLM
В трёх частях статьи мы с вами совершили настоящее путешествие в мир распределённого инференса, начиная с настройки GPU на Proxmox и заканчивая развёртыванием удобного веб-интерфейса для работы с большими языковыми моделями. Мы продемонстрировали, как можно создать гибкую, масштабируемую и безопасную инфраструктуру даже в домашних условиях.
Настройка GPU и проброс через Proxmox
Мы подробно разобрали, как правильно настроить Proxmox для проброса GPU в виртуальные машины. Это позволило объединить ресурсы нескольких видеокарт, обходя ограничения одной карты, и заложило основу для дальнейших вычислений.
Развёртывание Kubernetes-кластера с Deckhouse Kubernetes Platform
С помощью DKP мы создали Kubernetes-кластер, добавили GPU-узлы и интегрировали инструменты, такие как NVIDIA GPU Operator и KubeRay Operator, для эффективного управления вычислительными ресурсами.
Использование vLLM и Ray Serve
Благодаря vLLM мы смогли шардировать и распределить вычисления между несколькими GPU, а Ray Serve обеспечил масштабируемый HTTP API, совместимый с OpenAI-стилем, для общения с моделью. Это дало возможность работать с крупными языковыми моделями, не ограничиваясь одной видеокартой.
Подготовка Docker-образа и настройка KubeRay Cluster
Мы подробно описали процесс сборки Docker-образа на основе официального Ray-образа, добавления наших скриптов и необходимых зависимостей, а затем развёртывание Ray-кластера с помощью Helm-чарта. Это позволило создать оптимизированное окружение для инференса.
Интеграция с Open WebUI и вывод в интернет
Open WebUI был развёрнут как бесплатный и удобный интерфейс для взаимодействия с LLM, позволяя управлять пользователями, настраивать API и использовать расширенные опции через Helm-чарт. Кроме того, применение CDN и WAF гарантирует защиту и высокую скорость доступа, скрывая реальный IP-адрес кластера и обеспечивая базовую защиту от DDoS и других угроз.
В итоге статья демонстрирует, как можно собрать платформу для распределённого инференса, которая не только эффективно использует аппаратные ресурсы, но и обеспечивает безопасный, масштабируемый и удобный доступ к языковым моделям через веб-интерфейс. Это решение открывает широкие возможности для дальнейших экспериментов, разработки и внедрения в различных масштабах — от домашних лабораторий до крупных корпоративных инфраструктур.
Я надеюсь, что мой проект вдохновит вас на новые идеи и эксперименты, а полученная платформа станет отличной отправной точкой для реализации самых смелых задумок в области искусственного интеллекта и распределённых вычислений.
P. S. Что успело измениться, пока статья готовилась к выходу
Пока текст проходил редактуру, мой домашний кластер не стоял на месте. Я успел добавить несколько новых сервисов и начать эксперименты, которые делают инфраструктуру куда полезнее:
Stable Diffusion уже встроен в Open WebUI, поэтому теперь к каждому ответу LLM при желании можно получить мгновенную иллюстрацию или схему.

Whisper обрабатывает голосовые запросы: надиктовал вопрос — сразу получил текст. В связке с TTS (Microsoft Speech) это даёт режим «расскажи сказку вслух» — ребёнок формулирует тему голосом, модель сочиняет историю и тут же её озвучивает.


Тестирую мультимодальность: доработал
serve.py
, чтобы Gemma 3 принимала не только текст, но и изображения.Подключаюсь как бэкенд к различным Copilot-подобным ассистентам и AI-агентам (MCP): OpenAI-совместимый эндпойнт позволяет VS Code, JetBrains AI и другим инструментам «думать» силами домашнего кластера.
В плане доработок — режим RAG: загрузка PDF, DOCX и прочих документов, чтобы модель отвечала с цитатами и ссылками на конкретные страницы, а также AI-SRE-помощник для k8s: он будет на лету анализировать метрики и логи, предлагать и по одобрению применять исправления в пару кликов, непрерывно учиться на runbook’ах и отзывах, делать бэкапы и восстанавливаться из них — надеюсь, это позволит забыть про рутину и сосредоточиться на действительно крутых задачах.
Если у вас есть идеи, что ещё можно запустить на таком кластере, — пишите в комментариях, будем экспериментировать вместе!
P. P. S. Минутка рекламы
20 мая в 19:35 я выступаю на первом митапе Deckhouse User Community с докладом по теме этой статьи. Места на офлайн в Москве закончились, но можно посмотреть выступление в онлайн-трансляции и задать мне вопросы в чате. Зарегистрироваться можно на TimePad.
Комментарии (9)
DimanODG
16.05.2025 08:05Здравствуйте! Спасибо за такое подробное описание работы распределенных вычислений.
Скажите, возможно мне провести этот эксперимент на моих домашних ноутбуках? Всего 3 ноутбука. У одного (13900hx) дискретная 4080 (12gb). У 2-х других (12700h и 13500h) есть внешние видеокарты через TB4: 2080ti и 3090.
Myskat_90 Автор
16.05.2025 08:05Здравствуйте!
Да, провести возможно, но надо подумать как лучше объединить ваше оборудование в единый ray кластер с проброшенными GPU - на это может потребоваться много времени)
Плюс надо понимать, что при разнородной инфраструктуре, распределение будет ограничено по самой наименьшей по видеопамяти карте (особенности vLLM)
Мне кажется проще будет в вашем случае использовать решение Exo https://github.com/exo-explore/exo
Достаточно будет поставить docker и прокинуть в контейнер GPU и в этой среде поставить exo
project_delta
очень крутые статьи! в какой бюджет обошлась ваша домашняя лаборатория?
Myskat_90 Автор
Большое спасибо за отзыв! Для меня очень важна обратная связь.
Вопрос про бюджет провокационный конечно) Поэтому отвечу так - точно дешевле, чем одна Tesla H100 80Gb, если смотреть объявления на авито.
project_delta
на самом деле никакой провокации, сам занимаюсь посторойкой homelab, но без видеокарт)
Myskat_90 Автор
Это другой разговор - написал в ЛС более подробно)
project_delta
Спасибо за список. К сожалению, у вас выключены входящие сообщения на Хабре, поэтому отпишусь тут)
Список ваш впечатляет, у меня просто NAS и 2 ПК на инженерных intel i9 1200 сокета (описывал в своих статьях сборку)