joy diretory caption
The Joy Caption batch node that builds your LoRA dataset
- joy_pipeline
- image_files
- captions
Name aside ("diretory" - a typo the author kept), this is the workhorse of the ymc_node_joy pack. Point it at a folder of images and it captions every one of them with Joy Caption, one pass through the model, and optionally drops a .txt file next to each image. That's the entire LoRA-dataset pipeline: images in, natural-language captions out, in exactly the format kohya, ai-toolkit and OneTrainer expect.
Why you'd reach for it
If you're training a LoRA on an LLM-encoder model - Flux, Qwen-Image, Z-Image - your training captions should be natural language, not tags. Joy Caption is the community's go-to for writing those, and the KB's training guidance is blunt: captioning quality beats dataset size, and BLIP is not an acceptable substitute. This node is how you caption 50 images without clicking through a single one. Set it up, run it, go make tea - each image takes a couple of seconds plus the model load, depending on your GPU.
How it works
You feed it the JoyPipeline from the joy model loader and an image_dir path. It lists the images in that folder (only .png, .jpg, .jpeg, .webp, and only the top level - no recursion), loops through them with the model already loaded, and produces a caption per image. If an image fails to open, it logs the error, writes a ,,, placeholder, and keeps going - one bad file won't kill your batch.
Two outputs come back: image_files (the full paths, one per line) and captions (the matching captions, one per line). If you turned on save_caption, you'll also find imagename.txt files sitting right next to the source images.
The inputs that matter
- joy_pipeline - from the model loader. No loader, no captions.
- image_dir - the absolute path to your folder. This is the one beginners mangle; see below.
- trigger - your LoRA trigger word, prepended to every caption as
trigger, <caption>. This is huge for training: a trigger word makes the captioner include your concept token so it doesn't get baked into the model as background. - save_caption - write the
.txtfiles. You want this on for real training runs. - prompt - the instruction the LLM follows, like "A descriptive caption for this image". Defaults to a plural version since you're captioning a batch.
The same cache toggle exists here, but it's far less of a footgun: the directory node clears the pipeline only after the whole folder is done, so a batch runs in one model load regardless. Leave it off.
Where people get burned
The most common failure is Directory not found - the node takes a plain filesystem path, not a ComfyUI output directory, so paste the full path (/home/you/images/training_set, or C:\Users\... on Windows). Watch for the folder-not-recursive behavior: subfolders are silently ignored. And after a run, scan the generated captions for ,,, - those are the images that errored, and you want to know before you train on a dataset with holes in it.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/YMC-GitHub/ymc_node_joy
Restart ComfyUI and let the deps auto-install; or grab it via ComfyUI Manager under "ymc_node_joy". Model setup is shared with the rest of the pack - the loader auto-downloads SigLIP and your chosen Llama on first run, but you must drop models/Joy_caption/image_adapter.pt in place yourself or nothing loads.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| joy_pipeline | JoyPipeline | — | |
| image_dir | STRING | — | |
| prompt | STRING | A descriptive caption for these images | — |
| max_new_tokens | INT | 102410–4096 | — |
| temperature | FLOAT | 0.700–1 | — |
| cache | BOOLEAN | false | — |
| trigger | STRING | — | |
| save_caption | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image_files | STRING | — |
| captions | STRING | — |