LoRA Test — Grid Collector
The Grid-Maker That Waits Until Every Cell Is Filled
- images
If you've ever compared LoRAs by juggling a wall of SaveImage nodes and squinting at filenames, LoRATestGridCollector is the node that ends that. It's the sink at the end of ComfyUI-LoRA-Lens' hand-built test flow: you feed it each generated image as the batch runs, and it quietly stashes the image, waits until the whole prompt×LoRA matrix is done, then renders clean, labeled comparison grids for you. It never outputs to the graph - it is the end of the line, an output node that returns preview images to the UI instead.
How it works. Every image that arrives is saved as a "cell" - a PNG plus a JSON sidecar - into ComfyUI/output/LoRA_Test_Grids/<run_id>/_cells/, named by position like p000_l002.png. The position is what matters: prompt_index and lora_index tell it where in the matrix this image belongs, and prompt_count/lora_count tell it the shape of the whole thing. When all cells for one prompt row exist, it renders a per-prompt labeled grid. When every cell in the matrix exists, it renders a master grid with prompt excerpts and LoRA labels, writes a manifest.json, and fires a lorapromptqueue.matrix_complete websocket event that the test controller (and the dashboard) listen for to know the run is done and analysis can start.
Two mechanical details worth knowing. It's an output node, so ComfyUI already treats it as always-run - but its IS_CHANGED also returns NaN on purpose, the classic idiom (covered in the KB's comfyui-node-plumbing.md) that defeats the execution cache so a collector can never be skipped. Second, all the cell-writing and grid-rendering happens under a lock, because in a batched run multiple instances may execute close together.
Inputs that matter:
images- the current cell's image, straight from your VAE-decode.run_id- names the output folder. Make it unique per run. Reusing one is how stale cells poison a grid.prompt_index/lora_indexandprompt_count/lora_count- the cell's position and the matrix's shape.prompt_label,prompt_text,lora_label- the captions that go on the grid.grid_mode-per_prompt_and_master(both),master_only,per_prompt_only, oroff. Off still saves every cell; it just never renders a grid.cell_width,label_height,font_size- grid cosmetics (width in 16px steps, 160–1024).
The trap most people hit: run_id collisions. The node accumulates cells per run folder, so if you reuse a run_id for a new matrix, leftover cells from the previous run can make a row look "complete" when it isn't - or your master grid silently mixes old and new images. Treat run_id like a seed: new run, new id.
Installation is the shared pack story: ComfyUI Manager (search "ComfyUI LoRA Lens"), or git clone https://github.com/astropuzzo/ComfyUI-LoRA-Lens.git into custom_nodes, install requirements.txt with ComfyUI's own Python, restart. The face-analysis dependencies (insightface, onnxruntime-gpu) only matter if you use the analyzer - the grid collector itself runs on stock ComfyUI, which is part of why it's a handy node to have even if you never touch the ranking features.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| run_id | STRING | manual_run | — |
| prompt_index | INT | 00–10000 | — |
| lora_index | INT | 00–10000 | — |
| prompt_count | INT | 11–10000 | — |
| lora_count | INT | 11–10000 | — |
| prompt_label | STRING | Prompt 1 | — |
| prompt_text | STRING | — | |
| lora_label | STRING | LoRA | — |
| output_prefix | STRING | LoRA_Test | — |
| grid_mode | COMBO | 4 options: per_prompt_and_master, master_only, per_prompt_only, off | |
| cell_width | INT | 384160–1024 | — |
| label_height | INT | 6432–180 | — |
| font_size | INT | 2210–64 | — |
Outputs (0)
No outputs