Nodes/ComfyUI-BILL-Concept_Isolator-Captioner/Bill's LoRA Detail Captioner (Gemma 4)
ComfyUI Node

Bill's LoRA Detail Captioner (Gemma 4)

Caption Your LoRA Dataset in Bulk with a Local Gemma 4 — No API Key Required

By 0-bill-0·Created 4 months ago·Updated 4 months ago· 1
Bill's LoRA Detail Captioner (Gemma 4)
  • image
  • STRING
model
excluded_detailsa vintage red sports car
trigger_wordMyCar
filenamecaption_output
save_foldercomfyui/output/captions

If you've ever assembled a LoRA dataset by hand, you know the grind: twenty images, each one needs a caption, and the quality of those captions decides whether your LoRA is a likeness or a lump. This node - Bill's LoRA Detail Captioner (Gemma 4), class BillLoRACaptionNode - automates the chore with a vision LLM running entirely on your own machine. The name is not a lie: it doesn't call any API and needs no key. It talks to a local Ollama server and writes the captions out as .txt files, ready for ai-toolkit, kohya, or whatever trainer you use.

What it actually does

The interesting part is the trick the author calls Concept Isolation, and it's smarter than "describe this picture." You tell it two things: the subject's physical traits (excluded_details, default "a vintage red sports car") and a single token to stand in for that subject (trigger_word, default "MyCar"). The node then builds a prompt that tells the LLM to describe the scene in high detail - lighting, composition, pose, texture - but to substitute every physical description of that subject with the trigger word. So you get MyCar parked on a rainy street, warm window light bouncing off wet asphalt instead of A red car parked on a rainy street....

That's exactly the captioning rule that actually works for LoRA training, straight out of the playbook: caption what you want to remain variable (scene, pose, lighting), and leave the fixed identity out of the general description so it binds to the trigger token. The LLM runs at temperature 0.1 in a single pass - deliberately boring, on purpose, so you don't get token drift between iterations.

Under the hood

The node is a thin wrapper over Ollama's local HTTP API. Your image gets converted to a JPEG, base64-encoded, and POSTed to http://localhost:11434/api/generate alongside the prompt. The model dropdown is populated live from whatever vision models you have installed in Ollama (it reads /api/tags), falling back to gemma4 if Ollama wasn't running when ComfyUI loaded. The heavy lifting - and the VRAM - all happens in the LLM, not in the node.

The inputs that matter:

  • image - any IMAGE tensor, e.g. from LoadImage. Note it only captions the first frame of a batch, so feed one image per run or loop it.
  • excluded_details - the subject's inherent traits, described so the model knows what to hide.
  • trigger_word - what the model substitutes for those traits.
  • model - which installed Ollama vision model to use.

Optional filename and save_folder control the .txt export (default comfyui/output/captions). The output is a single STRING - the caption - which wires straight into PreviewAny or a text display, exactly like the pack's sample workflows.

Installing it

Two steps, and only the second one is heavy:

cd ComfyUI/custom_nodes
git clone https://github.com/0-bill-0/ComfyUI-BILL-Concept_Isolator-Captioner

Or use ComfyUI Manager and search "ComfyUI-BILL-Concept_Isolator-Captioner", then restart. The requirements.txt is just torch, numpy, Pillow, and requests - all of which ComfyUI already has, so the pack itself adds essentially nothing. The real dependency is Ollama:

# install Ollama first, then pull a vision model
ollama run gemma4

Keep in mind the hardware table in the README: it's honest enough to list "potato" as the minimum and 24–32GB VRAM as recommended. Gemma 4 is a big model. On a smaller card, pull a smaller vision model and pick it in the dropdown - that's the beauty of the live model list.

Where people get burned

  • The dropdown shows only gemma4. That means Ollama wasn't running when ComfyUI loaded, so the live model list came back empty. Start Ollama, confirm your model with ollama list, then reload ComfyUI.
  • The caption output literally reads "Could not connect to Ollama. Is it running?" Errors come back as the output string rather than crashing the graph, so skim a caption or two before you trust a full dataset run - a dead server will happily write error text into all your .txt files.
  • The default filename is "caption_output" and the folder is relative to your ComfyUI working directory. Running the batch without setting a per-image filename overwrites the same file every time.
  • "MyCar" is a weak trigger. The community rule of thumb is a rare alphanumeric token (ohwx, ch9ractername) so it can't collide with a real word. The mechanic is fine; the example is just not the best one.

It's a niche, one-node pack from a single author, and there are mainstream captioners with bigger followings - JoyCaption and Florence 2 for natural language, WD14 for taggers. This one earns its place if you want the trigger-word isolation workflow, local privacy, and a .txt pipeline that lands captions directly where your trainer expects them.

CategoryBillNodes/Training

Inputs (6)

NameTypeDefaultDescription
imageIMAGE
modelCOMBO1 options: gemma4
excluded_detailsSTRINGa vintage red sports car
trigger_wordSTRINGMyCar
filenameoptSTRINGcaption_output
save_folderoptSTRINGcomfyui/output/captions

Outputs (1)

NameTypeDescription
STRINGSTRING