Local Multimodal Chat · Tank
Caption 200 images without leaving ComfyUI
- backend
- image
- video_frames
- video
- response
- reasoning
- raw_response
- stats
Local Multimodal Chat · Tank is the node that does the actual work: you give it a prompt, optionally an image, a batch of images, or video frames, and a local Qwen3.8 model answers in text. That's it - no chat window, no history, no server. Wire the sampler's output image in and get back a description; wire the description into a prompt box and you have img2img seeding that runs entirely on your own machine.
This is the LLM-in-the-graph pattern: an 8B-to-27B local VLM is uncensored, offline and free per call, which an API fundamentally is not. The two things it's genuinely good for are building caption files for a training set and turning a rough idea (or a reference image) into a structured prompt you can hand to an encoder. It is not a writer, and every VLM here shares one weakness worth knowing before you trust a batch: multi-subject attribution. Two people in frame and it will mix up who's wearing what, which is why people auto-caption the large sets and audit the small ones by hand.
What you set
backend comes from Qwen3.8 Model Loader · Tank - that's the only way in. Then:
- prompt - your instruction. The default asks for a detailed description, which is a fine starting point for captioning.
- system_prompt - persona and format rules. If you want output you can pipe into another node, say so here, in plain words ("no preamble, one paragraph, no markdown").
- image / video_frames / video - optional inputs.
imageaccepts one image or a batch and sends every frame of it, which is how you caption a folder in one queue.video_framestakes a decoded IMAGE batch and samples it down tomax_video_frames(8 by default);videotakes a ComfyUI VIDEO object. Local models always sample frames -video_transportexists for workflow compatibility and is ignored here. - max_tokens (4096) and context_length (8192) - the two numbers that matter on real prompts. Context covers your prompt plus media tokens plus the answer, and images eat a lot of it; bump it in 1024 steps when output gets clipped. Note the reload behaviour: changing context reloads the model, changing reasoning effort doesn't.
Sampling is the usual llama.cpp stack - temperature 0.6, top_p 0.95, top_k 40, min_p 0.05, repeat_penalty 1.05 - and the defaults are fine. Turn temperature down for captions you intend to reuse; 0 gets you deterministic greedy sampling.
thinking_mode is the one with a gotcha: auto on a local model means thinking off, preserving the pack's original behaviour. Qwen3.8 natively supports low/medium/xhigh, so high resolves to medium and max to xhigh; the stats output shows what actually took effect. And unload_after frees the VRAM the moment generation finishes - great when the graph continues into a diffusion model, wasteful when you're iterating on the same image.
What comes out
response is the clean answer with hidden reasoning tags stripped - this is the one you wire into a prompt node or a text-save node. reasoning holds the thinking when the model exposes it, raw_response is the unedited assistant content (including a full tool-call message), and stats gives you timing, token counts, speed and backend details - check it once per session to confirm whether reasoning was on when you expected it off. The optional tools_json field takes an OpenAI function/tool schema if you're doing something more exotic than prompting.
Install
requirements.txt installs only diskcache; the real prerequisite is a CUDA build of llama-cpp-python that knows Qwen3.8's chat template. Do not let anything install the plain PyPI wheel over it. If the nodes won't load with No module named 'llama_cpp_cuda' or the pack complains about a missing Qwen35ChatHandler, that's your build, not the pack. Full setup lives in the Qwen3.8 Model Loader article; the short version is ComfyUI Manager → search Tank, or clone into ComfyUI/custom_nodes and restart, then put the GGUF and the matching projector in ComfyUI/models/LLM/Qwen3.8/.
Where people get burned
First run looks frozen. Weights load when chat starts, not when the loader runs - that's a 27B GGUF plus a projector, so give it time and watch the console, not the canvas.
Truncated answers. Almost always context_length, not max_tokens. Images and video frames consume context before the model writes a word.
Garbage answers about the image. A projector from a different release than the main model. The loader's backend_info output names the recommended projector and whether your filename matched - read it.
Reasoning text leaking into your prompt. If you're feeding the output into an encoder, take response, not raw_response.
The model says something confidently wrong about a two-person photo. That's not a bug you can tune away; it's the known ceiling of every captioner in this family.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| backend | VISION_LLM_BACKEND | Connect Qwen / Bonsai GGUF Loader · Tank. The API Chat nodes return text directly and do not connect here. | |
| system_prompt | STRING | You are a professional visual-understanding assistant running in ComfyUI. Answer accurately and directly. | Persona and system-level behavior or response-format instruction. |
| prompt | STRING | Please describe the input image or video in detail. | User instruction sent with the attached image/video content. |
| thinking_mode | COMBO | auto | Qwen auto keeps thinking off; Bonsai auto uses off for text and low for images/video frames. Explicit low/medium/high/xhigh/max select an effort tier; high maps to medium and max to xhigh for these local models. |
| context_length | INT | 81922048–262144 | Local context window for prompt, media and response. Bonsai uses at least 16K to fit typical visual prompts; changing it reloads the model. |
| max_tokens | INT | 409616–32768 | Maximum number of new text tokens to generate. This is only a limit; generation still stops when the model finishes its answer. |
| temperature | FLOAT | 0.600–2 | Sampling randomness. Lower values are steadier; higher values are more varied. With a local model, 0 uses deterministic greedy sampling when supported. |
| top_p | FLOAT | 0.950–1 | Nucleus-sampling probability threshold. Lower values keep only more likely tokens; 0.95 is a strong general default. |
| top_k | INT | 400–200 | For local llama.cpp, restrict each token choice to the top K candidates. 0 disables top-K filtering; API backends ignore it. |
| min_p | FLOAT | 0.050–1 | For local llama.cpp, discard tokens whose probability is below this fraction of the best token's probability. API backends ignore it. |
| repeat_penalty | FLOAT | 1.050.5–2 | For local llama.cpp, penalize repeated text. 1.0 disables the penalty; API backends ignore it. |
| seed | INT | 10–4294967295 | Random seed used for reproducible sampling when all other inputs and backend settings match. API providers may ignore it. |
| max_video_frames | INT | 81–64 | Sample at most this many frames from video or video frames. Every image in the image input is still sent. |
| video_transport | COMBO | auto | Compatibility option: local models always sample frames. Saved values are retained. |
| unload_after | BOOLEAN | false | Release this backend after generation. Enable to recover VRAM, disable for faster repeated chats. |
| imageopt | IMAGE | One still image or an IMAGE batch of still images. | |
| video_framesopt | IMAGE | Decoded video frames as a ComfyUI IMAGE batch; the batch is sampled according to max video frames. | |
| videoopt | VIDEO | ComfyUI VIDEO object; local models sample it into frames, while API transport follows video transport. | |
| tools_jsonopt | STRING | Optional OpenAI function/tool schema as one JSON object or an array. |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| response | STRING | Final assistant answer without hidden reasoning tags. |
| reasoning | STRING | Reasoning text when the backend exposes it. |
| raw_response | STRING | Raw assistant content or complete tool-call message. |
| stats | STRING | Timing, token, speed, media-count, and backend statistics. |