Nodes/ComfyUI-LoopedDiT/Looped-DiT Loop Sweep
ComfyUI Node

Looped-DiT Loop Sweep

Settle the loop-depth argument in one queue

By hiroki-abe-58·Created 14 days ago·Updated 14 days ago· 0
Looped-DiT Loop Sweep
  • model
  • images
  • grid
  • report
◄prompta red cube on top of a blue sphere►
◄seed0►
◄loops1, 2, 4►
◄steps100►
◄cfg6.0►

Loop depth is the one genuinely novel knob on Looped-DiT, and it's also the one nobody has a feel for. Does running those shared blocks four times instead of once give you a better image, a different image, or just a slower one? If you test it by hand you'll queue Generate, screenshot, change loops, requeue, and quietly change the seed at some point and waste twenty minutes.

Loop Sweep exists so you don't. It runs the same prompt, the same seed, the same initial noise, the same steps and the same CFG at several loop depths, back to back, and hands you the comparison as images, a labeled grid and a JSON report. Upstream's sample.py does the same thing with --loops 1 2 3 4; this is that command, as a node.

What it's actually doing

This is not a batch trick and not a latent-space interpolation. Each loop depth is a complete, independent sampling run - its own text encode, its own noise draw, its own 100 Euler steps with both CFG passes. The pack makes the comparison fair by re-seeding the RNG to your seed before every run, inside a forked RNG context, so every depth starts from a byte-identical noise tensor. The report proves it: it hashes each run's initial noise and emits same_initial_noise: true when they all match.

What changes between runs is only the block count per model pass - 6 + 5 × loops + 6 for B/16, so 17, 22 and 32 blocks at depths 1, 2 and 4. Everything else is held constant. That's the whole experiment.

Because each depth is a full run, the time multiplies. On the author's RTX 5090 a loops 1/2/4 sweep takes about 33.5 seconds from queue to finished files, which is just the three single-image times added up. A sweep of eight depths costs you eight images' worth of generation, so keep the list short.

Inputs and outputs

Inputs are the same set as Generate, with one important difference:

  • loops - a plain text field, not an integer. Default "1, 2, 4". Comma-separated, at most 8 depths, each between 1 and 16. Semicolons work too if that's your habit. Anything non-numeric raises an error rather than being skipped.
  • model, prompt, seed, steps, cfg - identical to Generate, official values 100 steps and CFG 6.0. Fix the seed here; if the post-generate control is set to randomize, you'll get a different experiment every queue and no way to compare.

Outputs:

  • images - every render as one stacked batch, in the order you listed the depths. Save Image on this writes one file per depth, so label them yourself or use the grid.
  • grid - a single wide image, each render side by side with a label bar above it reading loops N | blocks/pass | steps ×passes. This is the one you actually look at.
  • report - JSON: same_initial_noise, the noise hash(es), which checkpoint and T5 release were used, and the full per-run reports from each depth, hashes and timings included.

Install

Same pack, same two steps:

cd ComfyUI/custom_nodes
git clone https://github.com/hiroki-abe-58/ComfyUI-LoopedDiT
python custom_nodes/ComfyUI-LoopedDiT/tools/download_models.py --models-dir models

Restart ComfyUI, then load workflows/gui/looped_dit_loop_sweep.json from the repo - it's already wired to a Looped-DiT Loader and saves the grid. No extra Python packages are involved; the grid is drawn with the Pillow that ComfyUI already has. You need ComfyUI 0.38.0+ and a CUDA GPU, same as the rest of the pack, and the 512×512 / batch-1 limits still apply per image.

Using it like you mean it

Run the sweep once per prompt you care about, read the grid, then move to Generate with your chosen depth. That's the intended loop, and it turns an unknowable into a two-minute decision.

Two things to expect. First, more loops is not more quality. The author's own demo set has loops 2 drawing two lanterns when the prompt asked for one, and a bicycle prompt where "on the left side of the door" isn't clearly followed at any depth. You're looking for the depth that holds your composition, not the biggest number.

Second, don't expect the sweep to survive a cancel. Hit cancel mid-sweep and the remaining depths never run - you get no partial output, not even the images that already finished. If you're on a slow card, sweep two depths at a time instead of six.

One practical note on the images output: the underlying model is still batch-1 per pass, so the "batch" is just the runs stacked in the order you asked for. The grid, meanwhile, is one single wide image - wire it downstream and it's treated as one frame, labels and all.

Categorysampling/looped-dit

Inputs (6)

NameTypeDefaultDescription
modelLOOPED_DIT—
promptSTRINGa red cube on top of a blue sphere—
seedINT00–18446744073709550000—
loopsSTRING1, 2, 4Comma-separated loop depths, at most 8. Loop depth = how many times the shared middle blocks run inside ONE denoising step (6 + 5 x loops + 6 blocks per model pass for B/16). It is not the number of sampling steps. The models were trained at 4.
stepsINT1001–1000Euler steps (official: 100)
cfgFLOAT6.01–30Classifier-free guidance (official: 6.0). The unconditional pass uses the same text with a zero mask.

Outputs (3)

NameTypeDescription
imagesIMAGE—
gridIMAGE—
reportSTRING—