Гайды

Как масштабировать воркфлоу ComfyUI до тысяч генераций

Воркфлоу, который даёт десять удачных картинок в браузере, ещё не готов к тысяче. Разбираем, что меняется на объёме: batch и очередь, API, несколько видеокарт, аренда GPU и брак.

Обновлено 19 октября 2026 г. · 9 мин чтения

Десять пробных картинок в ComfyUI делаются парой кликов. Тысяча требует другой схемы: пакетная генерация через очередь, а не через кнопку, скрипт, который ходит в API ComfyUI, по процессу на каждую видеокарту, аренда GPU, когда своих карт мало, и план на брак, который придётся выбросить.

Текст написан по практике: мы гоняем клиентские воркфлоу на объёме, небольшие заказы на своих видеокартах, крупные на арендованных через Vast.ai. Код — обычный Python поверх HTTP-эндпоинтов, которые есть в ComfyUI из коробки.

Batch size или очередь: два вида batch в ComfyUI

Два разных параметра, которые часто путают:

  • Batch size — поле batch_size у ноды Empty Latent Image (от 1 до 4096). Сэмплер обрабатывает все латенты за один проход.
  • Очередь — счётчик запусков рядом с кнопкой Run или несколько вызовов API. Каждый запуск отдельная задача, ComfyUI выполняет их друг за другом. Загруженные модели остаются в памяти между запусками, пока её хватает, и повторно не грузятся.
Batch sizeОчередь (отдельные запуски)
Видеопамятьрастёт с каждым латентом; перебор — out of memoryкак у одного запуска
Скоростьможет лучше загрузить GPU на лёгких моделях и малых разрешенияхнебольшие накладные на запуск, когда модели уже в памяти
Сидыодин сид на всю пачкусвой сид у каждого запуска
Повторить одну картинкутот же сид и batch size или нода LatentFromBatchперезапуск с её сидом
При ошибкетеряется вся пачкатеряется одна картинка

Строка про сиды важнее, чем кажется. ComfyUI генерирует шум для всей пачки из одного сида, поэтому пятую картинку из пачки в восемь можно повторить только как «сид X, пачка из 8, индекс 4». Когда дойдёт до перегенерации брака, отдельные запуски со своими сидами намного удобнее.

Считайте секунды на одну картинку, а не на запуск. Поднимайте batch size на рабочей карте, пока видеопамять не заполнится или время на картинку не перестанет падать, а объём набирайте очередью. В видео-графах почти всегда один ролик на задачу.

Ловушка: настройка сида control after generate (fixed, increment, randomize) работает только в интерфейсе. Через API сид из JSON используется как есть, менять его должен ваш скрипт.

Промпты из файла, списки сидов и входных картинок

Тысяча запусков с одним промптом и сидом — это одна картинка тысячу раз; ComfyUI и вовсе кэширует одинаковую задачу и не сохраняет новый файл. Объём получается, когда что-то меняется:

  • Сиды. Фиксированный список или начальное значение плюс номер задачи, чтобы любой результат можно было повторить.
  • Матрица промптов. Объект × стиль × фон: 10 × 5 × 4 — уже 200 комбинаций. Собирайте её скриптом.
  • Промпты из файла. В интерфейсе это умеют пакеты кастомных нод, например Load Prompts From File из Inspire Pack. Для больших запусков скрипт, читающий текстовый файл или CSV, проще контролировать и продолжить после сбоя.
  • Входные картинки. В графах image-to-image, image-to-video и правки картинки каждый входной файл — отдельная задача. Положите файлы в папку input ComfyUI (или загрузите через POST /upload/image) и подставляйте имя в ноду LoadImage.

Ведите манифест: строка на задачу с промптом, сидом, входом, выходом и статусом. По нему вы продолжите после падения и перегенерируете брак с новыми сидами.

API ComfyUI: запуск воркфлоу скриптом

