EmAySee Llama Vision
A vision LLM node that isn't Llama and doesn't need a key — point it at Ollama
- image
- text
Read the name as a lie, then read the defaults
EmAySee_LlamaVision does not call any Llama API, is not tied to Llama models, and needs no API key. It's a generic vision-LLM captioning client: you give it an image and a prompt, it ships the image to a local OpenAI-compatible server, and returns the model's description as a string. The default model name is qwen2-vl - not Llama at all - which tells you everything about how much the title should be trusted.
The pattern itself is well-trodden and worth having: a local vision model describing your image feeds captioning, tagging, and dataset-prep loops without any data leaving your machine. People run exactly this with Ollama or LM Studio behind a ComfyUI node, and it's a solid alternative to cloud APIs when you're building a training set. The one genuine gotcha is front and center in the defaults: server_url ships as http://10.0.0.71:11434 - that's the author's own LAN IP. You will not reach that. Change it to your Ollama instance (http://localhost:11434 is the usual) or your LM Studio / llama.cpp server's address, or every request will fail after a retry loop.
How it works
The mechanism is standard OpenAI-compatible chat-completions. It converts the image tensor to a JPEG, base64-encodes it, and POSTs a {server_url}/v1/chat/completions request with a system message, a user message containing your prompt plus the image as a data:image/jpeg;base64,... URL, max_tokens, and temperature. It then reads choices[0].message.content out of the response. It retries up to five times with exponential backoff, so a briefly-flaky server won't kill a batch - though five failed attempts just produce an error string as the output rather than raising.
Inputs
image(IMAGE) - the image to describe. Note it only sends the first frame (image[0]), so a multi-frame batch gets captioned from frame one.model(STRING) - defaultqwen2-vl. Whatever your server has loaded, as long as it accepts images.system_prompt- default "You are a specialized image captioning assistant for AI training datasets." Tune this hard; it's where output quality lives.prompt- default "Describe this image in detail."server_url- the one you must change.max_tokens(1–8192, default 1024) andtemperature(0–2, default 0.2). Keep temperature low for consistent captions.
Output: text (STRING) - the model's reply, ready for a text encoder, a save node, or your captioning pipeline.
Install
From ComfyUI_EmAySee_CustomNodes:
cd ComfyUI/custom_nodes
git clone https://github.com/EmAySee/ComfyUI_EmAySee_CustomNodes
# restart ComfyUI
Or via ComfyUI Manager → "ComfyUI_EmAySee_CustomNodes". No pip dependencies - it uses only urllib, PIL, and numpy, all already present. The heavy lifting lives on the server side: you need a running Ollama/LM Studio/llama.cpp instance with a vision model pulled.
Gotchas
Beyond the server URL, the real-world pain is output quality. Local vision models are decent at literal description but notorious for inventing booru-style tags that don't exist, which poisons Illustrious/NoobAI-era tag pipelines - people hit exactly this with the same setup. If you're captioning for training, pair this with a filter or keep a human pass, and consider EmAySee_LLMOutputCleaner to strip <think> reasoning traces from DeepSeek-style models that don't clean up after themselves.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| model | STRING | qwen2-vl | — |
| system_prompt | STRING | You are a specialized image captioning assistant for AI training datasets. | — |
| prompt | STRING | Describe this image in detail. | — |
| server_url | STRING | http://10.0.0.71:11434 | — |
| max_tokens | INT | 10241–8192 | — |
| temperature | FLOAT | 0.200–2 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |