ComfyUI Node

LM Studio Image Caption

The captioning node that doesn't run a model — it borrows your LM Studio

By Slartibart23·Created 4 months ago·Updated 4 months ago· 1
LM Studio Image Caption
  • image
  • caption
server_urlhttp://127.0.0.1:1234/v1/chat/completions
modelDEINE_MODEL_ID_HIER_EINTRAGEN
promptErstelle eine deutsche Bildcaption in 1 bis 3 Sätzen. Keine Analyse. Keine Stichpunkte. Nur die finale Caption.
thinking_modeno_think
image_formatdata_uri_jpeg
seed_modefixed
seed42
send_seed_to_lmstudiooff
temperature0.20
max_tokens4096
debug_responseon
fallback_modefinal_or_reasoning

This node sends whatever image you feed it to a local LM Studio server and puts the caption it gets back onto the graph as a plain string. The name is a mild lie in a good way: it doesn't call any cloud API, needs no key, and downloads no model weights into ComfyUI. LM Studio does all the heavy lifting; this node is just a polite HTTP client in a node-shaped costume.

The name's other half is the intended use. Slartibart23 built it around HauhauCS/Qwen3.5-35B-A3B-Uncensored-HauhauCS-Aggressive, a Qwen3.5 vision model, and the README makes the pitch unsubtle: in his testing, this stack captioned adult content "stronger" than JoyCaption Beta One, the usual community default for uncensored natural-language captions. You can point it at any vision model in LM Studio, though - the model field is just a string.

Why reach for it? Two jobs, straight out of the LLM-in-the-graph playbook: captioning a dataset for LoRA training (natural language, the right call for FLUX and the other LLM-encoded checkpoints), and seeding an img2img or image-to-video prompt from a reference image. A local captioner keeps everything on your machine, which matters when your content would get bounced by an API filter. It's the JoyCaption argument, with the twist that you can swap in whatever vision model you like without waiting for a node pack to support it.

How it works

Under the hood it's about as simple as a Comfy node gets. Your IMAGE tensor becomes a PIL image, gets base64-encoded (default data_uri_jpeg), and is POSTed to http://127.0.0.1:1234/v1/chat/completions, LM Studio's OpenAI-compatible endpoint. The response's choices[0].message.content is what comes back as caption. The only dependency is requests, which you already have. There's no key; the auth header is the literal string Bearer lm-studio.

The inputs that actually matter

The node dumps a dozen inputs on you, but most have sane defaults. Set these three first:

  • model - the exact model ID LM Studio reports. Ask its server: Invoke-RestMethod http://127.0.0.1:1234/v1/models | ConvertTo-Json -Depth 10 and paste the id in.
  • prompt - here's a trap: the default is in German, asking for a 1–3 sentence German caption. The author is German. If you want English or FLUX-style output, write your own, or copy the prompts/flux_image_to_prompt_template.txt from the repo.
  • server_url - only touch it if LM Studio isn't on the default port.

Then two switches decide whether you get clean output. thinking_mode: no_think prepends /no_think to the prompt, stopping reasoning models from burning every token on deliberation - this node's real job is taming a reasoner, because the recommended model wants to think. fallback_mode: final_or_reasoning uses content and falls back to reasoning_content when the final answer comes back empty, which happens on quantized Qwen models more often than anyone admits.

temperature (0.1–0.4 for captioning), max_tokens (4096), and the seed trio are worth a glance but leave them alone initially - and keep send_seed_to_lmstudio off, since some vision models return empty content when handed a seed. Output is one caption string; wire it into anything that takes text - a save node, a prompt builder, or a training-set writer.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/Slartibart23/comfyui-lmstudio-qwen35-captioning.git

Restart ComfyUI completely - the path must be custom_nodes/comfyui-lmstudio-qwen35-captioning/__init__.py, and the repo warns specifically about the wrong-folder mistake. You can also find it in ComfyUI Manager under the pack title. It's MIT-licensed with no heavy deps: no model download, just requests.

The real install cost is on the LM Studio side. The recommended 35B-A3B MoE is a big vision model - the README says RTX 5090 class GPU, and it means it. Anything smaller should grab a smaller or more heavily quantized vision GGUF instead. In LM Studio: load the model, open Developer, start the local server, leave it running, and paste the model ID into the node.

Where people get burned

  • Node missing after install - wrong folder or no full restart; check the console for import errors.
  • "Invalid url" from LM Studio - use image_format: data_uri_jpeg, not raw_base64; some setups reject the bare base64.
  • Empty caption / reasoning bleed - you're hitting the reasoner problem. no_think + final_or_reasoning + max_tokens: 4096 is the fix the README prescribes.
  • Cut-off or over-analytical output - the model spent its token budget thinking. Raise max_tokens and LM Studio's context length (16384+), and simplify the prompt to demand only the final caption.

One honest caveat before you wire it into a big training run: it's a brand-new, near-zero-install pack from a single author, and this ecosystem has seen a malicious "LLM vision" node before. That said, this one is as boring as they get - all it does is POST to a URL you specify, defaulting to localhost. Read it, use it, and keep the README's note in mind: legal, consenting-adult captioning only.

CategoryLM Studio

Inputs (13)

NameTypeDefaultDescription
imageIMAGEInput image from ComfyUI. The image is sent to LM Studio without resizing.
server_urlSTRINGhttp://127.0.0.1:1234/v1/chat/completionsLM Studio OpenAI-compatible chat completions endpoint.
modelSTRINGDEINE_MODEL_ID_HIER_EINTRAGENExact model ID as reported by LM Studio, for example from /v1/models.
promptSTRINGErstelle eine deutsche Bildcaption in 1 bis 3 Sätzen. Keine Analyse. Keine Stichpunkte. Nur die finale Caption.Instruction sent to the vision model together with the image.
thinking_modeCOMBOno_thinkno_think prepends /no_think to the prompt. This helps some Qwen reasoning models output final content. Use normal for models that do not understand /no_think.
image_formatCOMBOdata_uri_jpegHow the image is embedded in the request. data_uri_jpeg sends data:image/jpeg;base64,... data_uri_png sends data:image/png;base64,... raw_base64 sends plain base64 only; your LM Studio setup previously rejected this.
seed_modeCOMBOfixedfixed keeps the same seed value. random creates a new seed on every run and also helps force ComfyUI to re-execute the node.
seedINT420–2147483647Seed value used when seed_mode is fixed.
send_seed_to_lmstudioCOMBOoffIf off, the seed is only used inside ComfyUI. Recommended: off, because some local vision models return empty content when seed is sent.
temperatureFLOAT0.200–2Controls randomness. Lower values are more deterministic. For captioning, 0.1 to 0.4 is usually good.
max_tokensINT409632–262144Maximum number of output tokens. For reasoning models, use 2048-4096 so the model can finish after reasoning. Actual usable size depends on LM Studio context length.
debug_responseCOMBOonPrint the full LM Studio JSON response to the ComfyUI console.
fallback_modeCOMBOfinal_or_reasoningfinal_only uses choices[0].message.content only. final_or_reasoning uses content and falls back to reasoning_content if content is empty. reasoning_only always outputs reasoning_content. german_draft_from_reasoning tries to extract a German draft section from reasoning_content.

Outputs (1)

NameTypeDescription
captionSTRINGCaption text returned by LM Studio.