comfyanonymous / ComfyUI

The most powerful and modular stable diffusion GUI, api and backend with a graph/nodes interface.
https://www.comfy.org/
GNU General Public License v3.0
43.51k stars 4.61k forks source link

[Feature Request] foreach loop / reducer #3241

Open mnpenner opened 3 months ago

mnpenner commented 3 months ago

It would be great if there was some way to loop over lists so that we can process things like "SEGS" (from Impact Pack) one item at a time. For example, I can detect all the faces an image and then output that to a list of masks. For each mask I want to upscale/enhance that part of the image and paste it into the image.

I was thinking about how this would look in the UI, and I realized this is exactly like a "reducer" in many programming languages. It could look like this:

image (The mockup in the screenshot is just a shell of a node)

On the left I have some node that produces a list, doesn't matter what, and that would go into the array input. item would output the first entry from the list/array, which I could process however I please, but it would most likely be merged into accum (accumulator), which would most likely be an output image (e.g. paste the enhanced face back into the image). Then you take that output and feed it back into the input accum of the Reduce node, thus forming a loop. Reduce then runs again with the next item in the input array and the updated accum, which repeats until the list is done, and then outputs the final result on final. init is the initial value for the output accum, for the first iteration of the loop. It's optional and will be None if not specified, just like a normal reduce function.

I would implement this myself as a custom node, but as far as I know I can't output/return more than once during a single "Queue Prompt" cycle like this node needs to do.

ltdrdata commented 3 months ago

Setting up a workflow in the style of a loop is not feasible within the current execution model. Instead, by combining the Backend Cache feature of the Inspire Pack and Auto Queue, it may be possible to utilize the Reduce node.

mnpenner commented 3 months ago

I was hoping to avoid having to press queue more than once or use the Auto Queue feature because it makes transitioning to a new starter image more awkward, but if that's the best that can done for now I guess I'll have to make do. Thanks for the suggestion @ltdrdata

ltdrdata commented 3 months ago

I was hoping to avoid having to press queue more than once or use the Auto Queue feature because it makes transitioning to a new starter image more awkward, but if that's the best that can done for now I guess I'll have to make do. Thanks for the suggestion @ltdrdata

FYI, Impact Pack provides 'Queue Trigger' node. You can utilize it instead of auto queue.

mnpenner commented 3 months ago

The "Queue Trigger" node is working is working great, but "Retrieve Backend Data" keeps throwing an error when there's no data, which will always be the case on the first iteration. I've set up a conditional (custom "If Zero") node so that it uses a different image for the first iteration, so I'd much rather Retrieve Backend Data just returns None instead of complaining it can't find the key. Do you know of a workaround for that?

image

ltdrdata commented 3 months ago

The "Queue Trigger" node is working is working great, but "Retrieve Backend Data" keeps throwing an error when there's no data, which will always be the case on the first iteration. I've set up a conditional (custom "If Zero") node so that it uses a different image for the first iteration, so I'd much rather Retrieve Backend Data just returns None instead of complaining it can't find the key. Do you know of a workaround for that?

image

Now it returns None instead of raise exception.

mnpenner commented 3 months ago

It works perfectly now, thanks so much @ltdrdata !