ComfyUI — веб-сервер, а браузерный интерфейс лишь один из его клиентов. Скрипт может ходить в те же эндпоинты.

  1. Экспорт в API-формате: File → Export Workflow (API) (в старых версиях Save (API Format), который появлялся после включения dev mode в настройках). Обычный JSON воркфлоу сервер не примет. В API-формате ключи — id нод с class_type и inputs; связь ["4", 0] означает выход 0 ноды 4. Выпишите id нод, которые будете менять.
  2. Постановка в очередь: POST /prompt с телом {"prompt": <API JSON>} возвращает prompt_id. Сломанный граф получит HTTP 400 с node_errors ещё до очереди.
  3. Ожидание: GET /history/{prompt_id} отдаёт пустой объект, пока задача не закончилась, потом выходы нод и status. Для прогресса откройте ws://host:8188/ws?clientId=<id> и передайте тот же client_id в /prompt: придут progress, executing (с node: null, когда граф выполнен), execution_success и execution_error.
  4. Скачивание: у каждого файла есть filename, subfolder и type; их передают в GET /view.

Минимальный скрипт: каждая строка prompts.txt с каждым сидом, задачи раскладываются по двум серверам ComfyUI, только стандартная библиотека.

import copy, json, time, urllib.parse, urllib.request
from pathlib import Path

SERVERS = ["127.0.0.1:8188", "127.0.0.1:8189"]  # по процессу ComfyUI на видеокарту
PROMPT_NODE, SEED_NODE = "6", "3"  # id нод из вашего JSON в API-формате
SEEDS = [1001, 1002, 1003]

workflow = json.loads(Path("workflow_api.json").read_text())
prompts = [p.strip() for p in Path("prompts.txt").read_text().splitlines() if p.strip()]
out = Path("out")
out.mkdir(exist_ok=True)

def call(server, path, payload=None):
    data = json.dumps(payload).encode() if payload is not None else None
    req = urllib.request.Request(f"http://{server}{path}", data=data,
                                 headers={"Content-Type": "application/json"})
    with urllib.request.urlopen(req) as resp:
        return json.loads(resp.read())

jobs = []
for i, text in enumerate(prompts):
    for seed in SEEDS:
        wf = copy.deepcopy(workflow)
        wf[PROMPT_NODE]["inputs"]["text"] = text
        wf[SEED_NODE]["inputs"]["seed"] = seed
        server = SERVERS[len(jobs) % len(SERVERS)]
        prompt_id = call(server, "/prompt", {"prompt": wf})["prompt_id"]
        jobs.append((server, prompt_id, f"{i:04d}_{seed}"))

for server, prompt_id, tag in jobs:
    while not (history := call(server, f"/history/{prompt_id}")):
        time.sleep(2)
    entry = history[prompt_id]
    if entry["status"]["status_str"] != "success":
        print("failed:", tag)
        continue
    for node_output in entry["outputs"].values():
        files = [f for v in node_output.values() if isinstance(v, list)
                 for f in v if isinstance(f, dict) and f.get("type") == "output"]
        for f in files:
            query = urllib.parse.urlencode({k: f[k] for k in ("filename", "subfolder", "type")})
            with urllib.request.urlopen(f"http://{server}/view?{query}") as resp:
                (out / f"{tag}_{f['filename']}").write_bytes(resp.read())

6 и 3 — нода промпта и KSampler стандартного воркфлоу ComfyUI; в вашем графе id другие, а у части нод-сэмплеров поле называется noise_seed. Задача, не прошедшая проверку, бросит HTTPError, в теле ответа будут node_errors.

Что мы усвоили на реальных запусках:

  • История живёт в памяти процесса ComfyUI. После перезапуска файлы на месте, а связь «задача → файл» потеряна. Пишите prompt_id в манифест сразу.
  • Тысячи задач ставьте порциями и отдавайте следующую серверу с самой короткой очередью (GET /queue).
  • У ComfyUI нет авторизации. Не открывайте порт наружу, подключайтесь через SSH-туннель или прокси с паролем.

ComfyUI на нескольких видеокартах

