Как я поднял ComfyUI на CPU и пожалел об этом
Когда я решил попробовать ComfyUI, у меня не было NVIDIA-видеокарты. Вообще. Был только старый домашний сервер на OpenWrt с процессором Intel Celeron и 8 гигабайтами оперативки. И, как вы уже догадались, это была плохая идея.
Но я же самоуверенный айтишник, верно? Гайдов в интернете полно, ComfyUI же вроде как платформонезависимый. Ну, почти.
Сначала я установил Python, скачал репозиторий, запустил установку зависимостей. Всё шло бодро ровно до момента, пока не пошли зависимости для CUDA. Тут я впервые задумался: «А стоп, CUDA же не будет работать на CPU». Но отступать было позло — процесс установки уже шёл четвёртый час, а я люблю смотреть на горячие прогресс-бары.
Решение пришло неожиданно: в репозитории нашёлся флаг —cpu. Я обрадовался, переустановил всё заново, и — о чудо — ComfyUI запустился.
Интерфейс загрузился. Красиво. Современно. Ноды, коннекторы, всё как у людей. Я загрузил первую модель — SDXL, самую лёгкую из того, что нашёл. Нажал «Queue Prompt» и пошёл пить чай.
Вернулся через десять минут. Прогресс-бар стоял на 3%. Я подождал ещё двадцать минут. 7%. Ещё через час — 15%. Я начал подозревать, что генерация одной картинки займёт больше времени, чем написание этой статьи.
Через четыре с половиной часа я всё-таки дождался результата. На картинке было нечто, отдалённо напоминающее кота в космосе. Пиксели, шум, артефакты — но кот в космосе! Я был счастлив. Ровно три секунды. Пока не понял, что для следующей картинки придётся запускать всё заново, потому что оперативки не хватило даже на кэширование модели.
Попытка номер два закончилась крахом. OpenWrt просто убил процесс OOM-killer’ом на шестой минуте. Я попробовал уменьшить размер изображения до 256×256. ComfyUI крашнулся на загрузке модели с ошибкой «cannot allocate memory».
Тогда я пошёл ва-банк: подключил swap на USB-флешке. Система стала тормозить так, что даже ls выполнялся по пять секунд. Но ComfyUI упорно пытался работать. Через час я получил картинку 256×256 — набор цветных пятен, который нейросеть, видимо, считала очень философским.
Итог: я потратил вечер, сжёг несколько гигаватт электроэнергии (шучу, но процессор грелся будь здоров), и получил две картинки, которые нейросеть стеснялась бы показать маме.
Выводы? ComfyUI на CPU — это возможно. Но только если у вас есть неделя свободного времени, вы любите шум кулеров и не боитесь вида ошибок аллокации памяти. Если же вы хотите именно генерировать картинки, а не медитировать на прогресс-бар — лучше купите хотя бы подержанную видеокарту с 6+ гигабайтами. Или арендуйте облачный сервер.
Я же пошёл заказывать RTX 3060. OpenWrt-сервер обиженно гудит в углу.
С тех пор прошло время, и я решил рассказать историю целиком — со всеми деталями, которые в короткой версии я стыдливо опустил. Потому что у такой «неудачи» оказалось неожиданно много полезных выводов, и они пригодились мне позже, когда я уже работал с нормальным железом.
Начну с того, что меня вообще подтолкнуло к ComfyUI. Мне хотелось разобраться, как устроены генеративные сети изнутри, а не просто тыкать кнопки в каком-нибудь онлайн-сервисе. Плюс меня интересовала приватность: свои данные, своя модель, никаких сторонних сервисов. В тот момент у меня действительно не было дискретной видеокарты — домашний сервер был слабенький, а ноутбук старый, с интегрированной графикой, которая для нейросетей бесполезна. И вот с этим набором я и полез в мир генерации изображений.
Первый мой путь был по чужим гайдам. Я скачал репозиторий, настроил окружение, установил зависимости. Оказалось, что ComfyUI умеет работать на CPU, но делает это настолько медленно, что каждая картинка превращается в маленькую эпопею. Я тогда не понимал, что для CPU-режима нужно собирать отдельную версию PyTorch без CUDA, что установщик тащит кучу GPU-библиотек, которые просто занимают место. И что количество оперативной памяти играет огромную роль — модель грузится целиком в RAM, и если её не хватает, всё рассыпается.
Когда я наконец запустил интерфейс, я полчаса просто рассматривал его: граф нод, подключения, кнопки Queue Prompt. Выглядело внушительно. А потом началась настоящая боль — та самая генерация, где я в итоге потратил вечер на одну картинку. Но я не рассказал главного: процессор при этом грелся так, что я боялся за его сохранность, кулер выл как пылесос, а сам сервер на это время становился полностью бесполезным — даже пинг до него подскакивал до секунды.
Что я делал, чтобы ускорить процесс. Сначала решил, что надо уменьшить разрешение. 256×256 вместо 1024 — казалось, что это в шестнадцать раз меньше работы. На практике модель SDXL всё равно требовала кучу памяти на токены, и маленькая картинка не спасала. Потом я полез разбираться в сэмплеры и шаги: поставил минимум шагов, выбрал лёгкий сэмплер. Качеством оно, конечно, поплыло, но зато скорость выросла раза в полтора. Ещё я узнал про методы вроде Low VRAM, которые в моём случае превращались в Low RAM, и про то, что можно выгружать модель между генерациями.
Одной из самых забавных моих попыток был разгон через swap на USB-флешке. Идея была: если памяти мало, добавим её файлом подкачки. На практике флешка настолько медленная, что система превратилась в кисель. Кнопки нажимались с задержкой в несколько секунд, браузер зависал, а ComfyUI кряхтел где-то в глубине. Я честно высидел одну генерацию в таком режиме и пришёл к выводу, что swap — это не решение, а способ устроить себе дополнительные страдания.
Зато я извлёк из этой истории очень много полезного. Во-первых, я стал гораздо лучше понимать архитектуру: что такое CLIP-энкодер, что такое UNet, что такое VAE, и как они влияют на потребление памяти. Во-вторых, я научился читать лог запуска и понимать, на каком этапе упирается система. В-третьих — и это, пожалуй, главное — я осознал, что для такой задачи нужно специализированное железо, и перестал жалеть, когда потом всё-таки вложился в видеокарту.
Отдельно хочу сказать про урок, который я вынес для себя на будущее: перед тем как тащить какой-то тяжёлый инструмент на слабое железо, стоит сначала трезво оценить, а оно вообще вывезет. Это кажется очевидным, но в моменте азарта про это легко забыть. Я теперь для любых ресурсоёмких задач сначала смотрю системные требования и примеры реальных конфигураций, а уже потом ставлю.
Если ты оказался в похожей ситуации — у тебя нет видеокарты, но очень хочется попробовать ComfyUI — вот мой честный совет. Либо подготовься к тому, что скорость будет в десятки раз ниже и ты будешь получать одну картинку за полчаса-час, и воспринимай это как исследовательский эксперимент. Либо рассмотри облачные варианты: аренда GPU на время. Платишь немного, получаешь результат за минуты, и не нужно ничего устанавливать у себя. Для изучения принципов работы — отличный вариант. Я сам в итоге сначала позанимался на облаке, а потом уже купил себе видеокарту.
И ещё один момент, который я чуть не забыл: не сдавайся на середине из-за ошибок. «Cannot allocate memory», OOM-killer, зависший прогресс-бар — это не приговор, а просто сигнал, что конфигурация не подходит. Собственно, именно эти ошибки подтолкнули меня изучать, как ComfyUI работает с памятью, и это знание потом очень помогло. Каждая такая ошибка — это маленький урок.
Про то, что стало после. Когда у меня появилась RTX 3060, я был поражён контрастом: то, что на CPU занимало вечер, на GPU считалось за полминуты. Но самое смешное — я поймал себя на том, что мне не хватает того неторопливого ритуала: запустил, пошёл пить чай, ждёшь, возвращаешься к прогресс-бару, снова ждёшь. Это, наверное, была та самая медитация на прогресс-бар, о которой я писал. Но возвращаться к ней я, честно говоря, не хочу. Насладиться один раз — да, а жить с этим — нет.
Может, у тебя всё будет иначе: у кого-то процессор помощнее, у кого-то память побольше, и результаты будут приходить быстрее. Я знаю людей, которые спокойно гоняют лёгкие модели на CPU и довольны. Так что всё зависит от твоих задач и терпения. Главное — чтобы у тебя был честный ответ на вопрос «зачем мне это», и чтобы время, потраченное на генерацию, было осознанным выбором, а не сюрпризом.
В итоге моя история с ComfyUI на CPU — это не столько история про инструмент, сколько история про то, как я научился выбирать правильные инструменты под задачу и не тратить часы на то, что решается за минуты другими способами. И если она убережёт хотя бы одного читателя от вечера у прогресс-бара на Celeron с восемью гигабайтами памяти — значит, я писал её не зря.
Кстати, есть пара технических деталей, которые я не упомянул и которые могут здорово помочь, если ты всё же решишь попробовать ComfyUI на CPU. Во-первых, для CPU-режима ставь PyTorch именно CPU-версию — установщик откуда-то тащил CUDA-сборку, и она весила в разы больше. Переустановка чистой CPU-сборки заметно сократила время старта. Во-вторых, используй параметр —lowvram даже без видеокарты: он заставляет модель сбрасываться из памяти между этапами генерации, и это спасает при нехватке RAM. В-третьих, выбирай модели поменьше: вместо SDXL есть варианты вроде SD 1.5, которые весят в два раза меньше и требуют меньше ресурсов. Я этого тогда не знал и сразу полез в самую тяжёлую модель, о чём потом пожалел.
И ещё один совет от меня: обязательно смотри не только на объём RAM, но и на то, хватит ли её на всё сразу — модель, токены, изображение. У меня как раз не хватило, и это была главная причина крашей. Если есть возможность — добавь памяти или уменьшай размер модели. А если совсем не хочется мучиться — просто вспомни, что я написал выше про облачный GPU. Иногда пара рублей на аренду — это лучшая инвестиция в своё время.
И напоследок одна мысль, которая мне очень помогает. Любая «провальная» история — это на самом деле материал для статьи и для будущего опыта. Если бы у меня всё получилось с первого раза на CPU, я бы не разобрался, как устроена генерация изнутри, и не написал бы эту статью. Так что не бойся ошибаться — бойся не делать выводов из ошибок.