JLC CaptionForge Ollama Caption
A caption witness that lives in Ollama, not in your GPU
- image
- pipeline_plan
- template_options
- image_out
- pipeline_plan_out
- template_options_out
- caption
- resolved_prompt
The other two caption witnesses in this pack load Python/Hugging Face weights straight into ComfyUI. This one is different: JLC CaptionForge Ollama Caption delegates to your local Ollama server, so the model lives in the Ollama daemon instead of your ComfyUI process. It's the third Pass A "witness" voice, sitting parallel to Joy and Qwen - and despite the word "Ollama," it is not the validator. That's a VLM role later in the pipeline; this node's only job is producing raw witness captions.
Why would you add it? More independent voices. The whole CaptionForge premise is that one captioner misses things another catches - Joy notices the face, Qwen catches the pose, and an Ollama VLM might nail the material and lighting. You pick a model tag the Ollama dropdown knows about, and the node contributes its account to the Pass A evidence pile.
How it works
The node sends your image plus a resolved prompt to the Ollama API at http://127.0.0.1:11434 (configurable). The model dropdown reads config/captionforge_ollama_models.json → caption_models - defaults like gemma4:26b, qwen3.6:35B-A3B, or huihui_ai/gemma-4-abliterated:26b - and custom lets you type any tag you've pulled. keep_loaded passes keep_alive to Ollama, and max_new_tokens maps straight to num_predict. The download_probe_only toggle is a genuinely handy preflight: it checks that Ollama is reachable and the model tag is installed, then reports back without captioning.
Inputs that matter
- model / custom_model_tag - which VLM witness you're running.
- caption_type / caption_length - the template path, same as Joy/Qwen (Descriptive, LoRA Literal, Taggy, SFW Character Caption…).
- system_prompt / custom_prompt - pre-populated with a female-character LoRA-oriented default, including matter-of-fact guidance for glamour/swimwear/lingerie styling. If your dataset isn't character-focused, this is the first thing to change.
- temperature / top_p / top_k / repetition_penalty - standalone sampling; the Pipeline Planner overrides most of it when connected.
- request_timeout_seconds - default 900, because large models may still be pulling when you queue the run.
Outputs mirror the other caption nodes: caption, resolved_prompt, image_out, pipeline_plan_out, template_options_out. Same five, same wiring - caption is the text, the others exist for clean node-to-node chaining.
Install
Pack install is the usual one:
git clone https://github.com/Damkohler/CaptionForge.git ComfyUI/custom_nodes/CaptionForge
Then Ollama itself, and pull whatever tag you want to witness with:
ollama pull gemma4:26b
The repo ships no weights for this node - the model is Ollama's business.
Common issues
If it fails instantly, check the two usual suspects: is ollama serve actually running, and is the URL right (a non-default port is the classic trap)? On 16 GB VRAM boxes, remember this node clears the resident Joy/Qwen Python models before calling Ollama and leaves residency to the daemon - so mixing backends can feel like a reload between images. And don't confuse this witness role with the validator: this node feeds Pass A, it doesn't check anyone's work.
Inputs (25)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | gemma4:26b | Ollama vision-language model tag. Choices are loaded from config/captionforge_ollama_models.json -> caption_models. Use custom for any locally installed or pullable Ollama model tag. |
| custom_model_tag | STRING | Used only when model is custom. Example: gemma4:12b or qwen3.6:35B-A3B. | |
| ollama_url | STRING | http://127.0.0.1:11434 | Local Ollama server URL. Default is http://127.0.0.1:11434. |
| keep_loaded | BOOLEAN | true | Ask Ollama to keep the model warm after generation. This is passed as keep_alive. Ollama ultimately owns model residency. |
| caption_template_mode | BOOLEAN | true | Use the structured CaptionForge template path: caption_type, caption_length, and optional Template Options from the template_options pin. If custom_prompt_mode is also enabled, custom_prompt_mode takes precedence. |
| caption_type | COMBO | LoRA Literal | Caption template style used when caption_template_mode is active. |
| caption_length | COMBO | any | Target caption length used when caption_template_mode is active. |
| custom_prompt_mode | BOOLEAN | false | Use custom_prompt when non-empty, otherwise use prompt_preset. This overrides caption_template_mode when both toggles are enabled. |
| prompt_preset | COMBO | female_character_lora | Built-in prompt preset used only in custom_prompt_mode when custom_prompt is blank. Default is female_character_lora. |
| system_prompt | STRING | You are a multimodal image captioning engine for female character LoRA dataset preparation. Your job is to inspect the image and write one strong standalone caption. Rules: - Describe only visible image content. - Output exactly one paragraph and nothing else. - Do not output analysis, reasoning, notes, bullet points, labels, or a thinking trace. - Do not roleplay, address the user, ask follow-up questions, or include safety disclaimers. - If a detail is uncertain, omit it rather than hedge. - Use direct dataset-caption language, not chatty commentary. | Ollama system prompt. Kept next to custom_prompt because both control the instruction envelope. Prepopulated with the default female-character LoRA captioning system prompt. Pipeline Planner does not currently override this. |
| custom_prompt | STRING | Write one clean caption for a female character LoRA dataset. Caption priorities: - Be specific rather than generic. - Prioritize female-character-LoRA-relevant visual traits: subject type, pose, facial structure, expression, hair color and hairstyle, eye color, makeup color as distinct from eye color, lip shape and fullness, skin appearance, neck length, shoulder line, bust/chest shape, waist definition, hip width, body proportions, silhouette, legs, clothing construction, accessories, dominant colors, lighting, background, framing, and visual style. - Include visible anatomy and figure information when clear and relevant. Do not omit body-shape or facial-structure details merely because they are sensual, revealing, or anatomy-related. - If the image presents glamour, sensuality, revealing clothing, lingerie, swimwear, cleavage, underboob, sideboob, bare midriff, exposed hips, thighs, or other sexualized styling, describe that directly and matter-of-factly when visible. - Use strong, open dataset-caption language rather than timid euphemisms, but do not turn the caption into roleplay, commentary, or erotic prose. - Do not invent nudity, explicit acts, hidden anatomy, or hidden clothing details. - Do not force photo, render, doll, anime, realistic, or stylized language unless supported by the image. - Avoid meta phrases like "this image shows" or "the picture depicts." - One paragraph only. Final caption: | Custom prompt used only when custom_prompt_mode is enabled. The widget is prepopulated with the default LoRA-oriented prompt; if cleared, prompt_preset is used instead. |
| max_new_tokens | INT | 180016–8192 | Standalone token budget. For this Ollama-backed node, CaptionForge max_new_tokens is sent to Ollama as num_predict. When a Pipeline Planner is connected, this is overridden by the Planner's shared max_new_tokens. |
| temperature | FLOAT | 0.180–2 | Standalone sampling temperature. When a Pipeline Planner is connected, this is overridden by the Planner temperature schedule. |
| top_p | FLOAT | 0.920–1 | Standalone top-p sampling value. When a Pipeline Planner is connected, this is overridden by the Planner top-p schedule. |
| top_k | INT | 600–500 | Standalone top-k sampling limit. When a Pipeline Planner is connected, this is overridden by the Planner top-k schedule. |
| repetition_penalty | FLOAT | 1.031–2 | Ollama repeat_penalty. Kept with the core captioning parameters. This is not currently overridden by the Pipeline Planner. |
| max_size | INT | 10240–4096 | Maximum longest-side image size for standalone captioning. The image is resized in memory only. Pipeline Planner overrides this in planned runs. |
| request_timeout_seconds | INT | 90010–7200 | HTTP timeout for Ollama API calls, including large model pulls/generation. |
| forbidden_phrases | STRING | Optional cleanup filter: remove lines/captions containing any listed phrase, one per line. | |
| replace_pairs | STRING | Optional cleanup replacements, one per line: old=>new. | |
| download_probe_only | BOOLEAN | false | At the very bottom by design. Check Ollama availability, local model installation, and best-effort remote tag existence, then return a status message without captioning. |
| imageopt | IMAGE | Image or batch of images to caption. The image is passed through unchanged for clean node-to-node pipeline chaining. | |
| pipeline_planopt | CAPTIONFORGE_PIPELINE_PLAN | Connect the CaptionForge Pipeline Planner output here. When connected, this node switches into Pass A evidence mode: Planner image routing, per-run seeds, sampling schedules, shared output paths, and internal JSONL evidence append. | |
| template_optionsopt | CAPTIONFORGE_EXTRA_OPTIONS | Connect the CaptionForge Template Options node here. Works in standalone and Pipeline modes. This is the only source for template modifiers and name input. | |
| seedopt | INT | Optional standalone seed input. Ignored when a Pipeline Planner supplies a seed schedule. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| image_out | IMAGE | — |
| pipeline_plan_out | CAPTIONFORGE_PIPELINE_PLAN | — |
| template_options_out | CAPTIONFORGE_EXTRA_OPTIONS | — |
| caption | STRING | — |
| resolved_prompt | STRING | — |