Nodes/Kinburg-Nodes/Local LLM Server
ComfyUI Node

Local LLM Server

Run llama-server under ComfyUI so one GPU hosts your chat and your images

By Kinburg·Created 3 months ago·Updated 4 days ago· 1
Local LLM Server
  • draft
  • vision
  • embeddings
  • status
  • base_url
  • server_log
  • help
◄actionserve►
◄flavourllama-server►
◄server_binary▾►
◄server_binary_path►
◄model▾►
◄model_path►
◄n_ctx8192►
◄n_gpu_layers-1►
◄extra_args►
◄listen_host127.0.0.1►
◄listen_port5001►
◄autoloadtrue►
◄free_on_prompttrue►
◄idle_unload_minutes0►
◄unload_comfy_modelstrue►
◄fix_paramstrue►
◄auto_retrytrue►
◄drop_fields►
◄backend_port0►
◄ready_path►
◄startup_timeout300►
◄request_timeout900►
◄flash_attnauto►
◄kv_cache_typef16►
◄n_batch0►
◄n_ubatch0►
◄threads0►
◄cpu_moe_layers0►
◄parallel_slots0►
◄context_shifttrue►
◄alias►
◄api_key►
◄reasoningmodel default►
◄reasoning_budget-1►
◄reasoning_formatauto►
◄enable_thinkingmodel default►
◄reasoning_effortmodel default►
◄reasoning_effort_custom►
◄chat_template_file►
◄log_eventstrue►
◄log_textfalse►
◄log_server_outputfalse►

Local LLM Server exists for one specific headache: a chat model and an image model do not fit on the same GPU at once. If you've ever pointed a client like SillyTavern straight at llama-server while also generating images in ComfyUI, you know the failure - ComfyUI (or you) kills the LLM process to free the card, and the next chat message hits a closed port. Nothing is listening, so nothing can start the model back up. SillyTavern is still a genuinely live ecosystem in 2026, and the whole point of a local setup is keeping it off one card with your diffusion.

The node's answer is to split the listener from the model. It launches a real llama-server (or koboldcpp) as a subprocess under ComfyUI, behind a small gateway HTTP server that this ComfyUI process owns:

  • the gateway starts when you queue this node once and stays up as long as ComfyUI runs. That's the address you configure in the chat client and never touch again;
  • the model is a separate process on a private port that holds the VRAM. It loads on the first request that needs it and is killed whenever the VRAM is wanted elsewhere.

A chat message arriving with the model unloaded just waits for the load, then gets forwarded - the client sees a slow first reply, never an error. And requests that need no model, like the model list and health probe behind SillyTavern's Connect button, are answered by the gateway itself, so connecting works with nothing loaded at all.

The inputs that matter

It's a config-heavy node, but a beginner really sets five things:

  • action - serve (start the gateway, wait for the first request), serve + load the model now, reload the model, or stop everything.
  • server_binary - an executable to launch. This is the big gotcha: nothing is bundled. You download llama-server yourself from a llama.cpp release (or grab koboldcpp) and drop it under ComfyUI/models/llm, subfolders fine - the dropdown auto-lists anything it finds there recursively. If it's elsewhere, pick the placeholder and type a path in server_binary_path.
  • model - the .gguf from ComfyUI/models/llm to serve (or type a full path in model_path).
  • n_ctx (default 8192) and n_gpu_layers (-1 = all) - the usual two, and context is what eats VRAM fast once a long chat plus a character card fills it.
  • listen_port (default 5001) and listen_host (127.0.0.1 = this machine; 0.0.0.0 to reach it from the LAN).

Everything else is well-labelled and mostly "leave it alone until it bites": extra_args appends raw server flags (--flash-attn, --jinja, --model-draft …) and changing it reloads the model; autoload and unload_comfy_models handle the VRAM hand-off; fix_params repairs request bodies llama.cpp refuses (SillyTavern famously sends dry_sequence_breakers and friends as JSON strings where an array is required), and auto_retry drops an unknown field and retries when a 400 names one. free_on_prompt is the safety net: any queued prompt that isn't itself about the server unloads the model as it's queued, before a node of it runs. idle_unload_minutes frees VRAM after a quiet spell.

