Nodes/TankNodes/Local Multimodal Chat · Tank
ComfyUI Node

Local Multimodal Chat · Tank

Caption 200 images without leaving ComfyUI

By xzbdqian10nian·Created 2 months ago·Updated a day ago· 1
Local Multimodal Chat · Tank
  • backend
  • image
  • video_frames
  • video
  • response
  • reasoning
  • raw_response
  • stats
◄system_promptYou are a professional visual-understanding assistant running in ComfyUI. Answer accurately and directly.►
◄promptPlease describe the input image or video in detail.►
◄thinking_modeauto►
◄context_length8192►
◄max_tokens4096►
◄temperature0.60►
◄top_p0.95►
◄top_k40►
◄min_p0.05►
◄repeat_penalty1.05►
◄seed1►
◄max_video_frames8►
◄video_transportauto►
◄unload_afterfalse►
◄tools_json►

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. image accepts one image or a batch and sends every frame of it, which is how you caption a folder in one queue. video_frames takes a decoded IMAGE batch and samples it down to max_video_frames (8 by default); video takes a ComfyUI VIDEO object. Local models always sample frames - video_transport exists 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.

CategoryTankNodes/Local

Inputs (19)

NameTypeDefaultDescription
backendVISION_LLM_BACKENDConnect Qwen / Bonsai GGUF Loader · Tank. The API Chat nodes return text directly and do not connect here.
system_promptSTRINGYou are a professional visual-understanding assistant running in ComfyUI. Answer accurately and directly.Persona and system-level behavior or response-format instruction.
promptSTRINGPlease describe the input image or video in detail.User instruction sent with the attached image/video content.
thinking_modeCOMBOautoQwen 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_lengthINT81922048–262144Local context window for prompt, media and response. Bonsai uses at least 16K to fit typical visual prompts; changing it reloads the model.
max_tokensINT409616–32768Maximum number of new text tokens to generate. This is only a limit; generation still stops when the model finishes its answer.
temperatureFLOAT0.600–2Sampling randomness. Lower values are steadier; higher values are more varied. With a local model, 0 uses deterministic greedy sampling when supported.
top_pFLOAT0.950–1Nucleus-sampling probability threshold. Lower values keep only more likely tokens; 0.95 is a strong general default.
top_kINT400–200For local llama.cpp, restrict each token choice to the top K candidates. 0 disables top-K filtering; API backends ignore it.
min_pFLOAT0.050–1For local llama.cpp, discard tokens whose probability is below this fraction of the best token's probability. API backends ignore it.
repeat_penaltyFLOAT1.050.5–2For local llama.cpp, penalize repeated text. 1.0 disables the penalty; API backends ignore it.
seedINT10–4294967295Random seed used for reproducible sampling when all other inputs and backend settings match. API providers may ignore it.
max_video_framesINT81–64Sample at most this many frames from video or video frames. Every image in the image input is still sent.
video_transportCOMBOautoCompatibility option: local models always sample frames. Saved values are retained.
unload_afterBOOLEANfalseRelease this backend after generation. Enable to recover VRAM, disable for faster repeated chats.
imageoptIMAGEOne still image or an IMAGE batch of still images.
video_framesoptIMAGEDecoded video frames as a ComfyUI IMAGE batch; the batch is sampled according to max video frames.
videooptVIDEOComfyUI VIDEO object; local models sample it into frames, while API transport follows video transport.
tools_jsonoptSTRINGOptional OpenAI function/tool schema as one JSON object or an array.

Outputs (4)

NameTypeDescription
responseSTRINGFinal assistant answer without hidden reasoning tags.
reasoningSTRINGReasoning text when the backend exposes it.
raw_responseSTRINGRaw assistant content or complete tool-call message.
statsSTRINGTiming, token, speed, media-count, and backend statistics.