ComfyUI Node

Unified Caption

The caption node that phones a frontier LLM instead of running a tagger

By tardigrade1001·Created 6 months ago·Updated 2 months ago· 1
Unified Caption
  • images
  • text
prompt
modelreplicate/google/gemini-3-flash | $0.50/M in | $3.00/M out
freeze_captionfalse
system_instruction
replicate_api_key
openrouter_api_key
cerebras_api_key
retry_modelreplicate/google/gemini-3-flash | $0.50/M in | $3.00/M out
error_fallback_value
seed1509221223
temperature0.20
max_tokens2048

Captioning inside ComfyUI usually means one of two things: a local tagger like WD14 spitting out Danbooru tags, or a local vision model like Florence 2 or JoyCaption writing natural-language sentences. This node takes a third road that a lot of people don't realize is even open - it skips local models entirely and sends your image to a frontier multimodal LLM (Gemini, GPT-5-mini, Grok) over an API. No GPU load, no multi-gig model download, and captions written by the same class of model people reach for in everyday AI tools. It's the closest thing to "just ask a very smart assistant what's in this image" that you can bolt into a workflow.

The name is slightly aspirational: it's not a universal captioning pipeline, it's one node with one job - describe a single image and hand you the text. The author is explicit that this is an interactive tool, not a batch-captioning engine for training datasets. If you're captioning 5,000 images for a LoRA, go run JoyCaption locally. If you have one image you want to understand, re-prompt, or turn into a natural-language description for a Flux-style dataset, this is fast and painless.

How it works

Every call goes out to OpenRouter, Replicate, or Cerebras - pick a provider, and the node handles the API differences for you. Before sending, it resizes anything over 1024px on the longest side (LANCZOS, aspect preserved), converts to JPEG at quality 85, and base64-encodes it as a data URL. That preprocessing is pure cost control: you're paying per token, and a 4K image doesn't carry any more useful information to Gemini than a 1K one does.

Where this node gets clever is reliability. Frontier APIs occasionally return truncated responses - the connection drops mid-sentence and you get a caption that ends in mid-air. The node validates every response: a caption has to end in terminal punctuation, or the attempt counts as failed. Failed attempts retry the same model up to 3 times with backoff, and if you've set a retry_model on a different provider, it falls through to that for another 3 attempts. The README's console logs show the whole dance, including a [COST] $0.001277 | model=... line per request so you can see what each caption is actually setting you back. Retries cost money too, since each one is a fresh billed request - just know that going in.

The inputs that matter

You only strictly need three inputs:

  • images - the image tensor from your pipeline. Only the first image in the batch is processed, so don't feed it a whole batch expecting bulk output.
  • prompt - the instruction, e.g. "Describe the image in detail including objects, setting, lighting, and composition." This is sent verbatim to the model, so this is where your captioning style lives.
  • model - the dropdown, 8 choices across the three providers with per-million-token pricing baked into each label.

Everything else is optional, and two of the optional inputs are genuinely worth knowing. freeze_caption hard-locks the last caption so you can iterate on everything downstream with zero API calls - turn it on, re-run to your heart's content, flip it off when you want a fresh caption. There's also an always-on cache keyed on the image, prompt, model, and a few other settings, so re-running an unchanged workflow never re-bills you. And seed is a lie in the best way: these models don't take seeds, so the node just uses the number to force ComfyUI to re-execute and give you an alternate caption. Bump it, get a reroll.

Output is a single text string - wire it into a text-display node or a dataset-prep workflow.

Installing it

ComfyUI Manager and search "ComfyUI-Unified-Caption", or clone it directly:

cd ComfyUI/custom_nodes
git clone https://github.com/tardigrade1001/ComfyUI-Unified-Caption

Then restart ComfyUI. Dependencies are refreshingly light - just requests and Pillow - and there are no model files to download, because nothing runs locally.

The gotchas

The whole thing is moot without an API key. Paste it into the node's fields or set an environment variable - OPENROUTER_API_KEY, REPLICATE_API_TOKEN, or CEREBRAS_API_KEY - and empty fields fall back to the env var. Cerebras is the free option (the cerebras/gemma-4-31b model is listed at $0/M) but its free tier is tight: 5 requests/min, ~1M tokens/day. Fine for spot-checks, not serious work. Also note the retry model defaults to the same as the primary, which effectively disables the fallback - pair it with the other provider for real insulation.

It's a niche tool for a specific move: interactive, high-quality, natural-language captions with zero local compute. For that, it's the one I'd reach for.

CategoryUnified Caption

Inputs (13)

NameTypeDefaultDescription
promptSTRING
modelCOMBOreplicate/google/gemini-3-flash | $0.50/M in | $3.00/M out8 options: replicate/google/gemini-3-flash | $0.50/M in | $3.00/M out, replicate/google/gemini-2.5-flash | $0.30/M in | $2.50/M out, replicate/openai/gpt-5-mini | $0.25/M in | $2.00/M out, openrouter/google/gemini-2.5-flash | $0.30/M in | $2.50/M out, openrouter/google/gemini-3-flash-preview | $0.50/M in | $3/M out, openrouter/x-ai/grok-4.3 | $1.25/M in | $2.50/M out, +2
imagesIMAGE
freeze_captionoptBOOLEANfalse
system_instructionoptSTRING
replicate_api_keyoptSTRING
openrouter_api_keyoptSTRING
cerebras_api_keyoptSTRING
retry_modeloptCOMBOreplicate/google/gemini-3-flash | $0.50/M in | $3.00/M out8 options: replicate/google/gemini-3-flash | $0.50/M in | $3.00/M out, replicate/google/gemini-2.5-flash | $0.30/M in | $2.50/M out, replicate/openai/gpt-5-mini | $0.25/M in | $2.00/M out, openrouter/google/gemini-2.5-flash | $0.30/M in | $2.50/M out, openrouter/google/gemini-3-flash-preview | $0.50/M in | $3/M out, openrouter/x-ai/grok-4.3 | $1.25/M in | $2.50/M out, +2
error_fallback_valueoptSTRING
seedoptINT15092212230–2147483648
temperatureoptFLOAT0.200–1.5
max_tokensoptINT204864–65535

Outputs (1)

NameTypeDescription
textSTRING