Nodes/Joy Caption Two - PixelaiLabs Edition/Simple LLM Caption (Batch)
ComfyUI Node

Simple LLM Caption (Batch)

Caption a whole folder of images and get training-ready 1.png / 1.txt pairs

By Pixelailabs·Created 11 months ago·Updated 10 months ago· 12
Simple LLM Caption (Batch)
  • pipeline
  • STRING
input_directory
output_directory
caption_type
caption_lengthmedium
temperature0.7
max_new_tokens300
save_as_txttrue
lora_trigger
gender_age_replacement
hair_replacement
body_size_replacement
remove_tattoosfalse
remove_jewelryfalse
prefix
suffix

The dataset-prep node

SimpleLLMCaptionBatch is why most people install this pack at all: it points at a folder of images, captions every one, and writes out chronologically numbered 1.png, 1.txt, 2.png, 2.txt... pairs ready to drop into Kohya, ai-toolkit, or whatever you train with. Same Joy Caption Alpha Two engine as the basic node, minus the UI - folder in, training folder out.

This is the node to reach for when you're building a dataset for an LLM-encoder model (Flux, Z-Image, Qwen-Image, that family). Those models want natural-language captions, which is exactly what the Descriptive and Training Prompt types produce. If you're captioning for Illustrious or Pony, this can hand you Danbooru tags via the Booru Tags type, but the community default for the tagged-anime lineage is still a WD14 tagger - keep that in your back pocket.

Inputs and behavior

Required: pipeline, input_directory, output_directory, caption_type, caption_length, temperature, max_new_tokens, and save_as_txt (default on).

The two directory fields are where beginners slip. input_directory must be a real path on disk - the node returns "Error: Input directory does not exist" if it isn't. output_directory is required, not optional; without it the node refuses to run with "Please specify an output directory for chronological naming." Both are plain STRING widgets rather than folder pickers, so you type the absolute path.

Supported formats: .jpg, .jpeg, .png, .bmp, .webp, .tiff. The node sorts the file list, re-saves each image as a numbered PNG (RGBA is flattened to RGB), and writes the matching .txt. Unlike the Advanced node there's no top_p input here - it's fixed at 0.9 - and the text-processing options (lora_trigger, the replacement fields, the remove flags, prefix/suffix) all carry over.

Output is a single STRING status report: images processed, errors, and the output path. This is an output node, so it won't feed anything downstream; it's the end of the line.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/Pixelailabs/Joy_Caption_Two_PixelaiLabs.git
cd Joy_Caption_Two_PixelaiLabs
pip install -r requirements.txt

Restart and find it under image/captioning. ComfyUI Manager search "Joy Caption Two" works as well.

The catch: it's not a fire-and-forget queue

Two things to know before you point this at 2,000 images. First, the VRAM management that makes the basic node safe applies here too: models unload to CPU after each image and reload before the next. That keeps an 8GB card from dying on a big folder, but the wall-clock time per image includes a reload - a few thousand images is an overnight job, not a coffee break.

Second, the numbering starts at 1 on every run and it overwrites. Rerun the same folder and the previous 1.png / 1.txt are replaced. Fine for a single pass, annoying if you thought you were resuming. If a model load or download fails mid-run, the error count climbs and the node keeps going - usually the right behavior, but check the console for what actually failed.

One more thing worth repeating because it bites everyone: the first run downloads ~6-8GB of models (SigLIP, the Joy Caption adapters, your chosen LLM). Run a single test image through the basic node first so the loader has everything cached, then let the batch rip.

Categoryimage/captioning

Inputs (16)

NameTypeDefaultDescription
pipelineLLM_PIPELINE
input_directorySTRING
output_directorySTRING
caption_typeCOMBO7 options: Descriptive, Descriptive (Informal), Training Prompt, MidJourney, Booru Tags, Art Critic, +1
caption_lengthCOMBOmedium6 options: any, very short, short, medium-length, long, very long
temperatureFLOAT0.70.1–2
max_new_tokensINT30050–1000
save_as_txtBOOLEANtrue
lora_triggeroptSTRING
gender_age_replacementoptSTRING
hair_replacementoptSTRING
body_size_replacementoptSTRING
remove_tattoosoptBOOLEANfalse
remove_jewelryoptBOOLEANfalse
prefixoptSTRING
suffixoptSTRING

Outputs (1)

NameTypeDescription
STRINGSTRING