Nodes/Fal-Gateway/Fal Image-to-Text
ComfyUI Node

Fal Image-to-Text

Caption anything — Florence-2 to GPT-4o in one vision node

By modbender·Created 5 months ago·Updated 3 months ago· 1
Fal Image-to-Text
  • image
  • response
  • info
model_id
prompt
system_prompt
schema
seed-1

The workhorse captioner job - "describe this image" - has a cloud answer now, and Fal Image-to-Text bundles every flavor of it into one node. It's part of ComfyUI-Fal-Gateway, and its model list is the pack's smartest catalog: fal's direct vision endpoints (Florence-2, Moondream, LLaVA, Sa2VA) plus every OpenRouter model whose architecture accepts image input - Claude, Gemini, GPT-4o, Grok, Pixtral, Qwen-VL - auto-detected from OpenRouter's live model feed. New vision models just appear.

The use cases line up with where captioning actually gets used in this ecosystem: captioning a LoRA training set, describing a frame to seed an img2img or image-to-video prompt, or just getting a machine-readable read on what's in an image. For caption quality on a training set, the community's advice still holds - a natural-language captioner like this one works, but audit a sample by hand because multi-subject attribution is where every VLM fails.

Inputs and outputs

  • image - the picture you're asking about, from LoadImage.
  • model_id - the dropdown. [fal-ai] Florence 2 Large Detailed Caption on the fast end, [Anthropic] Claude Sonnet 4.5 on the smart end.
  • prompt - your instruction. "describe this image" for a caption, or something targeted like "what brand of car is this".
  • system_prompt - optional. Honored natively by OpenRouter vision models ("you are an expert wildlife photographer evaluating composition"); silently ignored by fal-direct endpoints (Florence-2, Moondream, Sa2VA) - leave it empty for those.
  • schema - the same JSON-mode toggle as the T2T node: comma-separated field list → structured JSON response. Only honored through the OpenRouter path.
  • seed - INT, default -1.

Outputs: response (STRING) and info (STRING).

How it works

The node uploads your image to fal, dispatches to the selected endpoint, and returns the text. The OpenRouter path routes through fal's openrouter/router/vision with the model ID injected; the fal-direct path calls the vision endpoint directly. Same schema-driven catalog idea as the rest of the pack - the fal-direct list is curated, the OpenRouter list is live-detected, and vision-only variants are filtered out so you're not wading through NSFW classifiers and OCR sub-paths.

Install

cd ComfyUI/custom_nodes
git clone https://github.com/modbender/ComfyUI-Fal-Gateway
pip install -r requirements.txt
export FAL_KEY=your_fal_key

Restart ComfyUI; the pack lives under Fal-Gateway. No weights to download - the vision models run on fal's hardware.

Gotchas

  • system_prompt is a lie for half the dropdown. It does nothing on fal-direct endpoints; the README is upfront about it. If your instruction isn't being followed, check which side of the catalog your model sits on.
  • Schema mode also depends on the path. fal-direct endpoints silently drop response_format, so structured JSON only works through OpenRouter models. Set a default on your JSON Extract node either way.
  • Per-call pricing. Captioning a 10,000-image LoRA set through a frontier VLM is not free and will add up; that's exactly the case where a local JoyCaption-style captioner wins. Use the smart endpoints for the hard images, the cheap ones for the rest.
  • No key → "FAL_KEY not set" hard error, fix documented in the message.

If you're on a budget and captioning at volume, this node is a convenience, not a cost saver - but for "what the hell is in this reference image, in one call," it's the fastest path in ComfyUI.

CategoryFal-Gateway

Inputs (6)

NameTypeDefaultDescription
model_idCOMBO11 options: [fal-ai] Florence 2 Large Detailed Caption, [fal-ai] LLaVA v1.6 34B, [fal-ai] Marlin, [fal-ai] Marlin Find, [fal-ai] Moondream2, [fal-ai] Moondream3 Preview [Caption], +5
promptSTRING
system_promptSTRING
schemaSTRING
seedINT-1-1–4294967295
imageIMAGE

Outputs (2)

NameTypeDescription
responseSTRING
infoSTRING