ComfyUI получил нативные циклы: ноды Start Loop и End Loop

ComfyUI Wikinews

Ядро ComfyUI теперь зацикливает граф нативно. Соедините Start Loop с End Loop, чтобы повторять граф по числу, диапазону индексов или списку.

Ядро ComfyUI теперь может зацикливать граф без пользовательских нод. PR #16227 добавил универсальный механизм зацикливания, построенный на двух граничных нодах, Start Loop и End Loop, и он входит в релиз ядра, опубликованный 15.09.2026. Обновите ComfyUI, и обе ноды появятся в категории utilities/looping.

Как устроен цикл

Настраиваемого контейнера цикла нет. Цикл состоит из пары нод, а телом является всё, что находится между ними: всё, что соединено от Start Loop до End Loop, выполняется один раз за итерацию.

Структура цикла проверяется во время обычной валидации промпта, поэтому некорректный цикл выдаёт ошибку до начала выполнения. Каждый Start Loop должен однозначно сочетаться ровно с одним End Loop, вложенные области должны оставаться согласованными, а ветвь цикла не может выходить за пределы своего End Loop. Start Loop и End Loop объявляют себя границами цикла в схеме своей ноды, и именно это считывает проверка парности.

Во время выполнения исходное тело блокируется, и каждая итерация проецируется как свежие поставленные в очередь ноды графа, включая первую. Итерации остаются обычной работой планировщика, а не обрабатываются отдельным интерпретатором циклов, и прогресс итераций отображается на ноде как Iteration n / total.

Три способа задать число итераций

Вход mode ноды Start Loop определяет, как формируется счётчик итераций, и показываются только входы выбранного режима.

РежимПо чему итерируетсяСобственные входы
simpleФиксированное число повторовnum_iterations (по умолчанию 4)
ForЧисловой диапазон индексовstart_iteration_index (по умолчанию 0), max_iteration (по умолчанию 4, не включая верхнюю границу), step (по умолчанию 1)
ListОдин проход на каждый элемент прикреплённого спискаlist

step не меньше 1, а значение 0 вызывает ошибку. Если вычисленное число итераций равно нулю, тело цикла не выполняется, а is_last возвращает true.

Что возвращает Start Loop

ВыходЗначение
iteration_indexИндекс текущей итерации
is_firstTrue на первой итерации
is_lastTrue на последней итерации
list_itemТекущий элемент в режиме List, в остальных режимах пусто
current_iteration_valueЗначение, передаваемое через цикл, для этой итерации

is_first служит обычной точкой входа для отдельного первого прохода, например чтобы инициализировать видео-цикл исходным кадром вместо последнего кадра предыдущего окна.

Start Loop и End Loop, охватывающие небольшой граф генерации изображения

Минимальный случай: один Start Loop, небольшое тело генерации, один End Loop. Passthrough ноды Save Image подключён к входу termination, поэтому она всё равно выполняется один раз за итерацию.

Замыкание цикла

End Loop закрывает область видимости и определяет, что из неё выходит.

ВходРоль
output_valueЗначение, возвращаемое после завершения цикла
next_iteration_valueОтправляется обратно в Start Loop как current_iteration_value для следующей итерации
accumulateКогда включено, возвращается output_value каждой итерации, а не только последней
входы terminationДинамически расширяемые входы для превью, сохраняющих нод и других побочных эффектов, которые должны выполняться на каждой итерации. Их значения не возвращаются

У End Loop один выходной сокет, тип которого следует за output_value. При включённом accumulate значения выдаются как обычный список ComfyUI, объединённый в порядке итераций.

Входы termination решают частую неожиданность: нода Preview Image или Save Image внутри тела иначе сработала бы только на последней итерации, поскольку более ранние спроецированные тела перезаписываются. Подключение passthrough этой ноды к входу termination сохраняет её выполнение один раз за итерацию и удерживает её внутри границ цикла.

Накопление выхода каждой итерации

При включённом accumulate все четыре генерации возвращаются одним списком. Preview Image подключена как termination, поэтому каждая итерация видна по мере завершения.

Изменение работы на каждой итерации

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

Режим For задаёт разное разрешение на каждой итерации

Режим For подаёт iteration_index в разрешение, а результаты разного размера накапливаются в конце.

Передача состояния между итерациями

initial_iteration_value задаёт начальное передаваемое значение на первой итерации, а next_iteration_value каждой итерации становится current_iteration_value следующей итерации. Это весь канал состояния, и на каждую пару Start и End Loop приходится ровно один такой канал.

Чтобы передавать больше одного значения, поместите их в список. Существующая нода Create List теперь принимает разнородные входы, поэтому одно передаваемое значение может хранить смешанное состояние, например изображение и текстовый промпт, который его создал. Этот приём поддерживают две ноды в категории utilities:

  • Create List: собирает передаваемое значение из разнородных входов.
  • Get Item From List: новая нода в том же релизе. Она принимает список и индекс и возвращает этот элемент как обычное значение, поэтому компоненты передаваемого состояния можно распаковать внутри следующей итерации.
Две генерации, передающие друг другу изображение и промпт через передаваемое значение

Генерация Z-Image и vision-language подписи передаются туда-обратно через одно передаваемое значение с изображением и текстом.

Вложенность и кэширование

parent_iteration в Start Loop является force-входом: подключите к нему iteration_index внешнего цикла, чтобы вложить цикл в другой. Вложенность задаётся явно, а не выводится автоматически, и каждому Start Loop по-прежнему нужен ровно один End Loop.

cache_iterations в Start Loop относится к расширенным настройкам и по умолчанию отключён. Если его включить, спроецированные ноды итераций могут переиспользовать кэшированные результаты из более ранних выполнений. Сама нода End Loop является обычной исполняемой нодой, поэтому её финальный выход в любом случае кэшируется обычным образом.

Внутренний цикл, вложенный во внешний цикл, управляемый списком

Внешний цикл в режиме List по промптам, внутри которого через parent_iteration вложен цикл генерации.

Примеры для видео и латентов

Механизм создавался с расчётом на расширение видео, где каждое окно зависит от предыдущего. Два опубликованных примера напрямую показывают этот приём.

Сцепление видео-окон через передаваемый последний кадр

Видео-цикл из последнего кадра в первый: исходное изображение инициализирует initial_iteration_value, финальный кадр каждого сгенерированного окна становится первым кадром следующего окна, а батчи кадров накапливаются и перегруппировываются в один клип.

Передача латента через цикл и постепенное изменение LoRA

Латент передаётся напрямую через цикл при выключенном accumulate, поэтому возвращается только финальный латент, плюс ленивый переключатель для обработки первой итерации и сила LoRA, которая постепенно меняется по мере выборки.

Самая простая отправная точка, цикл генерации на четыре итерации без передаваемого состояния, это одна пара Start и End Loop:

Где находятся ноды

Start Loop и End Loop являются базовыми нодами в категории utilities/looping и поставляются вместе с самим ComfyUI, поэтому пакет узлов не нужен. Create List и Get Item From List находятся в utilities. Поведение зацикливания описано на официальных страницах встроенных нод Start Loop и End Loop.

Существующие рабочие процессы не затрагиваются: циклы включаются по желанию, и граф без пары Start и End Loop ставится в очередь точно так же, как раньше.

Комментарии

Войдите через GitHub, чтобы участвовать в обсуждении.

Загрузка комментариев…
ComfyUI получил нативные циклы: ноды Start Loop и End Loop | ComfyUI Wiki