Expose long-text fields as input sockets (forceInput)
axes, reference_description, system_prompt, user_prompt now render as INPUT SOCKETS (forceInput) so they can be wired from other nodes — e.g. describe's canonical output -> compare's reference_description, or a text node -> chat prompts. Small config (report_dir, run_tag, model_path, ...) stays as typeable fields. Unconnected sockets fall back to sensible defaults; the agent/bridge can still set them by value via the API. Dropped the now-socket fields from the example workflows; bumped their max_new_tokens to 2048. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -37,14 +37,15 @@ can act on it.
|
|||||||
| `model_select` | dropdown (model name) | 4B local | **which judge** (transformers/safetensors, auto-downloaded): Qwen3-VL 4B/8B/30B-A3B, **Qwen3.5-9B**, **Qwen3.6-27B/35B-A3B** (newer, natively multimodal). Param size shown in the label |
|
| `model_select` | dropdown (model name) | 4B local | **which judge** (transformers/safetensors, auto-downloaded): Qwen3-VL 4B/8B/30B-A3B, **Qwen3.5-9B**, **Qwen3.6-27B/35B-A3B** (newer, natively multimodal). Param size shown in the label |
|
||||||
| `precision` | bf16 / fp8 / nf4 | bf16 | **the quant** — applies to the selected model (VRAM table below) |
|
| `precision` | bf16 / fp8 / nf4 | bf16 | **the quant** — applies to the selected model (VRAM table below) |
|
||||||
| `model_path` | STRING | "" (empty) | **manual override** of the dropdown — local dir, HF repo id, or alias (`8b`/`30b-a3b`/`3.5-9b`/`3.6-27b`/`3.6-35b`). Empty = use `model_select` |
|
| `model_path` | STRING | "" (empty) | **manual override** of the dropdown — local dir, HF repo id, or alias (`8b`/`30b-a3b`/`3.5-9b`/`3.6-27b`/`3.6-35b`). Empty = use `model_select` |
|
||||||
| `axes` | STRING | "" (empty) | **override** the profile's axis set with a custom comma/newline list; empty = use `profile` |
|
| `axes` | STRING **input** | — | (socket) optional override of the profile's axis set; wire a text node or leave unconnected to use `profile` |
|
||||||
| `max_new_tokens` | INT | 2048 | raise it if a reasoning model (Qwen3.5/3.6) gets cut off before finishing |
|
| `max_new_tokens` | INT | 2048 | raise it if a reasoning model (Qwen3.5/3.6) gets cut off before finishing |
|
||||||
| `temperature` | FLOAT | 0.0 | 0 = greedy/repeatable |
|
| `temperature` | FLOAT | 0.0 | 0 = greedy/repeatable |
|
||||||
| `swap_eval` | BOOL | true | run twice with images swapped, average → cuts position bias |
|
| `swap_eval` | BOOL | true | run twice with images swapped, average → cuts position bias |
|
||||||
| `keep_loaded` | BOOL | true | cache weights across loop iterations |
|
| `keep_loaded` | BOOL | true | cache weights across loop iterations |
|
||||||
| `auto_download` | BOOL | true | if `model_path` is a repo id/alias and not local, fetch it from HF into `models/prompt_generator/` |
|
| `auto_download` | BOOL | true | if `model_path` is a repo id/alias and not local, fetch it from HF into `models/prompt_generator/` |
|
||||||
| `system_prompt` | STRING | "" | **chat mode**: your system prompt |
|
| `system_prompt` | STRING **input** | — | (socket) chat mode: wire your system prompt from a text node |
|
||||||
| `user_prompt` | STRING | "Describe this image." | **chat mode**: your instruction over the image(s) |
|
| `user_prompt` | STRING **input** | — | (socket) chat mode: wire your instruction from a text node |
|
||||||
|
| `reference_description` | STRING **input** | — | (socket) compare: wire describe's canonical output here to anchor the reference |
|
||||||
|
|
||||||
**Auto-download:** set `model_path` to `30b-a3b` (alias) or any `org/name` repo id and leave
|
**Auto-download:** set `model_path` to `30b-a3b` (alias) or any `org/name` repo id and leave
|
||||||
`auto_download` on — the node snapshot-downloads it on first run (into ComfyUI's
|
`auto_download` on — the node snapshot-downloads it on first run (into ComfyUI's
|
||||||
|
|||||||
+12
-12
@@ -795,34 +795,34 @@ class QwenVLImageJudge:
|
|||||||
{"default": list(MODEL_PRESETS.keys())[0]}),
|
{"default": list(MODEL_PRESETS.keys())[0]}),
|
||||||
"model_path": ("STRING", {"default": ""}), # manual override (local dir / HF repo / alias)
|
"model_path": ("STRING", {"default": ""}), # manual override (local dir / HF repo / alias)
|
||||||
"precision": (["bf16", "fp8", "nf4"], {"default": "bf16"}),
|
"precision": (["bf16", "fp8", "nf4"], {"default": "bf16"}),
|
||||||
"axes": ("STRING", {"default": "", "multiline": True}),
|
|
||||||
"max_new_tokens": ("INT", {"default": 2048, "min": 64, "max": 8192}),
|
"max_new_tokens": ("INT", {"default": 2048, "min": 64, "max": 8192}),
|
||||||
"temperature": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.5, "step": 0.05}),
|
"temperature": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.5, "step": 0.05}),
|
||||||
"swap_eval": ("BOOLEAN", {"default": True}),
|
"swap_eval": ("BOOLEAN", {"default": True}),
|
||||||
"keep_loaded": ("BOOLEAN", {"default": True}),
|
"keep_loaded": ("BOOLEAN", {"default": True}),
|
||||||
"auto_download": ("BOOLEAN", {"default": True}),
|
"auto_download": ("BOOLEAN", {"default": True}),
|
||||||
# The agent reads the analysis from these files after each queue.
|
# Small config values stay as typeable fields.
|
||||||
"report_dir": ("STRING", {"default": ""}),
|
"report_dir": ("STRING", {"default": ""}),
|
||||||
"run_tag": ("STRING", {"default": ""}),
|
"run_tag": ("STRING", {"default": ""}),
|
||||||
# compare: canonical reference text (from describe). When set, compare
|
|
||||||
# anchors on it instead of re-reading the reference image each time.
|
|
||||||
"reference_description": ("STRING", {"default": "", "multiline": True}),
|
|
||||||
# chat mode: use the node as a general VLM with your own prompts.
|
|
||||||
"system_prompt": ("STRING", {"default": "", "multiline": True}),
|
|
||||||
"user_prompt": ("STRING", {"default": "Describe this image.", "multiline": True}),
|
|
||||||
},
|
},
|
||||||
# Only genuine node-to-node wires stay optional (widgets in `optional` render
|
# Long text content is exposed as INPUT SOCKETS (forceInput) so it can be wired
|
||||||
# as input sockets instead of editable fields in some ComfyUI frontends).
|
# from other nodes — e.g. describe's canonical output -> reference_description, a
|
||||||
|
# text node -> system_prompt/user_prompt. Left unconnected, sensible defaults apply
|
||||||
|
# (empty axes -> profile; empty reference_description -> two-image compare). The
|
||||||
|
# agent/bridge can still set them by value via the API.
|
||||||
"optional": {
|
"optional": {
|
||||||
"generated_image": ("IMAGE",), # required for compare, ignored for describe/chat
|
"generated_image": ("IMAGE",), # required for compare, ignored for describe/chat
|
||||||
|
"axes": ("STRING", {"forceInput": True}),
|
||||||
|
"reference_description": ("STRING", {"forceInput": True}),
|
||||||
|
"system_prompt": ("STRING", {"forceInput": True}),
|
||||||
|
"user_prompt": ("STRING", {"forceInput": True}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
def judge(self, reference_image, mode, model_path, precision, axes,
|
def judge(self, reference_image, mode, model_path, precision,
|
||||||
max_new_tokens, temperature, swap_eval, profile="general",
|
max_new_tokens, temperature, swap_eval, profile="general",
|
||||||
model_select=MANUAL_CHOICE, generated_image=None,
|
model_select=MANUAL_CHOICE, generated_image=None,
|
||||||
keep_loaded=True, auto_download=True,
|
keep_loaded=True, auto_download=True,
|
||||||
report_dir="", run_tag="", reference_description="",
|
report_dir="", run_tag="", axes="", reference_description="",
|
||||||
system_prompt="", user_prompt="Describe this image."):
|
system_prompt="", user_prompt="Describe this image."):
|
||||||
# `axes` overrides the profile when provided; otherwise use the profile's axis set.
|
# `axes` overrides the profile when provided; otherwise use the profile's axis set.
|
||||||
axis_list = [a.strip() for a in re.split(r"[,\n]", axes) if a.strip()]
|
axis_list = [a.strip() for a in re.split(r"[,\n]", axes) if a.strip()]
|
||||||
|
|||||||
@@ -68,15 +68,13 @@
|
|||||||
"model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16",
|
"model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16",
|
||||||
"precision": "bf16",
|
"precision": "bf16",
|
||||||
"profile": "general",
|
"profile": "general",
|
||||||
"axes": "",
|
"max_new_tokens": 2048,
|
||||||
"max_new_tokens": 512,
|
|
||||||
"temperature": 0.0,
|
"temperature": 0.0,
|
||||||
"swap_eval": true,
|
"swap_eval": true,
|
||||||
"keep_loaded": true,
|
"keep_loaded": true,
|
||||||
"auto_download": true,
|
"auto_download": true,
|
||||||
"report_dir": "/media/p5/Comfyui/output/calibrator",
|
"report_dir": "/media/p5/Comfyui/output/calibrator",
|
||||||
"run_tag": "",
|
"run_tag": ""
|
||||||
"reference_description": ""
|
|
||||||
},
|
},
|
||||||
"_meta": { "title": "Qwen3-VL Image Judge (Calibrator)" }
|
"_meta": { "title": "Qwen3-VL Image Judge (Calibrator)" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,7 @@
|
|||||||
"profile": "general",
|
"profile": "general",
|
||||||
"model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16",
|
"model_path": "/media/p5/qwen3vl_4b_abliterated_comfy_convert/hf_bf16",
|
||||||
"precision": "bf16",
|
"precision": "bf16",
|
||||||
"axes": "",
|
"max_new_tokens": 2048,
|
||||||
"max_new_tokens": 1024,
|
|
||||||
"temperature": 0.0,
|
"temperature": 0.0,
|
||||||
"swap_eval": false,
|
"swap_eval": false,
|
||||||
"keep_loaded": true,
|
"keep_loaded": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user