Nodes/ComfyUI LM Studio/LM Studio Generate Text
ComfyUI Node

LM Studio Generate Text

Caption Your Whole LoRA Dataset Without an API Key

By Winnougan·Created 2 months ago·Updated 2 months ago· 3
LM Studio Generate Text
  • connection
  • image
  • generated_text
promptDescribe this image.
max_tokens500
temperature0.70
top_p0.95
seed0
system_prompt
max_image_size1024
image_formatjpeg
batch_separator

This is the node you came for. Wire in your images, get captions out as plain text - local, free per call, and nothing ever leaves your machine. It replaces TextGenerate in the built-in CLIPLoader → TextGenerate pair, and it's the engine for this pack's headline job: building a LoRA training dataset. Where the cloud captioning route costs per call and ships your reference images to someone else's server, this one runs a vision model on your own hardware through LM Studio's OpenAI-compatible endpoint. VLM captioning a dataset is the default move for LLM-encoded bases these days (llm-in-comfyui.md calls the pattern won); this is just the version that needs no key and no upload.

How it works

The node takes the connection dict from LMStudioConnection and POSTs to {base_url}/chat/completions with standard OpenAI-style chat messages. With an image wired in, it downscales the frame to max_image_size (default 1024, LANCZOS), base64-encodes it as a JPEG, and attaches it as an image_url message - so a vision model actually sees the picture. No image means a plain text assistant call. It retries transient network errors with backoff, but deliberately does not retry HTTP errors from LM Studio, since those are deterministic (bad payload, context overflow). And despite the README claiming otherwise, the shipped code sends one request per image in a batch tensor, joining the results with batch_separator - five images, five calls, and you'll see Captioning image 3/5... in the console.

The inputs that matter

  • max_tokens - the trap, and the one to touch first. The 500 default is fine for plain instruct models, but reasoning/thinking models (Gemma "thinking" variants, Qwen thinking modes, R1 distills) burn the whole budget writing a hidden reasoning_content field, then return an empty content. The node falls back to the raw reasoning text with a console warning - messy chain-of-thought, not a caption. Give non-reasoning models 500–1000, reasoning models 4000–8000, or better, disable thinking mode in LM Studio entirely.
  • prompt - your caption instruction (default "Describe this image."). Tune it to your base model's caption style - this is where you decide "flowing sentence" vs "tag-ish."
  • image (optional) - any IMAGE output (LoadImage, etc.). The model must be vision-capable or it errors or silently ignores the image.
  • system_prompt (optional) - a persistent persona/format instruction sent as the system message.
  • temperature, top_p, seed - standard sampling; seed 0 means no fixed seed, set a value for reproducible captions.
  • image_format, max_image_size, batch_separator - leave alone until you hit a problem: JPEG is ~10× faster and smaller than PNG (switch to PNG for text-heavy images), and the batch separator defaults to a blank line between captions.

The single output, generated_text, is a plain STRING - wire it into ShowText|pysssss to preview, SaveText|pysssss to write .txt files for training, or anywhere else a STRING is expected. A LoadImage → Connection → GenerateText → SaveText line is the whole dataset-captioning workflow.

Install and setup

Same pack install as the connection node: ComfyUI Manager (search "LM Studio" / comfyui-lmstudio) or:

cd ComfyUI/custom_nodes
git clone https://github.com/Winnougan/comfyui-lmstudio

Then restart, load a vision model in LM Studio, go to Developer → Start Server, and confirm the port matches base_url in the connection node (default 1234). The pack downloads no models and its dependencies (requests, Pillow, numpy) are already ComfyUI's.

Gotchas

Empty output with finish_reason: length in the console? Your model spent max_tokens thinking and never wrote an answer - raise the budget or kill thinking mode. Text-only model with an image wired in? It'll error or ignore the picture. And set expectations on throughput: every call ships a full base64 JPEG, so a modest local GPU captions noticeably slower than a cloud vision API. Finally, the weakness every VLM shares is multi-subject attribution - auto-caption the large set, but audit a small one by hand (lora-training.md). For captioning, small-and-obedient beats clever: you don't need the model to reason out loud, you need it to follow the format and stop.

CategoryLM Studio

Inputs (11)

NameTypeDefaultDescription
connectionLM_STUDIO_CONNECTION
promptSTRINGDescribe this image.
max_tokensINT5001–8192
temperatureFLOAT0.700–2
top_pFLOAT0.950–1
seedINT00–4294967295
imageoptIMAGE
system_promptoptSTRING
max_image_sizeoptINT1024256–4096Images are downscaled so their longest side is at most this many pixels before sending. Most VLMs resize internally anyway, so larger values mostly cost latency, not quality.
image_formatoptCOMBOjpegjpeg: ~10x faster encode, ~10x smaller payload. png: lossless, better for pixel-exact or text-heavy images.
batch_separatoroptSTRING When `image` is a batch of more than one image, each image gets its own request and the resulting captions are joined with this string.

Outputs (1)

NameTypeDescription
generated_textSTRING