Nodes/ComfyUI-Ollama-Describer/πŸ¦™ Ollama Image Captioner πŸ¦™
ComfyUI Node

πŸ¦™ Ollama Image Captioner πŸ¦™

Batch-caption a whole folder for LoRA training

By alisson-anjosΒ·Created 2 years agoΒ·Updated 5 months agoΒ· 123
πŸ¦™ Ollama Image Captioner πŸ¦™
  • extra_options
  • STRING
β—„modelβ–Ύβ–Ί
β—„custom_modelβ–Ί
β—„api_hosthttp://localhost:11434β–Ί
β—„timeout300β–Ί
β—„input_dirβ–Ί
β—„output_dirβ–Ί
β—„max_images-1β–Ί
β—„low_vramfalseβ–Ί
β—„keep_model_alive-1β–Ί
β—„top_p0.90β–Ί
β—„temperature0.60β–Ί
β—„caption_typeβ–Ύβ–Ί
β—„caption_lengthβ–Ύβ–Ί
β—„nameβ–Ί
β—„custom_promptβ–Ί
β—„prefix_captionβ–Ί
β—„suffix_captionβ–Ί
β—„structured_output_formatβ€”β–Ί

This is the dataset-prep node in the pack: point it at a folder of images and it writes a .txt caption file next to each one, ready for a LoRA training run. It's a different job from OllamaImageDescriber - that one hands you a single description string to wire elsewhere in a graph; this one is a batch tool that walks a directory and produces files on disk.

If you've done any LoRA training, you already know captioning is one of the highest-leverage things you can spend time on, and also one of the most tedious. The community's actual go-to captioners for this - JoyCaption and Florence 2 - are purpose-built vision models tuned specifically for terse, dataset-friendly output; the pack's own README lists JoyCaption as a direct reference project for this node's design, and the caption-format options here (Descriptive, MidJourney-style, Booru-like tags) mirror JoyCaption's own presets. The trade-off you're making by using this node instead is flexibility versus specialization: you get to swap in whatever vision model you already have pulled in Ollama, at the cost of not having a model that was specifically fine-tuned for the captioning task the way JoyCaption's is. If your dataset is small and the result matters a lot, plenty of people still just caption by hand - but for a first pass over a few hundred images, this beats nothing.

How it works

Same HTTP call to your local Ollama server as the rest of the pack, just wrapped in a loop over input_dir. For each image found, it builds a prompt out of your caption_type, caption_length, custom_prompt, and any connected extra_options, sends it to the model, and writes the response - with prefix_caption/suffix_caption applied - as a .txt file in output_dir.

The inputs and outputs that matter

  • input_dir / output_dir - the folder to read images from and the folder to write .txt captions to. Both are plain path strings; there's no browse dialog.
  • caption_type - five presets: Descriptive, Descriptive (Informal), FLUX/SD3+, MidJourney, and Booru-like tag list. Pick the one matching your training target - Booru-like for anime/Illustrious-style bases trained on comma-separated Danbooru tags, natural-language Descriptive for Flux-class or other LLM-encoder models.
  • caption_length - from "very short" through "very long," plus specific word-count targets (20 through into the hundreds). Shorter captions leave more for the model to infer; longer ones lock in more detail - the training-community rule of thumb still applies here: describe what you want to stay adjustable, leave what should be fixed undescribed.
  • name - if you're captioning a specific character or subject, set this so the captioner refers to them consistently (works together with the matching toggle on OllamaCaptionerExtraOptions, if you've wired one in).
  • prefix_caption / suffix_caption - text glued onto every caption, most commonly your trigger word.
  • extra_options (optional, Extra_Options type) - plug in an OllamaCaptionerExtraOptions node here to add specific instructions (lighting, camera angle, watermark detection, and so on) without hand-writing them into custom_prompt.
  • max_images (-1 = no limit) and low_vram are worth knowing before running a large folder: cap max_images while you're testing your settings, and flip low_vram if you're on a tight GPU budget.

Output is a single STRING - mostly a status/summary value, since the real output of this node is the .txt files it writes to disk.

How to install it

Requires Ollama running locally with a vision-capable model pulled - same as OllamaImageDescriber (LLaVA, MiniCPM-V, Moondream, etc). Get the node pack via ComfyUI Manager (search "ComfyUI-Ollama-Describer") or manually:

cd ComfyUI/custom_nodes
git clone https://github.com/alisson-anjos/ComfyUI-Ollama-Describer.git
pip install -r requirements.txt   # or install.bat on Windows

Restart ComfyUI.

Common issues & troubleshooting

Same connection-refused failure as the rest of the pack if Ollama isn't running first. Beyond that, on a large folder the practical trap is running out of patience or VRAM partway through - there's no resume/skip-existing behavior implied by the schema, so a run that dies halfway likely means starting over unless you've tracked which files already got a .txt. Test your caption_type, caption_length, and extra_options combination on a handful of images with max_images capped low before turning it loose on a full dataset - rerunning a few hundred captions because the prompt wasn't quite right is the expensive mistake to avoid.

CategoryOllama

Inputs (19)

NameTypeDefaultDescription
modelCOMBO19 options: llava:7b-v1.6-vicuna-q2_K (Q2_K, 3.2GB), llava:7b-v1.6-mistral-q2_K (Q2_K, 3.3GB), llava:7b-v1.6 (Q4_0, 4.7GB), llava:13b-v1.6 (Q4_0, 8.0GB), llava:34b-v1.6 (Q4_0, 20.0GB), llava-llama3:8b (Q4_K_M, 5.5GB), +13
custom_modelSTRINGβ€”
api_hostSTRINGhttp://localhost:11434β€”
timeoutINT3000–18446744073709550000β€”
input_dirSTRINGβ€”
output_dirSTRINGβ€”
max_imagesINT-1β€”
low_vramBOOLEANfalseβ€”
keep_model_aliveINT-1-1–18446744073709550000β€”
top_pFLOAT0.900–1β€”
temperatureFLOAT0.600–1β€”
caption_typeCOMBO5 options: Descriptive, Descriptive (Informal), FLUX/SD3+, MidJourney, Booru-like tag list
caption_lengthCOMBO31 options: any, very short, short, medium-length, long, very long, +25
nameSTRINGβ€”
custom_promptSTRINGβ€”
prefix_captionSTRINGβ€”
suffix_captionSTRINGβ€”
extra_optionsoptExtra_Optionsβ€”
structured_output_formatoptSTRINGβ€”

Outputs (1)

NameTypeDescription
STRINGSTRINGβ€”