Release 1.0.6: remove Krea2 VLM Preview node

The preview only exposed the decode-path (lm_head) refusals of abliterated
models and didn't reflect the conditioning (hidden-state) path, so it was
misleading. Encoder + Krea2 System Prompt nodes unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Ethanfel
2026-06-27 09:20:24 +02:00
co-authored by Claude Opus 4.8
parent e02c57f689
commit 38da10b0d4
4 changed files with 3 additions and 89 deletions
-12
View File
@@ -56,18 +56,6 @@ downstream of this node — that works generically at the sampler level.)
**Output:** `conditioning` for the Krea2 sampler. (`print_prompt` dumps the assembled Qwen3-VL
prompt to the console for debugging.)
## Inspecting what the VLM sees — `Krea2 VLM Preview`
The conditioning path only extracts hidden states; it never generates text. To actually *read*
how Qwen3-VL interprets your image + prompt, use the **`Krea2 VLM Preview`** node: it mirrors the
encoder's image/template prep, then runs the model **generatively** (`clip.generate` → `decode`)
and outputs the text. Same `vision_megapixels` / `mask_padding` / `vision_position` / `system_prompt`
controls, plus `max_length` / `temperature` / `seed`.
Notes: it's a *proxy* (the generated text shares the VLM's forward understanding but isn't the
hidden-state tensor the sampler uses); it needs the encoder's `lm_head` weights; and image inputs
require a **bf16** encoder (FP8 vision is unsupported — see below).
## System prompt (making the prompt interact with the image)
`system_prompt` is a connectable text **input**, not a widget — leave it unconnected to use
+1 -75
View File
@@ -157,8 +157,7 @@ class TextEncodeKrea2:
@classmethod
def _prepare_vision(cls, kwargs, vision_megapixels, mask_padding):
"""Crop+resize each connected reference and build the vision-token string.
Shared by the encoder and the VLM preview so both feed the model identically."""
"""Crop+resize each connected reference and build the vision-token string."""
images = cls._collect_indexed(kwargs, "image")
masks = cls._collect_indexed(kwargs, "mask")
ordered = sorted(images.keys())
@@ -207,19 +206,6 @@ class TextEncodeKrea2:
)
return None
@staticmethod
def _quiet_token_progress():
"""Silence ComfyUI's per-token tqdm bar during generation (it prints one console line
per token on consoles that don't honor carriage returns). The UI progress ring, driven
by a separate comfy.utils.ProgressBar, still updates. Returns a restore() callable."""
try:
import comfy.text_encoders.llama as _llama
orig = _llama.tqdm
_llama.tqdm = lambda it=None, *a, **k: (it if it is not None else orig(*a, **k))
return lambda: setattr(_llama, "tqdm", orig)
except Exception:
return lambda: None
def encode(self, clip, prompt, vision_megapixels=1.0, mask_padding=0.0,
system_prompt=KREA2_SYSTEM_DEFAULT, vision_position="before prompt",
print_prompt=False, **kwargs):
@@ -272,72 +258,12 @@ class Krea2SystemPrompt:
return (text,)
class Krea2VLMPreview:
"""Runs Krea2's Qwen3-VL encoder GENERATIVELY on the same image+prompt the encoder feeds,
returning the model's text output — a proxy for what the VLM 'sees'. Needs the encoder's
lm_head in the weights; use a bf16/fp16 encoder for image inputs (FP8 vision is unsupported)."""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"clip": ("CLIP",),
"prompt": ("STRING", {"multiline": True, "dynamicPrompts": True}),
},
"optional": {
"system_prompt": ("STRING", {
"forceInput": True,
"tooltip": "Same as the encoder's system_prompt input; unconnected = Krea2 descriptor.",
}),
"image1": ("IMAGE",),
"mask1": ("MASK",),
"vision_megapixels": ("FLOAT", {"default": 1.0, "min": 0.1, "max": 8.0, "step": 0.1}),
"mask_padding": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 1.0, "step": 0.02}),
"vision_position": (["before prompt", "after prompt"], {"default": "before prompt"}),
"max_length": ("INT", {"default": 256, "min": 1, "max": 8192,
"tooltip": "Max number of tokens to generate."}),
"temperature": ("FLOAT", {"default": 0.7, "min": 0.0, "max": 2.0, "step": 0.01,
"tooltip": "0 = greedy/deterministic."}),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
},
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("vlm_text",)
FUNCTION = "preview"
CATEGORY = "model/conditioning/krea2"
DESCRIPTION = ("Generate text from Krea2's Qwen3-VL encoder on the same image+prompt the encoder "
"sends, to inspect how the VLM reads your reference. Needs lm_head weights; use a "
"bf16 encoder for image inputs.")
def preview(self, clip, prompt, vision_megapixels=1.0, mask_padding=0.0,
system_prompt=KREA2_SYSTEM_DEFAULT, vision_position="before prompt",
max_length=256, temperature=0.7, seed=0, **kwargs):
images_vl, image_prompt = TextEncodeKrea2._prepare_vision(kwargs, vision_megapixels, mask_padding)
text, template = TextEncodeKrea2._build_text(system_prompt, prompt, image_prompt, vision_position)
tokens = clip.tokenize(text, images=images_vl, llama_template=template)
restore = TextEncodeKrea2._quiet_token_progress()
try:
ids = clip.generate(tokens, do_sample=(temperature > 0.0), max_length=max_length,
temperature=max(temperature, 0.01), seed=seed)
except NotImplementedError as exc:
hint = TextEncodeKrea2._fp8_hint(exc, images_vl)
if hint is not None:
raise hint from exc
raise
finally:
restore()
return (clip.decode(ids),)
NODE_CLASS_MAPPINGS = {
"TextEncodeKrea2": TextEncodeKrea2,
"Krea2SystemPrompt": Krea2SystemPrompt,
"Krea2VLMPreview": Krea2VLMPreview,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"TextEncodeKrea2": "Text Encode (Krea2)",
"Krea2SystemPrompt": "Krea2 System Prompt",
"Krea2VLMPreview": "Krea2 VLM Preview",
}
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui-krea2-text-encoder"
description = "Vision-aware text conditioning for the Krea2 / K2 model. Feeds reference images through the Qwen3-VL-4B vision path with the Krea2 descriptor template; optional per-image mask crops to the masked region. No VAE (Krea2 has no reference-latent pathway). Auto-growing image+mask slots."
version = "1.0.5"
version = "1.0.6"
license = "MIT"
requires-python = ">=3.10"
dependencies = []
+1 -1
View File
@@ -3,7 +3,7 @@ import { app } from "../../scripts/app.js";
// Auto-growing reference slots for "Text Encode (Krea2)": each reference is an
// (imageN, maskN) pair. Keep exactly one empty trailing pair, appending a fresh
// pair whenever the last one gets connected.
const NODE_NAMES = new Set(["TextEncodeKrea2", "Krea2VLMPreview"]);
const NODE_NAMES = new Set(["TextEncodeKrea2"]);
const IMAGE_RE = /^image(\d+)$/;
function pairNumbers(node) {