FL VLM Image Inference
Getting Qwen3-VL to actually read your images
- vlm_model
- image
- response
- metadata_json
This is the node that does the work the pack is named for. FL VLM Model Loader gets the engine into VRAM; this one points it at an image - or a whole batch of them - and hands back text. Feed it any ComfyUI IMAGE tensor, get a response string and a metadata_json string out. That's the whole contract, and it's refreshingly small for a vision-language node.
You reach for it for two jobs. First: captioning a dataset for LoRA training, where a VLM doing the bulk of the descriptions is the community default. Second: seeding a prompt from an existing image for img2img or image-to-video, the describe-then-enhance-then-generate chain. Qwen3-VL sits at the heavy end of that work - the 32B is what people grab when they want maximum description accuracy before a second model reshapes it into a prompt. Running it here means it's local, offline, and free per call, no API key in sight.
How it works
It slices your image batch using image_start, image_stride, and max_images (the batch dimension is frames), writes the selected frames to temporary PNGs, and builds a system + user message with Qwen's chat template and its min_pixels/max_pixels visual budget. Then it runs model.generate, greedy by default, and decodes the result. In each_image_separately mode it loops per image and concatenates labeled responses ([image 0], [image 1], ...). Along the way it pushes a live progress feed - stage by stage, then token by token - and it cleans up its temp files when it's done.
Inputs that matter
- vlm_model - must come from this pack's FL VLM Model Loader. The node checks the backend and refuses a foreign model, which is a friendly error, not a bug.
- image - any
IMAGEtensor, single frame or a full batch. This is the only real prerequisite beyond the model. - system_prompt / prompt - full Qwen prompting, both fields. The default prompt ("Describe the image in detail.") is fine for a first test.
- batch_mode -
all_images_one_promptsends everything in one call for "compare these" or "describe this sequence";each_image_separatelyis the per-image captioning mode. - resize_preset -
244p_fastup to720p_high, defaulting to360p_balanced. This is your main speed knob: Qwen's pixel budget controls both speed and how much detail it can see.manual_qwen_budgetexposesmin_pixels/max_pixelsdirectly if you know what you're doing. - max_new_tokens - response length cap (512 default).
- do_sample + temperature/top_p/top_k - off by default for deterministic captioning; flip it on with a seed for creative output.
Outputs
response is the text - drop it into a Show Text node or save it to a file. metadata_json is a compact JSON string carrying the model id, batch settings, the exact pixel budget used, and (in per-image mode) a structured array of responses. Handy if you're scripting over the results.
Gotchas
The big one, from real Qwen3-VL-in-ComfyUI experience: feeding a large image causes a VRAM spike and OOMs. The community fix is exactly what this node's resize_preset exists for - keep big renders at 360p_balanced or 244p_fast when all you need is a caption, and resize inputs before they hit the node. Detail and pixels trade off directly here.
If you get "No images selected", your image_start/image_stride/max_images combination sliced the batch to nothing - raise max_images or drop the stride. First run downloads the model (see the loader article for sizes), so don't panic at the hang. And remember every VLM shares one weakness the KB spells out: with two people in frame they mix up who's wearing what. Auto-caption a large set, but audit a small one by hand.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| vlm_model | FL_VLM_MODEL | — | |
| image | IMAGE | — | |
| system_prompt | STRING | You are a precise vision-language assistant. Answer only from the provided image content. | — |
| prompt | STRING | Describe the image in detail. | — |
| batch_mode | COMBO | all_images_one_prompt | 2 options: all_images_one_prompt, each_image_separately |
| image_start | INT | 00–100000 | — |
| image_stride | INT | 11–100000 | — |
| max_images | INT | 161–512 | — |
| min_pixels | INT | 6464–4096 | Qwen visual token budget lower bound. Internally multiplied by 28*28. |
| max_pixels | INT | 25664–8192 | Qwen visual token budget upper bound for manual_qwen_budget. Internally multiplied by 28*28. |
| max_new_tokens | INT | 5121–8192 | — |
| do_sample | BOOLEAN | false | — |
| temperature | FLOAT | 0.700–5 | — |
| top_p | FLOAT | 0.900–1 | — |
| top_k | INT | 500–500 | — |
| repetition_penalty | FLOAT | 1.000.1–5 | — |
| seed | INT | -1-1–18446744073709550000 | — |
| cleanup_temp_images | BOOLEAN | true | — |
| resize_preset | COMBO | 360p_balanced | Controls Qwen's image resize budget before inference. Existing min_pixels/max_pixels are only used by manual_qwen_budget. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| response | STRING | — |
| metadata_json | STRING | — |