Illustrious Caption Edit (Safe Copy)
Bulk caption surgery that can't destroy your originals
- dataset
- dataset
- edit_report
Auto-tagging gets you a caption on every image. It does not get you good captions, and the difference is where a character LoRA is won or lost. IllustriousCaptionEdit is the node where you fix the machine's work: add a trigger to everything, delete the tags that should be identity rather than description, and rename tags the tagger got almost right.
The "(Safe Copy)" in its display name is not decoration. Every edit produces a new dataset run. Your input run is read and never written to, which means an edit you regret is a deleted output folder and a re-queue instead of a re-tagged dataset.
How it works
With enabled on, the node resolves the run, works out which images you selected, and computes each new caption in memory: add_tags go in front, existing tags pass through the replacement map, anything on the removal list is dropped, duplicates are eliminated. Matching is normalised - trimmed, underscores to spaces, case-folded - so Long_Hair and long hair are the same tag here. Tag order from the tagger is otherwise preserved, keeping the highest-confidence tags near the front.
Captions survive as UTF-8 and each is size-checked before it lands, so a runaway replacement map fails loudly rather than writing a 3 MB text file next to a PNG. Then the whole dataset is copied into a fresh run labelled caption_edit, the new captions are written into the copy, and the copy carries a parent_run pointer back at the original. With enabled off you get NOT_EDITED and your dataset passes through untouched - which is exactly what you want in the pack's reviewed-training workflow, where the node sits in the graph but should stay inert unless you're actually editing.
The fields, and how not to hurt yourself with them
enabled defaults to false. Nothing happens until you flip it. Good default; you will queue the graph five times while setting things up.
selection takes either all or a comma-separated list of prepared filenames - 000004.png, 000017.png - copied out of the preview node's report. Anything that isn't all and isn't an exact filename in the run is a hard error. There's no wildcard, no glob, no "first N."
add_tags is a comma-separated list added to every selected caption. Put your trigger here after the tagger has run, and remember the tagger's own trigger field does the same thing - pick one place, or you'll get the tag twice (it dedupes, so no disaster, just confusion).
remove_tags is the comma-separated kill list. This is the important one for character work: long hair, purple eyes, red ribbon are traits you want the LoRA to absorb as part of the identity, not features you might prompt for separately. The captioning rule is the same everywhere on the Illustrious line - describe what should stay variable, leave what should be fixed undescribed.
replace_tags_json is a JSON object of string to string, e.g. {"grey hair": "silver hair", "solo": ""}. Each value has to be a single tag - no commas, no newlines - and an empty value deletes the tag outright. That restriction is enforced, and it's the field people bounce off, because the honest answer is that this node's textbox UI is the weakest part of the pack. For anything more involved than find-and-replace, edit the .txt files in the run's images/ folder with your normal text editor and then pass the dataset through as-is.
Outputs
dataset is the new run's handle - wire it to the audit or straight to the trainer. edit_report is JSON with the status (EDITED_COPY or NOT_EDITED), the source run name, the new run name, and how many images were selected. That new run name is what you paste into IllustriousDatasetOpen next time, which is how you train against your hand-edited captions without ever re-importing or re-tagging.
Install
Manager, searching ComfyUI-IllustriousLoRATools (Illustrious LoRA Tools), or:
cd ComfyUI/custom_nodes
git clone https://github.com/katorikonoe-ai/ComfyUI-IllustriousLoRATools
pip install -r ComfyUI-IllustriousLoRATools/requirements.txt
Install with ComfyUI's Python; the pack's dependency list is long (diffusers, transformers, peft, accelerate, bitsandbytes, onnxruntime, huggingface-hub, safetensors) and it must not replace your CUDA PyTorch. Keep native/, web/ and crop_routes.py with __init__.py - the README warns about partial installs specifically. Restart the server; the node appears under Katori/Illustrious Native Training.
Where people get burned
The copy-on-write design means every edit costs a full duplicate of your dataset on disk, so a loop of small edits will fill an SSD faster than you expect.
Selection typos are the most common failure: an error like Select all or exact prepared image filenames from the preview report means you typed an index or a source filename instead of the prepared one (000042.png, not refsheet.jpg).
And the one that bites after cropping: the edit node will happily keep a tag that describes something you just cropped out of the frame. If your crop removed the background, your caption still says outdoors, and the audit will not catch it, because the audit only checks that text exists.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| dataset | ILLUSTRIOUS_DATASET | — | |
| enabled | BOOLEAN | false | — |
| selection | STRING | all | — |
| add_tags | STRING | — | |
| remove_tags | STRING | — | |
| replace_tags_json | STRING | {} | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| dataset | ILLUSTRIOUS_DATASET | — |
| edit_report | STRING | — |