Generate Caption (AITocha)
The node that turns your image into a caption — and never returns None
- vlm
- image
- caption
Generate Caption (AITocha) is the second half of the split setup: the loader puts JoyCaption Beta One in VRAM, and this node is where the image actually becomes text. You hand it the vlm handle from Load Caption Model (AITocha), connect an IMAGE, and out comes a STRING caption ready to wire into a CLIPTextEncode or a training caption file.
Why split it at all? Because JoyCaption is a generator, not a utility - a single queue run that captions a dozen images shouldn't reload an 8B model twelve times. Load once, caption N times. If that sounds like overkill for your use case, it is: for one image per run the pack's Auto Caption node fuses both halves and you'll never touch this pair.
The background matters for picking presets. JoyCaption is the community default for uncensored natural-language captions - it exists because the alternatives were an expensive censored API or a weak open model, and it's what people caption Flux/Z-Image LoRA datasets with. Every captioner in this class shares one honest weakness, stated by the author himself: multi-subject attribution. Two people in a frame and the model mixes up who's wearing what. Auto-caption a large set, audit a small one by hand.
How it works
Inside, it's a thin wrapper around transformers. The node converts your ComfyUI image tensor (float [B,H,W,C], so it takes batch image 0) to a PIL RGB image, builds a chat conversation from the system and user prompts you picked, runs it through the model's chat template, and calls generate() with your sampling settings. Then it strips the prompt tokens and decodes only the freshly generated text. One detail the author clearly cared about: if the model somehow returns an empty string, the node returns the literal placeholder "image" instead of None - the exact crash the GGUF-based nodes were famous for (a NoneType blowing up CLIPTextEncode mid-workflow).
Inputs that matter
The two that shape the output are the presets:
system_preset- defaults to Scene only (no identity), the pack's signature. It tells the model to describe pose, clothing, setting, lighting, composition - and not facial features, hair, eye color, age, or identity traits. That's a deliberate choice for img2img + character LoRA: you bring the identity token, the captioner fills in the scene without fighting your LoRA. Other options are Full description and Booru-style tags.user_preset- Long descriptive caption (default), Short caption, Booru tags, or Stable Diffusion prompt (comma-separated phrases, no full sentences).
The rest are standard LLM knobs: max_new_tokens (300 default, up to 2048, floor of 16), temperature (0.6; set it to 0 for greedy, reproducible captions), top_p (0.9), and a seed. If a preset's "Custom" option is picked, the system_prompt and custom_user_prompt textareas take over. The vlm and image inputs are required, and the vlm only comes from this pack's loader.
What comes out
One caption (STRING). Feed it to CLIPTextEncode's text input for an auto-prompted img2img run, pipe it to a text node to read it, or write it to .txt files for a LoRA training set. Same seed, same settings, same image - same caption, which matters when you're captioning a dataset and want stable output.
Install
ComfyUI Manager → search "AITocha Vision" → install → restart. Manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/AITocha/ComfyUI-AITocha-Vision.git
cd ComfyUI-AITocha-Vision
pip install -r requirements.txt
Restart ComfyUI. It needs transformers, accelerate, bitsandbytes, and Pillow, plus a CUDA GPU - this pack deliberately has no CPU path. First run downloads the ~14 GB model into HF_HOME; set HF_HOME=/workspace/huggingface on rented pods so it persists.
Troubleshooting
You'll get an immediate "can't connect" if you forget the loader - the vlm input is required and there's no lazy default. Bitsandbytes version gripes are the other common one (pip install -U bitsandbytes). And remember the model cache holds one model at a time: change the loader's quantization between runs and the next caption pays a ~20–30 second reload. If captions come back weirdly short, check max_new_tokens - 300 covers most images, but long scenes can run out of budget.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| vlm | AITOCHA_VLM | — | |
| image | IMAGE | — | |
| system_preset | COMBO | Scene only (no identity) | 4 options: Scene only (no identity), Full description, Booru-style tags, Custom (use system_prompt) |
| user_preset | COMBO | Long descriptive caption | 5 options: Long descriptive caption, Short caption, Booru tags, Stable Diffusion prompt, Custom (use custom_user_prompt) |
| max_new_tokens | INT | 30016–2048 | — |
| temperature | FLOAT | 0.600–2 | — |
| top_p | FLOAT | 0.900–1 | — |
| seed | INT | 00–18446744073709550000 | — |
| system_promptopt | STRING | You are an expert image captioner. Describe the pose, body position, clothing or lack thereof, setting, lighting, camera angle, framing, and overall composition of the image. Focus only on what is happening and where, not who is in the image. Do NOT describe the subject's facial features, hair color, eye color, age, or any identifying physical traits. | — |
| custom_user_promptopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| caption | STRING | — |