Open WebUI медленно отвечает: причины и решение
Вы отправляете «Привет», курсор мигает секунд десять, текст ползёт по слову, а после последней точки интерфейс ещё не отпускает. Обидно то, что Open WebUI тормозит обычно не там, где на него думают: заметная часть времени уходит на фоновые вызовы модели, о которых пользователь не знает. Ниже — как разложить эти секунды и какие из них вернуть настройками.
Содержание
- Разложите задержку на четыре куска — иначе почините не то
- Пауза перед первым словом: модель выгрузилась из памяти
- Хвост после ответа: Open WebUI дёргает модель ещё три раза
- Чем длиннее переписка, тем медленнее ответ
- Тормозит сам интерфейс: RAG, эмбеддинги и разбухшая база
- Секунды, которые съедает не сервер, а маршрут
- Какой сервер под быстрый Open WebUI брать в MAATRIX
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Разложите задержку на четыре куска — иначе почините не то
«Медленно» — не диагноз. У связки Open WebUI + Ollama четыре места, где теряется время: загрузка модели в память (load_duration), обработка переписки (prompt_eval_duration), генерация (eval_duration) и хвост после ответа — служебные запросы самого Open WebUI. Первые три числа Ollama отдаёт сама:
curl -s http://127.0.0.1:11434/api/chat -d '{"model":"qwen2.5:7b","stream":false,
"messages":[{"role":"user","content":"Перечисли три планеты"}]}' | python3 -c '
import sys, json; d = json.load(sys.stdin)
for k in ("load_duration","prompt_eval_duration","eval_duration","total_duration"):
print(k.ljust(22), round(d[k] / 1e9, 2), "c")
print("tok/s", round(d["eval_count"] / (d["eval_duration"] / 1e9), 1))
'
Замер на стенде 4 vCPU без GPU, 8 ГБ RAM, Ubuntu 24.04, qwen2.5:7b-instruct-q4_K_M:
load_duration 6.41 c
prompt_eval_duration 3.24 c
eval_duration 22.13 c
total_duration 31.79 c
tok/s 5.6
Пользователь жаловался на «сорок секунд». Недостающие восемь-девять Ollama не показывает: это отдельные запросы, которые Open WebUI шлёт сам после того, как ответ дописан.
Пауза перед первым словом: модель выгрузилась из памяти
Ollama держит модель в RAM пять минут после последнего запроса, потом её освобождает. Отошли на обед — следующий вопрос упирается в повторное чтение гигабайт весов с диска. Проверка одной командой:
$ ollama ps
NAME ID SIZE PROCESSOR UNTIL
qwen2.5:7b 845dbda0ea48 6.2 GB 100% CPU 4 minutes from now
Пустой вывод — модели в памяти нет, ваши 5–7 секунд ушли на это. Правим окружение через sudo systemctl edit ollama.service:
[Service]
Environment="OLLAMA_KEEP_ALIVE=24h"
Environment="OLLAMA_NUM_PARALLEL=1"
Дальше sudo systemctl daemon-reload && sudo systemctl restart ollama; значение -1 держит модель вечно. Прогреть её после рестарта — пустым промптом:
curl -s http://127.0.0.1:11434/api/generate -d '{"model":"qwen2.5:7b","keep_alive":-1}'
OLLAMA_NUM_PARALLEL здесь не случайно: свежие версии Ollama сами решают, сколько слотов открыть, и при достаточной памяти берут четыре. Каждый слот получает свою копию KV-кэша — при контексте 8192 токена резервируется не 8192, а 32768. На 8 ГБ это разница между «модель влезла» и «модель уехала в своп».
Честная оговорка: 24h навсегда занимает 6–7 ГБ под 7B-модель. Живёт на машине что-то ещё — вы перенесли проблему на соседа: на 8 ГБ компромисс 1h.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть Open WebUIХвост после ответа: Open WebUI дёргает модель ещё три раза
Самая частая причина, о которой не пишут. После каждого сообщения Open WebUI шлёт модели служебные запросы: заголовок чата, теги, варианты продолжения, а при включённой базе знаний — переписанный поисковый. На GPU незаметно, на CPU каждый вызов — ещё один полный проход модели. В логах они начинаются характерно:
docker logs --tail 200 open-webui 2>&1 | grep -c "### Task:"
На одном сообщении мы поймали четыре обращения к модели вместо одного. Замер от последней точки ответа до момента, когда индикатор погас: было 11,4 с, стало 1,2 с. Выключается в Admin Panel → Settings → Interface или переменными:
ENABLE_TITLE_GENERATION=False
ENABLE_TAGS_GENERATION=False
ENABLE_FOLLOW_UP_GENERATION=False
ENABLE_AUTOCOMPLETE_GENERATION=False
ENABLE_RETRIEVAL_QUERY_GENERATION=False
Особенно вреден ENABLE_AUTOCOMPLETE_GENERATION: автодополнение стучится к модели, пока вы набираете текст, — сервер занят подсказкой ровно в момент, когда вы жмёте Enter.
Выключать всё подряд не обязательно: заголовки чатов полезны, просто их не должна писать семимиллиардная модель. В том же разделе есть пункт Task Model — поставьте туда llama3.2:1b. На стенде она даёт около 34 tok/s против 5,6 у 7B: заголовок пишется за полсекунды вместо шести. Для внешних провайдеров то же делает TASK_MODEL_EXTERNAL.
Ловушка, на которую наступают все: правка переменной может не примениться — при первом запуске часть настроек копируется в таблицу config внутри базы, и приоритет у неё. Меняйте в админке либо ставьте ENABLE_PERSISTENT_CONFIG=False; подробнее — в разборе частых ошибок.
Чем длиннее переписка, тем медленнее ответ
Классическая жалоба: «утром летало, к вечеру невыносимо, а я ничего не менял». Менялась длина чата: модель не помнит предыдущие реплики, поэтому Open WebUI при каждом сообщении отправляет всю историю целиком, и сервер перечитывает её заново.
Арифметика со стенда: промпт обрабатывается примерно на 48 tok/s. Пустой чат — 155 токенов, 3,2 секунды. Сороковое сообщение в том же чате — 5800 токенов, то есть две минуты только на чтение переписки. Сравните prompt_eval_count в новом чате и в проблемном: разница в десятки раз — диагноз поставлен.
- Не тащить один чат месяцами. Новая тема — новый чат: самое дешёвое решение и самое игнорируемое.
- Проверить размер контекста. По умолчанию Ollama даёт 4096 токенов (
OLLAMA_CONTEXT_LENGTH). Когда переписка перерастает окно, начало обрезается, кэш обработанного промпта перестаёт переиспользоваться и каждое сообщение считается с нуля — тот самый момент, когда чат резко проваливается по скорости. - Не задирать контекст вслепую. Поле Context Length лежит в Settings → General → Advanced Parameters, и 32768 «чтобы наверняка» — плохая идея: KV-кэш займёт лишние гигабайты, а prompt eval станет дольше. Для CPU-сервера 8192 — разумный потолок. Сжатие кэша (
OLLAMA_FLASH_ATTENTION=1плюсOLLAMA_KV_CACHE_TYPE=q8_0) помогает на видеокарте, на чистом CPU выигрыш околонулевой.
Если и после правок генерация не радует, вы упёрлись не в Open WebUI, а в железо и квантование — это отдельный разбор, почему Ollama медленно генерирует токены.
Тормозит сам интерфейс: RAG, эмбеддинги и разбухшая база
Бывает наоборот: генерация быстрая, а интерфейс вялый — чаты открываются с задержкой, список моделей думает. Виноват бэкенд.
Первое — память. Контейнер в простое держит 600–900 МБ, но при обращении к базе знаний подгружает модель эмбеддингов (sentence-transformers/all-MiniLM-L6-v2) и вырастает до 1,2–1,5 ГБ:
$ docker stats --no-stream open-webui
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
7f3a91c4e802 open-webui 1.87% 1.412GiB / 7.75GiB 18.22%
Если сумма «Open WebUI + модель в Ollama» подошла к объёму RAM, начинается своп — конец скорости. Проверка: vmstat 1 5, ненулевые si и so в установившемся режиме означают, что веса ездят на диск. Настройками не лечится — только память или модель поменьше.
Разгрузить бэкенд можно, отдав эмбеддинги в Ollama: RAG_EMBEDDING_ENGINE=ollama и RAG_EMBEDDING_MODEL=nomic-embed-text экономят 400–600 МБ, но индексация начинает конкурировать за процессор с генерацией. Осторожнее и с галочкой Hybrid Search: она подтягивает реранкер весом больше двух гигабайт.
Второе — база. SQLite спокойно живёт при паре сотен чатов и подтормаживает на паре тысяч, особенно в сайдбаре; удалённые чаты место не отдают:
docker stop open-webui
sqlite3 /var/lib/docker/volumes/open-webui/_data/webui.db "VACUUM;"
docker start open-webui
На базе в 180 МБ это вернуло 60 МБ и заметно оживило сайдбар. Если пользователей больше десятка и в логах мелькает database is locked, пора на PostgreSQL через DATABASE_URL. Честно: штатного переноса из SQLite в Postgres нет, решать надо на старте.
Секунды, которые съедает не сервер, а маршрут
Осталась категория задержек, где вычислений нет вовсе. Сравните один запрос с сервера и из дома:
curl -s -o /dev/null -w 'ttfb=%{time_starttransfer} total=%{time_total}\n' \
-H "Authorization: Bearer sk-ВАШ_КЛЮЧ" -H "Content-Type: application/json" \
-X POST https://ai.example.com/api/chat/completions \
-d '{"model":"qwen2.5:7b","messages":[{"role":"user","content":"тест"}],"stream":true}'
Ключ берётся в Settings → Account → API Keys. Разница в ttfb в пределах пинга — норма, разница в секунды — одна из трёх ловушек ниже.
Мёртвый апстрим в списке моделей. Обновляя список, Open WebUI опрашивает всех провайдеров сразу. Коннектор OpenAI включён по умолчанию, и если сервер до api.openai.com не достучится, каждое открытие выпадающего списка ждёт таймаута:
ERROR [open_webui.routers.openai] Connection error: Cannot connect to host api.openai.com:443
ssl:default [Connect call failed ('104.18.7.192', 443)]
Не пользуетесь внешними API — ENABLE_OPENAI_API=False. Пользуетесь — уберите лишние адреса из OPENAI_API_BASE_URLS и подтяните AIOHTTP_CLIENT_TIMEOUT (по умолчанию 300 секунд, для списка моделей абсурдно много). В свежих сборках есть отдельный AIOHTTP_CLIENT_TIMEOUT_MODEL_LIST; версию покажет curl -s http://127.0.0.1:3000/api/version.
Проверка обновлений и загрузка с Hugging Face. На старте Open WebUI идёт на GitHub за номером версии, а при первом использовании RAG тянет эмбеддинги с huggingface.co. Недоступны эти адреса — старт зависает на минуты. Лечится связкой ENABLE_VERSION_UPDATE_CHECK=False и OFFLINE_MODE=1, но тогда модель надо положить заранее.
Соседи по гипервизору. Если на хосте пересдана мощность, такты уходят чужим виртуалкам. Показывает steal time: sudo apt install -y sysstat && mpstat -P ALL 1 3. Колонка %steal устойчиво выше 5 — вы платите за ядра, которых у вас нет; настройками не чинится.
И отдельно: ответ, приходящий целиком через полминуты вместо потока по словам, — это буферизация в reverse proxy, лечится proxy_buffering off; в nginx. Подробнее — в статье Open WebUI не видит Ollama.
Какой сервер под быстрый Open WebUI брать в MAATRIX
Сам Open WebUI — лёгкое веб-приложение, ему хватает двух ядер; тяжёлым становится то, что считает модели.
| Сценарий | vCPU | RAM | NVMe | Что по скорости |
|---|---|---|---|---|
| Интерфейс к внешним API (OpenAI, свой LiteLLM) | 2 | 4 ГБ | 40 ГБ | Скорость провайдера, сервер не при чём |
| Локальная модель до 8B на CPU | 4–8 | 16 ГБ | 100 ГБ | 5–8 tok/s, хватает одному |
| Команда, RAG, PostgreSQL рядом | 8 | 32 ГБ | 200 ГБ | Столько же, но держит параллель |
Минимум, на котором это честно работает — 2 vCPU, 4 ГБ, 40 ГБ NVMe, и только если модели считаются не здесь. Отвечать будет так же быстро, как провайдер: для большинства это самый разумный вариант.
Комфортный вариант под локальный инференс — 8 vCPU и 16 ГБ. Почему не 8 ГБ: 7B в Q4 занимает 6,2 ГБ, плюс полтора гигабайта контейнера, плюс KV-кэш — на восьми вы живёте на грани свопа, а своп на инференсе это не «чуть медленнее», а «в десять раз медленнее». Диск с запасом: три-четыре модели с индексом съедают 80 ГБ. И прямо: на процессоре без видеокарты быстро не будет никогда. 5–8 токенов в секунду — скорость медленно печатающего человека: личному помощнику хватит, десяти пользователям нужен GPU-сервер.
Локация — Великобритания (Лондон). Пинг в интерактивном интерфейсе ощущается на каждом клике: из Москвы до Лондона 45–60 мс против 110–130 мс до Нью-Йорка. Второй аргумент важнее первого — с британского адреса нормально открываются api.openai.com, huggingface.co и ghcr.io, то есть не будет ни зависших списков моделей, ни минутного старта. Франция равноценна для пользователей в ЕС, Нью-Йорк берут под сервисы с проверкой на американский адрес, а российская локация оправдана, когда все модели локальные и 152-ФЗ важнее задержек.
Оплата — картами российских банков, по СБП, криптовалютой или токеном MAAT; зарубежная карта для сервера в Лондоне не нужна. Связка Ollama и Open WebUI ставится из каталога приложений, дальше вы правите окружение под себя. Сомневаетесь — опишите сценарий: сколько человек и какие модели.
Развернуть за пару минут
Готовый образ на VPS MAATRIX: NVMe, AMD EPYC, root-доступ. Локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Развернуть Open WebUIОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Почему первый вопрос за день идёт 30 секунд, а следующие быстро?
Ollama выгружает модель через 5 минут простоя, и первый запрос заново читает гигабайты весов с диска. Пустой ollama ps подтверждает диагноз, лечится OLLAMA_KEEP_ALIVE=24h и прогревом через curl.
Ответ дописан, а интерфейс ещё крутится — нормально?
Нет, это фоновые вызовы модели: заголовок чата, теги, варианты продолжения. Выключите лишнее в Admin Panel → Settings → Interface или поставьте в Task Model llama3.2:1b — у нас хвост сократился с 11,4 до 1,2 секунды.
Старый чат отвечает медленнее нового — почему?
Вся переписка уходит модели заново при каждом сообщении, и время обработки промпта растёт вместе с ней. Сравните prompt_eval_count в новом и проблемном чате: разница в десятки раз значит, что дешевле начать новый.
Нужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.