ComfyUI на CPU: как я бросил GPU и обрёл покой
Когда я задумал запустить генерацию картинок на своём сервере, логичным выбором казалась старая RX 580. В теории — отличная карта для Stable Diffusion: 8GB VRAM, шина 256-bit, сообщество уверяло, что она летает. На практике всё пошло не так.
Попытка №1: ROCm
AMD продвигает ROCm как свой ответ CUDA. Разворачиваю rocm/pytorch — контейнер падает при первой же попытке загрузить модель. Ошибки вида Missing HIP kernel. Лезу в форумы — оказывается, для Polaris (RX 580, gfx803) поддержка в ROCm урезана.
Дальше — перебор образов:
rocm/pytorch:latest— не видит GPUrocm/pytorch:rocm6.1— видит, но падает на forward passwoodrex/rocm612-torch24-gfx803— самый многообещающий: собран специально под gfx803, GPU детектится, но генерация хенгует
Последний образ заслуживает отдельного упоминания. Он единственный, кто прошёл инициализацию и даже начал денойзинг. На третьем шаге — тишина. docker logs молчит, процессов нет, контейнер жив. Просто берёт и зависает без единой ошибки.
Я потратил два дня на перебор hipBLAS, rocBLAS, MIOpen разных версий. Результат — ноль.
Попытка №2: CPU mode
Решение пришло от безнадёги: --force-cpu. ComfyUI запустился. Первая картинка за 4 минуты на 320×320. Это медленно, но оно работает.
Дальше — оптимизация. Собрал свой образ на python:3.10-slim:
FROM python:3.10-slim
WORKDIR /app
RUN apt-get update && apt-get install -y git &&
git clone https://github.com/comfyanonymous/ComfyUI &&
cd ComfyUI &&
pip install --no-cache-dir -r requirements.txt torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
CMD ["python", "main.py", "--listen", "0.0.0.0", "--port", "8188"]
Он весит ~3.5GB, запускается за 20 секунд, не требует GPU-драйверов, не ругается на HIP, не виснет.
Производительность
Замеры на реальном железе (Proxmox хост, CPU — без GPU-ускорения):
| Разрешение | Steps | Время на шаг | Итого |
|---|---|---|---|
| 320×320 | 10 | ~6 сек | ~1 мин |
| 512×512 | 20 | ~15 сек | ~5 мин |
| 768×768 | 30 | ~25-35 сек | ~15 мин |
Для блога — терпимо. Для продакшна — нет. Но если GPU нет или он не поддерживается — CPU работает.
Что пошло не так с ROCm?
- gfx803 — устаревшая архитектура. ROCm 6+ официально её не поддерживает. Нативные образы от сообщества — лотерея.
- Docker + GPU — добавляет уровень абстракции, на котором сыпется ещё больше. Нужен
--device /dev/kfd,--group-add video, совпадение версий драйвера хоста и библиотек в контейнере. - Отсутствие обратной связи — когда GPU хенгует, нет никакого сообщения об ошибке. Просто пустой лог.
Что в итоге
CPU-режим — это честно. Медленно, стабильно, предсказуемо. Никакой магии, просто числа.
Я оставил Dreamshaper 8 (SD 1.5) как основную модель — она даёт хороший баланс качества и скорости. Контейнер запущен с --restart unless-stopped, интегрирован в WordPress через плагин-обёртку.
Мораль: если у вас нет современного NVIDIA или нормального AMD (RX 7000+), не мучайтесь. CPU — норм. Картинки генерируются, пост пишется, сервер не дымится.
Я расскажу подробнее всю эту историю с RX 580 и ROCm, потому что за сухим перечислением ошибок скрывается целый квест, из которого я вынес немало полезного. Если ты собираешься крутить Stable Diffusion на сервере без современной NVIDIA — эта статья сэкономит тебе дни, которые я потратил.
С чего всё началось. У меня была старая RX 580 с 8 гигабайтами видеопамяти, которая лежала без дела. В интернете полно роликов «RX 580 летает для Stable Diffusion», и я повёлся. Ключевая деталь, которую все почему-то опускают: «летает» — это на Windows с DirectML или с определёнными сборками, а в линуксовом Docker с ROCm всё куда мрачнее. AMD очень избирательно относится к поддержке своих старых карт в ROCm, и RX 580 относится к архитектуре Polaris, которую новые версии ROCm практически бросили.
Первая моя ошибка была в том, что я взял самый свежий официальный образ rocm/pytorch. Он вообще не видел GPU — при старте просто писал, что устройств нет. Потом я выяснил, что нужно прокидывать внутрь контейнера устройства /dev/kfd и /dev/dri, добавлять пользователя в группу video, задавать переменные окружения вроде HSA_OVERRIDE_GFX_VERSION. Без этого ROCm просто не поднимается. Когда я всё это сделал, образ rocm6.1 начал видеть карту, но падал на forward pass с непонятными ошибками вида Missing HIP kernel. Каждая такая ошибка уводила меня на форумы, где кто-то когда-то решал похожую проблему другой версией драйвера.
Самое обидное было с образом от сообщества woodrex, который специально собран под gfx803. Он прошёл инициализацию, загрузил модель, начал денойзинг — и просто завис на третьем шаге. Без ошибок, без падений, без логов. Контейнер жив, процессы исчезли, тишина. Я перепробовал разные версии hipBLAS, rocBLAS, MIOpen, менял переменные окружения, пересобирал — результат нулевой. Такое зависание без обратной связи — худшее, что может быть при отладке, потому что ты не знаешь, в какую сторону копать.
После двух дней таких плясок я сдался и включил CPU-режим. И тут произошло неожиданное: вместо разочарования я получил рабочую систему, пусть и медленную. Первая картинка 320×320 пришла за четыре минуты. Для блога это терпимо: запустил генерацию, пошёл писать текст, вернулся — картинка готова. Не для продакшна, конечно, но для своих задач — вполне.
Отдельно хочу остановиться на Docker-образе, который я собрал. Ключевая деталь — ставить CPU-сборку PyTorch через —index-url https://download.pytorch.org/whl/cpu. Это избавляет от кучи проблем: образ не тащит CUDA- или ROCm-библиотеки, не требует драйверов, весит меньше и запускается быстрее. Мой образ на базе python:3.10-slim весит около 3.5 гигабайт и стартует за двадцать секунд. Никаких HIP, никаких /dev/kfd, никакой магии — просто рабочий инструмент.
Теперь про цифры производительности, чтобы ты понимал, чего ожидать. На моём CPU в проксмоксе: 320×320 при десяти шагах — около минуты суммарно; 512×512 при двадцати шагах — около пяти минут; 768×768 при тридцати шагах — около пятнадцати минут. Скорость на шаг зависит от мощности процессора и количества потоков, так что у тебя цифры могут отличаться в обе стороны. Главное — прикинь заранее, подходит ли тебе такой темп.
Что я понял про выбор модели. Для CPU-режима важно брать лёгкие модели. Я остановился на Dreamshaper 8, который построен на базе SD 1.5, — он даёт хороший баланс качества и скорости и весит заметно меньше более тяжёлых моделей. Тяжёлая модель на CPU может превратить и так медленную генерацию в пытку. Правило простое: чем меньше шагов и чем легче модель — тем быстрее результат.
Ещё несколько практических советов. Ограничь количество шагов до разумного минимума — для многих задач хватает 10–15. Уменьшай разрешение, если качество не критично, а потом масштабируй картинку. Держи под рукой команду для выгрузки модели между генерациями — это экономит память. И обязательно поставь restart: unless-stopped, чтобы контейнер поднимался сам после перезагрузки сервера. Мой контейнер так и работает, я про него забыл и просто пользуюсь.
Про интеграцию с WordPress расскажу пару слов. Я написал плагин-обёртку, который дергает ComfyUI через API. У ComfyUI есть HTTP-интерфейс: можно отправить workflow, дождаться завершения и забрать картинку. Это позволило мне генерировать изображения прямо из админки, не заходя в контейнер. Для блога — очень удобно: не нужно вручную выгружать картинки, всё делается одним движением.
Теперь про мораль, ради которой я вообще пишу этот текст. Если у тебя нет современной NVIDIA или нормальной AMD из семейства RX 7000+ — не мучайся с ускорением на старой видеокарте. Я потратил два дня на ROCm и получил ноль. Включил CPU-режим — и всё заработало за вечер. Да, медленно. Но стабильно и предсказуемо. Для задач уровня «сгенерировать обложку к посту» этого более чем достаточно.
И напоследок о том, что я бы сделал иначе, знай я всё это заранее. Я бы сразу проверил, поддерживает ли моя видеокарта ROCm нужной версии — это час, а не два дня. Потом, если не поддерживает — сразу собрал бы CPU-образ и не тратил время на эксперименты с драйверами. И я бы не верил слепо роликам «RX 580 летает» — в них почти всегда опускают детали про операционную систему, драйверы и контейнеры.
Сейчас мой сервер спокойно генерирует картинки на CPU, пост пишется, и ничего не дымится. Может, когда-нибудь я куплю карту посовременнее и ускорюсь — но в том, что уже есть, я нашёл рабочее решение. Главный урок этой истории: иногда путь назад, к простому и скучному CPU-режиму, — это самый быстрый путь вперёд к результату.
Расскажу ещё про несколько хитростей, которые я открыл уже после того, как запустил CPU-режим. Во-первых, очень полезно посмотреть, сколько ядер доступно контейнеру, и при необходимости ограничить или, наоборот, разрешить больше потоков через настройки Docker. PyTorch по умолчанию использует столько потоков, сколько видит, и на хостинге с кучей виртуальных ядер это может привести к неожиданной нагрузке на соседей. Я выставил через переменную окружения разумное число потоков, чтобы генерация не мешала основному сайту.
Во-вторых, я заметил, что скорость зависит от того, что ещё происходит на сервере в момент генерации. Если параллельно идёт бэкап или другой тяжёлый процесс — время на шаг может вырасти в полтора-два раза. Поэтому я стараюсь гонять генерацию в спокойные часы, когда на сервере мало активности. Для моего блога это не критично, но если бы мне нужно было генерировать много картинок — я бы вынес ComfyUI на отдельную машину или как минимум выделил ему фиксированные ресурсы.
В-третьих, про сохранение модели в памяти. Между генерациями ComfyUI может выгружать модель, и загрузка заново занимает время. Если ты генерируешь серию картинок — постарайся держать модель в памяти, а не перезагружать её каждый раз. Сэкономишь минуты, а на CPU каждая минута на счету.
И последняя мелочь, которая кажется очевидной, но о ней легко забыть: сделай бэкап своих workflow. У меня был случай, когда я пересоздал контейнер и потерял все свои настроенные пайплайны. Хорошо, что я запомнил структуру и восстановил за полчаса, но могло быть хуже. ComfyUI хранит workflow прямо в интерфейсе, и их можно экспортировать в JSON — сделай это заранее.