ArchAi3D_Qwen_Encoder
How text and up to three images become Qwen conditioning
- clip
- vae
- image1_vl
- image2_vl
- image3_vl
- image1_latent
- image2_latent
- image3_latent
- conditioning
- latent
- formatted_prompt
Every node in this pack that generates a prompt eventually feeds into one of these. ArchAi3D_Qwen_Encoder (V1) is the original: it takes your text, up to three reference images, and a Qwen-VL CLIP, and produces the conditioning that a KSampler needs to actually run Qwen-Image-Edit. The whole pack is scaffolding around this one idea - getting a 20B multimodal editor's conditioning to play nice in ComfyUI's graph.
What it takes in
Required:
clip- the Qwen-VL CLIP for encoding text and vision tokens.prompt- your edit instruction. Vision tokens for whatever images you attach get inserted automatically, wrapped in ChatML format (<|im_start|>...).system_prompt- optional, wrapped in its own ChatML system block.image1_label/image2_label/image3_label- you can name your images ("Image 1 (target)", "Image 2 (style ref)"), and those labels go into the prompt so Qwen knows which image is which. Underrated input - it's how the model distinguishes "change this" from "match this style."conditioning_strength(0–2) - the master dial for text+vision embeddings. 1.0 is normal, below 1.0 weaker, above 1.0 stronger. V1 applies this as a raw multiplier, which is exactly why V2 exists - more on that in the V2 article.image1/2/3_latent_strength(0–2) - per-image strength on the VAE-encoded reference latents.
Optional:
vae- needed if you use the latent image inputs.image1_vl/image2_vl/image3_vl- for the vision encoder (RGB only, expects the right size).image1_latent/image2_latent/image3_latent- same images (or different ones) re-encoded through the VAE as reference latents. The dual path is the Qwen-Edit design: the VL branch gives semantic control, the latent branch gives appearance control.
Outputs
conditioning- text + vision embeddings with the reference latent metadata attached. This goes to the sampler.latent- the image1 latent in standard format, ready for VAEDecode or any latent node.formatted_prompt- the final ChatML prompt with vision tokens, for debugging. Great for seeing what the model actually received when results are weird.
How it works
Qwen-Image-Edit's input image is dual-encoded: Qwen2.5-VL handles semantic understanding, the VAE encoder handles appearance. This node replicates that split inside ComfyUI - *_vl images feed the vision encoder, *_latent images feed the VAE - and stitches everything into a ChatML-wrapped conditioning. The labels and system prompt become part of the chat template, and the strength dials scale the resulting embeddings.
The one thing to know
V1 multiplies conditioning by strength directly. The pack's docs are blunt that this is the problem: with a system prompt attached, a raw multiply can feel "10× stronger" than intended - the "weight spike." That's why the README recommends Encoder V2 over V1 for real work. V1 is still fine for a simple single-image edit at strength 1.0, but if you find yourself fighting the strength slider, the fix isn't a different value - it's the V2 node.
Install
Pack install, once for all the nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/amir84ferdos/ComfyUI-ArchAi3d-Qwen.git
cd ComfyUI-ArchAi3d-Qwen && pip install -r requirements.txt
Or ComfyUI Manager → "ArchAi3d Qwen". Restart, then it's under ArchAi3d/Qwen. You need the Qwen-Image-Edit checkpoint (GGUF Q4/fp8 on consumer cards) and a Qwen-VL CLIP loader. Images should come pre-sized for the VL encoder - the pack's Image Scale node exists for exactly that.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| clip | CLIP | Qwen-VL CLIP model for encoding text and vision tokens | |
| prompt | STRING | Text prompt (vision tokens inserted automatically in ChatML format) | |
| system_prompt | STRING | Optional system prompt (wrapped in ChatML <|im_start|>system block) | |
| image1_label | STRING | Image 1 | Custom label for Image 1 (e.g., 'Image 1 (target)', 'Image 1 (room)') |
| image2_label | STRING | Image 2 | Custom label for Image 2 (e.g., 'Image 2 (style ref)', 'Image 2 (material)') |
| image3_label | STRING | Image 3 | Custom label for Image 3 (e.g., 'Image 3 (color ref)', 'Image 3 (lighting)') |
| conditioning_strength | FLOAT | 1.000–2 | Global strength for text+vision embeddings (1.0=normal, <1.0=weaker, >1.0=stronger) |
| image1_latent_strength | FLOAT | 1.000–2 | Image1 latent strength (1.0=normal, <1.0=weaker, >1.0=stronger) |
| image2_latent_strength | FLOAT | 1.000–2 | Image2 latent strength (1.0=normal, <1.0=weaker, >1.0=stronger) |
| image3_latent_strength | FLOAT | 1.000–2 | Image3 latent strength (1.0=normal, <1.0=weaker, >1.0=stronger) |
| debug_mode | BOOLEAN | false | Enable console logging (shows strengths, shapes, and formatted prompt) |
| vaeopt | VAE | VAE for encoding reference latents (required if using latent images) | |
| image1_vlopt | IMAGE | Image 1 for vision encoder (RGB only, expects correct size) | |
| image2_vlopt | IMAGE | Image 2 for vision encoder (RGB only, expects correct size) | |
| image3_vlopt | IMAGE | Image 3 for vision encoder (RGB only, expects correct size) | |
| image1_latentopt | IMAGE | Image 1 for reference latent (RGB only, expects correct size) | |
| image2_latentopt | IMAGE | Image 2 for reference latent (RGB only, expects correct size) | |
| image3_latentopt | IMAGE | Image 3 for reference latent (RGB only, expects correct size) |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| conditioning | CONDITIONING | Text+vision embeddings with reference latents metadata attached |
| latent | LATENT | Image1 latent in standard format (for VAEDecode or other latent nodes) |
| formatted_prompt | STRING | Final ChatML-formatted prompt with vision tokens (for debugging) |