В предыдущем уроке об образах мы разобрали варианты сборки Open WebUI с поддержкой CUDA и встроенной Ollama. По названию образа ещё нельзя определить, какая программа нагружает видеокарту. Для обычного чата через удалённую модель GPU на компьютере с Open WebUI вообще не обязателен.
Проследим, какому компоненту и в какой среде нужен ускоритель. Сначала отправим учебное сообщение через внешний API. Затем представим, что на него отвечает Ollama на нашем компьютере. После этого зададим тому же чату вопрос по текстовой инструкции о перезапуске домашнего роутера. Это объясняющий пример, а не отчёт о проведённом тесте: скачивать образы, менять настройки или запускать модели для чтения урока не нужно.
Где вычисляется ответ в обычном чате
Если Open WebUI открыт на вашем компьютере, легко предположить, что вся работа нейросети происходит здесь же. На деле экран в браузере, серверная часть (backend) Open WebUI и сервер выбранной языковой модели выполняют разные задачи.
Рассмотрим стандартное подключение через backend без специальных режимов вроде Direct Connections. Когда вы отправляете сообщение в обычном чате, работа делится на три этапа:
- Браузер отображает страницу чата и передаёт ваше действие в backend Open WebUI. Видеокарта компьютера может помогать браузеру плавно рисовать страницу, но отрисовка интерфейса не имеет отношения к работе языковой модели.
- Backend Open WebUI принимает запрос и пересылает сообщение выбранному серверу модели: например, через маршрутизатор OpenAI-совместимого API или обработчик запросов Ollama. Слово API здесь означает лишь программный способ обращения: сам сервер модели может работать в облаке, на соседнем компьютере в локальной сети или в отдельном процессе на вашей машине.
- Сервер модели вычисляет ответ и передаёт его через backend в браузер. При потоковом режиме текст поступает по мере генерации.
Пока генерацию выполняет внешний сервер, он и несёт вычислительную нагрузку. Компьютеру с Open WebUI не нужна видеокарта ни для открытия интерфейса, ни для пересылки сообщений в таком чате. У backend бывают и собственные модели; к ним вернёмся после разбора чата. Пока оставим чат прежним и перенесём сервер языковой модели на свой компьютер.
Что меняется, когда модель работает в Ollama
Представим, что на то же сообщение теперь отвечает подключённая к Open WebUI Ollama, запущенная на вашем компьютере. Вычисление ответа переехало на вашу машину, но выполняет его именно процесс или контейнер Ollama, а не интерфейс Open WebUI.
В документации Ollama по Docker предусмотрен и запуск только на центральном процессоре (CPU). Работать на CPU допустимо, хотя заранее обещать комфортную скорость для конкретной модели и компьютера без проверки нельзя. Если же вы хотите ускорить генерацию на видеокарте, доступ к GPU должен получить сам сервер Ollama. Переключение Open WebUI на образ с тегом :cuda не переносит генерацию ответа внутрь WebUI и не даёт видеокарту отдельно работающей Ollama.
Возможности ускорения зависят от оборудования и среды запуска:
- Для видеокарт NVIDIA и поддерживаемых моделей AMD Radeon действуют собственные платформенные требования и списки совместимости из справки Ollama по GPU. Настройки CUDA от NVIDIA нельзя переносить на видеокарты AMD.
- На компьютерах Apple с чипами серии M нативно установленная Ollama может использовать графическое ускорение через Metal. Однако если запустить Ollama внутри Linux-контейнера через стандартный Docker Desktop на macOS, этот контейнер не получит прямой доступ к GPU автоматически: в ответах на частые вопросы Ollama прямо отмечено отсутствие проброса GPU (GPU passthrough) для Docker Desktop на macOS.
Теперь зададим тому же чату вопрос по небольшой текстовой инструкции. Перед генерацией ответа появится ещё одна задача для модели.
Почему у embeddings может быть другой исполнитель
Допустим, у нас есть короткая памятка с порядком перезапуска домашнего роутера, и мы хотим найти в ней точный шаг для ответа в чате. В этом примере выберем поиск по фрагментам текста (RAG). Он не описывает любую загрузку файла в чат: в Open WebUI есть и другие режимы работы с документами. Сначала из файла нужно извлечь текст. Этот отдельный шаг описан в документации по извлечению текста документов. Будем считать, что чистый текст инструкции уже получен.
Чтобы найти в инструкции нужный абзац по смыслу, а не просто по точному совпадению слов, система использует эмбеддинги (embeddings) — числовые представления текста. Специальная embedding-модель превращает фрагменты инструкции и ваш вопрос в наборы чисел (векторы), после чего поиск отбирает близкие по смыслу куски текста и передаёт их чатовой модели. Извлечение текста, расчёт embeddings, поиск фрагментов и генерация итогового ответа составляют четыре разные задачи.
Рассчитывать embeddings можно в разных местах независимо от того, где работает чатовая модель:
- Локально внутри backend Open WebUI. В полном стандартном образе задачу по умолчанию выполняет библиотека
SentenceTransformerпрямо внутри процесса backend, что видно в коде маршрутизатора поискаretrieval.pyи функциях выбора моделиretrieval/utils.py. - Во внешнем по отношению к WebUI сервисе. В настройках конфигурации
config.pyрасчёт embeddings можно поручить отдельному серверу Ollama или внешнему OpenAI-совместимому API. Слово «внешний» здесь означает лишь «вне процесса Open WebUI»: сама Ollama при этом может работать на том же самом компьютере.
Вы можете вести диалог через удалённый облачный API, но считать embeddings инструкции внутри своего контейнера Open WebUI. И наоборот: чатовая модель может отвечать локально в Ollama, а embeddings будут запрашиваться у стороннего API. Ускорение требуется оценивать именно там, где выполняется конкретная задача. Облегчённый образ :slim из руководства быстрого старта Open WebUI не содержит локального стека машинного обучения. Поэтому для расчёта embeddings ему обязательно нужен отдельный сервис.
Теперь понятно, что ответ и embeddings могут вычислять разные исполнители. Вернёмся к CUDA-образу Open WebUI и разберём, какую работу он может ускорить.
Когда нужен CUDA-образ и кому открывать GPU
Для ускорения локальных задач Open WebUI на NVIDIA нужны три условия. Одного тега :cuda или доступа к устройству недостаточно:
- Состав образа и режим приложения. В Dockerfile выпуска v0.12.3 сборка с поддержкой CUDA устанавливает библиотеки PyTorch под CUDA и включает внутренний флаг
USE_CUDA_DOCKER=true. В актуальной документации Quick Start описаны теги:cuda(с библиотеками CUDA 12.8) и:cuda126(CUDA 12.6). - Доступ к устройству из среды запуска. Контейнеру нужно явно разрешить доступ к видеокарте, как описано в инструкции Docker Compose по поддержке GPU. Сам по себе тег
:cudaв имени образа не открывает контейнеру доступ к оборудованию хоста, а проброс GPU в обычный CPU-образ не добавит внутрь недостающие CUDA-библиотеки. - Поддержка со стороны конкретной функции. В коде настройки окружения
env.pyверсии v0.12.3 backend выбирает устройство и сохраняет результат вDEVICE_TYPE. Начальное значение —cpu. В рассматриваемом Docker-сценарии с NVIDIA оно меняется наcuda, если включёнUSE_CUDA_DOCKER=trueи доступен CUDA. Если режим включён, но CUDA недоступен, backend возвращается к CPU и пишет предупреждение в журнал. Локальная модельSentenceTransformerвretrieval.pyполучает выбранное устройство. ЗначениеDEVICE_TYPEприложение определяет само; записывать его в.envне нужно.
CUDA-образ Open WebUI может быть полезен, если мы хотим ускорить на поддерживаемой видеокарте NVIDIA локальные задачи машинного обучения в backend, например расчёт embeddings. Эти задачи могут выполняться и на CPU. Другие внутренние функции (например, распознавание речи или переранжирование результатов в audio/__init__.py и retrieval.py) тоже могут опираться на выбранное устройство, но их внутренние механизмы различаются и не сводятся к одному универсальному правилу для всех моделей.
Если вы разворачиваете Open WebUI и Ollama как два отдельных сервиса в Docker Compose, доступ к GPU настраивается для каждого сервиса отдельно в зависимости от того, кто именно считает модели. В совмещённом образе (:ollama) оба процесса запускаются внутри одного контейнера через стартовый скрипт start.sh, но даже там backend Open WebUI и сервер Ollama остаются разными программами со своими вычислительными путями.
Для этих задач нужно учитывать доступную память. При расчётах на процессоре расходуется системная оперативная память (RAM), а при работе на дискретной видеокарте расходуется её видеопамять (VRAM); в некоторых случаях модель размещается частично в VRAM и частично в RAM. У компьютеров Apple с архитектурой единой памяти (unified memory) процессор и графическое ядро обращаются к общему пулу памяти, а не к двум раздельным запасам. Как поясняется в FAQ Ollama, в памяти размещаются веса модели, контекст диалога и данные параллельных запросов. Поэтому размер файла на диске не определяет полный расход памяти. Если и чатовая модель в Ollama, и локальная embedding-модель внутри Open WebUI используют одну и ту же физическую видеокарту, они делят её доступную память и вычислительный ресурс между собой. Передача одной видеокарты двум контейнерам не удваивает объём VRAM и не выделяет каждому сервису изолированную квоту памяти.
Настройки доступа ещё не подтверждают, что модель загрузилась на видеокарту. Проверить её размещение можно в уже работающей системе.
Как проверить размещение уже работающей модели
Если у вас уже есть настроенная система, проверить состояние оборудования и размещение моделей можно безопасными командами чтения без изменения конфигурации. Диагностику на тестовом стенде для этого урока мы не проводили. Ниже приведены команды и объяснение их результатов.
На уже подготовленном сервере Ubuntu 24.04 с видеокартой NVIDIA и установленным драйвером базовую картину по хосту показывает стандартная утилита:
Команда выводит список видимых драйверу видеокарт, занятую видеопамять и активные процессы на GPU. Успешный вывод nvidia-smi на хосте ещё не доказывает, что видеокарта проброшена внутрь конкретного Docker-контейнера или что именно ваша модель сейчас считает на GPU. Показатель CUDA Version в выводе утилиты хоста не подтверждает состав CUDA-библиотек внутри контейнера Open WebUI.
Чтобы узнать, как именно сервер Ollama разместил языковую или embedding-модель в памяти, используют команду клиента Ollama, подключённого к нужному работающему серверу:
Согласно документации Ollama, эта команда показывает только те модели, которые прямо сейчас загружены в память. Смотреть нужно на колонку PROCESSOR:
100% GPUозначает, что модель целиком размещена в памяти видеокарты;100% CPUпоказывает размещение модели в системной памяти для работы на CPU;- промежуточное соотношение (например, частичное распределение между CPU и GPU) говорит о том, что модель разделена между двумя устройствами.
Проценты в колонке PROCESSOR отражают долю размещения модели в памяти, а не текущую вычислительную нагрузку видеокарты. Пустая таблица ollama ps означает, что сейчас в памяти нет загруженных моделей. Сама по себе она не указывает на поломку. Специально загружать модель ради чтения урока не нужно. Если же Ollama запущена внутри существующего исправного проекта Docker Compose, где сервис в файле конфигурации действительно называется ollama, то из рабочего каталога этого проекта ту же проверку выполняют через docker compose exec ollama ollama ps.
В нашем примере с чатом и инструкцией к роутеру обычный ответ вычисляет выбранный сервер языковой модели, а числовые представления текста (embeddings) для поиска по инструкции строит тот исполнитель, которого вы назначили для этой задачи: сам backend Open WebUI или отдельный сервис. Если для локальных моделей backend выбрано ускорение на NVIDIA, CUDA-сборка и доступ к GPU нужны самому Open WebUI. Отдельный сервер модели использует собственный программный стек и получает доступ к ускорителю отдельно; CPU-варианты при этом остаются возможны.