Один процесс ComfyUI генерирует на одной видеокарте. Под объём запускайте по процессу на каждую карту, каждый на своём порту:

python main.py --cuda-device 0 --port 8188 --output-directory /data/out0 --temp-directory /data/tmp0
python main.py --cuda-device 1 --port 8189 --output-directory /data/out1 --temp-directory /data/tmp1
  • --cuda-device оставляет процессу видимой только указанную карту.
  • Папки вывода и временных файлов — свои у каждого процесса: ComfyUI чистит temp при старте и нумерует файлы по содержимому папки вывода, общие папки дают коллизии.
  • Папку моделей можно сделать общей, но каждый процесс грузит свою копию моделей в видеопамять и в оперативную память.

С конца мая 2026 года в ComfyUI есть и встроенная нода MultiGPU CFG Split, которая делит одну генерацию между одинаковыми картами. По документации ей нужны одинаковые карты поколения Ampere или новее, она работает с перечисленным набором моделей (среди них WAN 2.2 и SDXL) и ничего не даёт при CFG 1, то есть дистиллированным воркфлоу вроде LoRA типа Lightning не поможет. Она ускоряет одну генерацию; для тысячи картинок отдельные процессы проще, и падение одного не останавливает остальные.

Несколько машин — та же схема с большим числом адресов в SERVERS, если везде одна версия ComfyUI, одни коммиты нод и одни файлы моделей.

ComfyUI в облаке или локально: какие лимиты проверить

Локально вы контролируете всё, но потолок задают одна-две карты. Облачные сервисы с ComfyUI и serverless-GPU снимают вопрос железа и добавляют свои ограничения. Проверьте:

  • Кастомные ноды и модели: часто доступен только одобренный набор нод, загрузка своих LoRA может быть ограничена.
  • Параллельность: сколько задач на аккаунт идёт одновременно. Это и есть ваша скорость.
  • Таймауты: предельное время задачи, в которое упираются длинные видео-графы.
  • Холодный старт: на serverless первая задача после простоя грузит модели.
  • Единица оплаты: секунды GPU, задачи или кредиты. От неё зависит цена брака.

Аренда целой машины с GPU — середина: любые ноды и модели, но настройка на вас.

ComfyUI на Vast.ai: чему нас научила аренда GPU

Vast.ai — маркетплейс хостов с видеокартами. На крупных заказах мы держим там несколько инстансов параллельно. Вот на чём теряли время:

  • Диск задаётся при создании. Увеличить его потом Vast не даёт, а хранение оплачивается, даже когда инстанс остановлен. Модели видео-графа занимают десятки гигабайт; наше правило — примерно полтора объёма всех моделей плюс место под результаты и не меньше 50 ГБ.
  • Холодный старт — минуты, и они оплачиваются. Запуск контейнера, установка ComfyUI и кастомных нод, затем скачивание моделей — обычно самая долгая часть, зависящая от сети хоста. Поэтому один инстанс должен брать большую часть запуска.
  • Хосты не одинаковые. Наш видео-граф делает апскейл через NVIDIA RTX Video Super Resolution, и на части хостов эта нода не запускалась, хотя CUDA работала. Теперь мы проверяем такие ноды сразу после старта, до скачивания моделей, и при сбое меняем хост. Reliability score у Vast — фильтр, а не гарантия.
  • Закрепляйте версии. Кастомные ноды — из git на закреплённых коммитах, ComfyUI — закреплён под каждый воркфлоу. У нас падал загрузчик модели, потому что закреплённый коммит ComfyUI был старше её поддержки. Установка без пинов рано или поздно поменяет результат посреди запуска.
  • Исходите из того, что инстанс может пропасть. Выгружайте результаты по ходу работы (мы используем облачное хранилище) и держите манифест отдельно.

Контроль брака на объёме