Four outputs: status, base_url (ends in /v1 - paste it into SillyTavern as a Custom OpenAI-compatible endpoint with no API key), server_log (your debugging friend when a load stalls), and help (a cheat sheet - wire it to a Preview as Text node). The gateway also answers /kinburg/status, /kinburg/unload and /kinburg/load in a browser.

Installing

Clone the pack or install "Kinburg-Nodes" via ComfyUI Manager and restart. One clarification people trip on: the pack's install.py installs the CUDA build of llama-cpp-python, but that's for the in-graph Local LLM (GGUF) nodes - this node doesn't use it at all, because it shells out to the external server binary you provide. If you only want the server pair, the binary and a .gguf in ComfyUI/models/llm are the actual prerequisites.

Where it bites

Model loads are slow the first time - raise startup_timeout (default 300s) if a big quant legitimately needs longer, and read server_log rather than guessing. Changing the model, n_ctx or extra_args reloads on the next request. And remember this node generates nothing itself: if you want a text answer inside a graph, that's Local LLM (GGUF), not this. This one is the sidecar - the thing that makes a local chat client and your image pipeline share one card without ever seeing each other's mess.

CategoryKinburg-Nodes/LLM

Inputs (45)

NameTypeDefaultDescription
actionCOMBOserveserve = start the gateway and wait for the first request. 'load now' also loads the model straight away. 'reload' kills a loaded model so the next request starts it fresh. 'stop everything' shuts the gateway down too.
flavourCOMBOllama-serverWhich server is being launched. It picks the flag names for every setting below — and a few settings only one of them has (the status output names those).
server_binaryCOMBOExecutable to launch. Auto-lists every llama-server / koboldcpp found anywhere under ComfyUI/models/llm, subfolders included; otherwise pick the placeholder and type a path below. Download or build it yourself — not bundled.
server_binary_pathSTRINGFull path to the server executable when the dropdown is the placeholder.
modelCOMBOThe .gguf from ComfyUI/models/llm to serve. Placeholder = type a path in model_path.
model_pathSTRINGFull path to the .gguf when 'model' is the placeholder.
n_ctxINT8192256–1048576Context size (--ctx-size / --contextsize). A long chat plus a character card eats this fast — and the KV cache grows with it.
n_gpu_layersINT-1-1–1000GPU layers (-ngl / --gpulayers). -1 = all.
extra_argsSTRINGRaw flags for what has no widget: rope/yarn, --tensor-split, --override-tensor, --lora, --fit… Appended last, so they win. Changing this reloads the model.
listen_hostSTRING127.0.0.1Where the gateway listens. 127.0.0.1 = this machine only; 0.0.0.0 to reach it from another box on the LAN.
listen_portINT50011–65535The port SillyTavern is pointed at. It stays open while ComfyUI runs, model or no model.
autoloadBOOLEANtrueLoad the model on the first request that needs one. Off = a request with nothing loaded gets a clear error instead.
free_on_promptBOOLEANtrueUnload whenever a ComfyUI prompt is queued that is not itself about the server — the safety net for image workflows you did not edit.
idle_unload_minutesINT00–1440Unload after this many minutes with no request. 0 = never.
unload_comfy_modelsBOOLEANtrueFree ComfyUI's own models from VRAM before loading the LLM.
fix_paramsBOOLEANtrueRepair the request bodies llama.cpp refuses — SillyTavern sends dry_sequence_breakers and friends as JSON strings where an array is required.
auto_retryBOOLEANtrueOn a 400 that names a field, drop that field and retry once, then strip it from later requests. Keeps one unknown option from breaking every message.
drop_fieldsSTRINGField names to strip from every request, one per line. The manual version of auto_retry.
backend_portINT00–65535Private port for the model server. 0 = pick a free one.
ready_pathSTRINGPath polled until the model is ready. Blank = per-flavour default (llama-server /health, koboldcpp /v1/models).
startup_timeoutINT30010–3600How long a load may take before it is called a failure.
request_timeoutINT90010–7200How long one forwarded request may take.
flash_attnCOMBOautoFlash Attention: faster, smaller KV cache. llama-server decides for itself on 'auto' and koboldcpp has it on already, so this is for forcing it off on a model that misbehaves.
kv_cache_typeCOMBOf16Quantize the KV cache to fit a longer chat in VRAM. q8_0 is nearly free; q4_0 is noticeable. Full effect needs Flash Attention — without it only K is quantized.
n_batchINT00–65536Logical batch size (-b / --blasbatchsize). 0 = the server's default. Bigger reads a long prompt faster and costs VRAM.
n_ubatchINT00–65536Physical batch size (-ub). 0 = default. llama-server only.
threadsINT00–256CPU threads (-t). 0 = the server's own choice. Matters only for what is not on the GPU.
cpu_moe_layersINT00–1000Keep the Mixture-of-Experts weights of the first N layers in system RAM (-ncmoe / --moecpu). 0 = off. On a MoE model this frees more VRAM per point of speed than anything else here; on a dense model it does nothing.
parallel_slotsINT00–64Concurrent request slots (-np / --multiuser). 0 = the server's default. Each slot costs its own share of the KV cache, so 1 is right for one chat.
context_shiftBOOLEANtrueLet the server drop the oldest tokens and keep going when the chat outgrows n_ctx. Off = it stops instead (--no-context-shift / --noshift).
aliasSTRINGThe model name the API reports, and what the gateway lists in /v1/models. Blank = the .gguf filename. llama-server only.
api_keySTRINGRequire this key on every request (--api-key / --password). Blank = no authentication. The gateway forwards whatever the client sends.
reasoningCOMBOmodel defaultThinking on or off (-rea). 'model default' leaves it to the model's template. koboldcpp can only express 'off'.
reasoning_budgetINT-1-1–1048576How many tokens thinking may spend before it is cut off (--reasoning-budget). -1 = unrestricted, 0 = end it immediately. llama-server only.
reasoning_formatCOMBOautoWhere the thoughts go. 'auto' (the default) hands them back separately as reasoning_content, which SillyTavern renders as its own collapsible block; 'none' leaves the raw think tags in the reply. llama-server only.
enable_thinkingCOMBOmodel defaultChat-template variable (--chat-template-kwargs), not prompt text — so the model cannot ignore it. 'model default' leaves it undefined, which each family reads its own way (Qwen3.5/3.8: ON, Gemma-4: OFF).
reasoning_effortCOMBOmodel defaultHow hard to think, as a chat-template variable. Qwen3.5/3.8 accept xhigh / medium / low and ERROR on anything else; use 'custom' for other families (gpt-oss: high).
reasoning_effort_customSTRINGEffort value sent when reasoning_effort = custom (e.g. 'high' for gpt-oss). Empty = send nothing.
chat_template_fileSTRINGA .jinja chat template that OVERRIDES the one in the GGUF (--chat-template-file). Empty = the model's own, which is right for almost every model. llama-server only.
log_eventsBOOLEANtrueFeed the 'LLM Server Live Log' node: every request with its status, duration, token counts and the sampler settings the client sent, plus loads, unloads and errors. No message text — see log_text.
log_textBOOLEANfalseAlso log the last user message and the reply, trimmed to a few hundred characters. OFF by default on purpose: that is somebody's conversation, and the log is drawn on the ComfyUI canvas for whoever is sitting there.
log_server_outputBOOLEANfalseAlso log llama.cpp's own stdout (slots, prompt-eval timings). Useful when a model misbehaves, noisy the rest of the time. It always reaches the 'server_log' output regardless.
draftoptKINBURG_LLM_SERVER_DRAFTOptional — wire an 'LLM Server Draft' node here for speculative decoding.
visionoptKINBURG_LLM_SERVER_VISIONOptional — wire an 'LLM Server Vision' node here to serve an mmproj so the chat client can send images.
embeddingsoptKINBURG_LLM_SERVER_EMBEDOptional — wire an 'LLM Server Embeddings' node here to serve /v1/embeddings (SillyTavern's Vector Storage) from the same address.

Outputs (4)

NameTypeDescription
statusSTRING—
base_urlSTRING—
server_logSTRING—
helpSTRING—