joy image caption
Turn one image into a natural-language caption with Joy Caption
- joy_pipeline
- image
- STRING
This is the node that finally gets you a proper sentence out of an image. "joy image caption" from the ymc_node_joy pack runs the Joy Caption model on a single image and hands you back a STRING - a real natural-language description, not a wall of WD14 tags. It doesn't call any API and needs no key; the whole thing runs on your GPU, and it's the kind of caption that Flux, Qwen-Image and Z-Image training actually want.
Why you'd reach for it
Joy Caption is the community's favorite captioner for LoRA training on LLM-encoder models. The modidex knowledge base counts it as the clear winner for natural-language captions - it's an uncensored vision-language model built specifically to write the descriptive sentences those architectures were trained on. Where BLIP is widely considered trash and WD14 tags are right for the Danbooru lineage, Joy Caption gives you flowing, detail-rich text you can feed straight into a training run.
The single-image node is for the times you don't need a whole folder done. Testing your prompt, captioning a reference image to paste into a training manifest, describing a screenshot you want to reproduce. It's the friendly, interactive counterpart to the pack's batch node.
How it works
You first load the model once with the joy model loader node, which assembles three pieces: the SigLIP vision encoder, a Llama 3.1 8B language model, and a small image adapter. This node takes that JoyPipeline object plus an image, encodes it through SigLIP, squashes the vision features through the adapter, and feeds them to Llama as input embeddings - so the model "sees" the image and then writes about it using your prompt as the instruction. Generation uses top_k=10 sampling at your chosen temperature, and the caption comes out collapsed to one line.
The inputs that matter
Most of the defaults are fine; you'll actually touch three of them:
- joy_pipeline - the object from the model loader. Non-negotiable.
- image - any IMAGE tensor. Load Image, the output of a sampler, whatever. It converts to RGB internally, so RGBA won't trip it up.
- prompt - this is your secret weapon. It's the instruction to the LLM, so "Write a descriptive caption" and "Describe only the clothing and pose" give you different captions. Default is "A descriptive caption for this image".
Two more worth knowing: max_new_tokens (default 1024, caps caption length) and temperature (default 0.7 - lower it if captions drift into hallucination). The cache toggle is the trap, see below.
The output is a single STRING - wire it to a Save Text node, a display node, or anything that takes text.
The gotcha that bites everyone
cache defaults to false, and that means after every single caption the node clears the whole pipeline out of VRAM. Load the model again on the next run, reload SigLIP, reload Llama - each caption turns into a multi-GB reload unless you're chaining many images inside one workflow. If you're captioning a series in one sitting, flip cache to true. If you're captioning a whole folder, use the pack's "joy diretory caption" node instead, which loops through images in one pass and only unloads at the end.
Install
Same story for every node in this pack:
cd ComfyUI/custom_nodes
git clone https://github.com/YMC-GitHub/ymc_node_joy
then restart ComfyUI - deps install automatically on startup. Or search "ymc_node_joy" in ComfyUI Manager. The first load triggers a big download (SigLIP ~1GB, the Llama you chose - see the loader article), so it looks hung for a while. And don't forget the manual bit: models/Joy_caption/image_adapter.pt must exist or the loader throws a FileNotFoundError before this node ever runs.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| joy_pipeline | JoyPipeline | — | |
| image | IMAGE | — | |
| prompt | STRING | A descriptive caption for this image | — |
| max_new_tokens | INT | 102410–4096 | — |
| temperature | FLOAT | 0.700–1 | — |
| cache | BOOLEAN | false | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| STRING | STRING | — |