На тысяче картинок вопрос в том, какая доля негодна и кто её найдёт.

  1. Сначала пробная партия: 20–50 результатов по всей матрице промптов и входов, а не первые 50 строк. Её мы согласуем с клиентом до массового запуска.
  2. Посчитайте долю брака. Если негодна каждая пятая, для 1 000 годных генерируйте около 1 250, а худшие промпты перепишите.
  3. Заморозьте настройки. Смена моделей или параметров посреди запуска — новая пробная партия.
  4. Отсматривайте глазами: руки и лица, артефакты, сломанный текст, уход персонажа от референса, мерцание и швы в видео. Мы отсматриваем вручную, сеткой, отсортированной по промпту, — плохой промпт виден целым блоком.
  5. Перегенерируйте брак по манифесту с новыми сидами.

Из чего складывается цена 1 000 генераций

GPU        = t × N ÷ (1 − r) ÷ 3600 × P
Итого      ≈ GPU + настройка + пробная партия + отсмотр

t — секунды на генерацию, N — сколько нужно годных результатов, r — доля брака, P — цена часа GPU.

  • t нельзя взять из чужого бенчмарка: оно зависит от модели, разрешения, шагов, графа и карты. Замеряйте на пробной партии.
  • Несколько видеокарт сокращают время до результата, но не число GPU-часов.
  • Настройка — холодные старты, умноженные на число инстансов, плюс часы на установку и отладку. На малых объёмах это главная статья.
  • Отсмотр — время человека, оно растёт вместе с N.

Картинки у нас стоят от $0.10 за штуку на любом чекпойнте и LoRA. Настройка и пробная партия входят в заказ, минимальный заказ $50.

Когда проще отдать нам

Если рабочий воркфлоу у вас есть и нужен объём, а не новое хобби в администрировании GPU, пришлите его нам. Мы разворачиваем шаблон как есть — ноды на закреплённых коммитах, модели с Hugging Face, Civitai или по прямой ссылке, — делаем пробную партию на согласование, гоним объём на своих или арендованных видеокартах, вручную отсматриваем и сдаём архивом или ссылкой на папку. Если модель платная, закрытая или её лицензия запрещает коммерческое использование, скажем до старта (подробнее — о лицензиях моделей с Civitai).

Пришлите воркфлоу, задачу и объём через форму заявки.

 FAQ

Вопросы

Q01 Что быстрее: большой batch size или больше запусков в очереди?

Зависит от модели и видеокарты. Batch может лучше загрузить GPU на лёгких моделях и малых разрешениях, но съедает видеопамять, делит один сид на всю пачку и падает целиком. Замерьте секунды на одну картинку в обоих вариантах на своей карте и оставьте тот, где их меньше.

Q02 Может ли ComfyUI считать одну картинку на двух видеокартах?

По умолчанию один процесс ComfyUI работает на одной видеокарте. В свежих версиях есть встроенная нода MultiGPU CFG Split, которая делит одну генерацию между одинаковыми картами, но выигрыш она даёт только при CFG выше 1. Для объёма проще поднять по процессу на каждую карту: так падение одного не останавливает остальные.

Q03 Есть ли у ComfyUI API?

Есть: сервер, с которым работает браузер, и есть API. POST /prompt ставит в очередь воркфлоу, экспортированный в API-формате, /history отдаёт результат, /view скачивает файлы, websocket показывает прогресс. Авторизации у него нет, поэтому порт нельзя открывать в интернет.

Q04 Сколько поднимается арендованная видеокарта под ComfyUI?

Минуты, а не секунды: нужно запустить контейнер, поставить ComfyUI и кастомные ноды, скачать модели. Больше всего времени уходит на модели, и это зависит от сети конкретного хоста, а GPU оплачивается всё это время.

Q05 Сколько стоит 1 000 картинок, если отдать генерацию вам?

Картинки у нас от $0.10 за штуку на любом чекпойнте и LoRA, то есть 1 000 картинок от $100. Настройка и пробная партия входят в заказ, минимальный заказ $50.

 Связь

Обсудить проект

Расскажите о шаблоне и объёме. Мы ответим туда, куда вы укажете.

Отправляя заявку, вы соглашаетесь с политикой конфиденциальности.