Claimed 2026-09-03T01:25Z — dispatched to a fix agent. Taking this. One correction up front, because it changes what the fix should be. **The observation is right; the stated impact is not.** ComfyUI's own `common_ksampler` (`nodes.py`) calls `comfy.sample.fix_empty_latent_channels`, which repeats an **all-zero** latent up to the model's `latent_channels` before sampling. Qwen Image's latent format is `Wan21` (16 channels, `latent_dimensions=3`), and both empty-latent nodes emit `downscale_ratio_spacial: 8` — so the two paths converge. Measured on this box against the installed ComfyUI, not re… read the rest
Qwen Image 2512 Text-to-Image Workflows
Build Qwen Image 2512 text-to-image workflows with QwenImageIntegratedKSampler, separate component loading, lightning LoRAs, and fine-tuned model variants
How to install
- Setup differs for this server — follow the Installation part of the README below.
- Claude Code:
claude mcp add <name> -- <command>. - Claude Desktop / Cursor: add it under
mcpServersin the MCP config file.
npx degit artokun/comfyui-mcp/plugin/skills/qwen-txt2img#main ~/.claude/skills/qwen-txt2imgFor one project only, change the path to .claude/skills/qwen-txt2img. This skill also uses image_qwen_image.json — copying SKILL.md alone won't be enough. See the folder on GitHub.
This one runs on your machine and can reach your files. Read the README below before you connect it.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Show the full text347 lines
Qwen Image 2512 Text-to-Image Workflows
Overview
Qwen Image 2512 is the latest (December 2025) text-to-image model from the Qwen family. It uses a vision-language model (Qwen2.5-VL) as the text encoder and generates high-quality images from natural language prompts. Two workflow approaches:
- QwenImageIntegratedKSampler: All-in-one node (recommended for simplicity)
- Separate component loading: UNETLoader + CLIPLoader + VAELoader + standard KSampler (more flexible)
Models
Standard Components
| Component | Node | Model | Notes |
|---|---|---|---|
| UNET | UNETLoader |
qwen_image_2512_fp8_e4m3fn.safetensors |
FP8, not currently installed — download if needed |
| CLIP | CLIPLoader (type=qwen_image) |
qwen_2.5_vl_7b_fp8_scaled.safetensors |
Shared across all Qwen models, in clip/ |
| VAE | VAELoader |
qwen_image_vae.safetensors |
Qwen-specific VAE (242MB) |
Fine-tuned Variants (Installed)
| Model | Path | Focus |
|---|---|---|
qwenImageEditRemix_v10 |
diffusion_models/qwenImageEditRemix_v10.safetensors |
General-purpose remix |
qwenUltimateRealism_v11 |
UNETLoader path | Product photography, hyper-realistic |
copaxTimeless |
UNETLoader path | Ultra-realistic portraits |
qwnImageEdit_v16Bf16 |
UNETLoader path | Abliterated (uncensored) |
Lightning LoRAs
4-Step Lightning (General Qwen / txt2img)
{
"class_type": "LoraLoaderModelOnly",
"inputs": {
"model": ["<unet_node>", 0],
"lora_name": "Qwen-Image-Lightning-4steps-V1.0.safetensors",
"strength_model": 1.0
}
}
Settings: steps=4, cfg=1.0, sampler=euler, scheduler=simple, denoise=1.0
8-Step Lightning (Higher Quality)
{
"class_type": "LoraLoaderModelOnly",
"inputs": {
"model": ["<unet_node>", 0],
"lora_name": "Qwen-Image-Lightning-8steps-V1.0.safetensors",
"strength_model": 1.0
}
}
Settings: steps=8, cfg=1.0 (or 2.5 for character detail), sampler=euler, scheduler=simple
Sampler Settings
| Preset | Steps | CFG | Sampler | Scheduler | Denoise | LoRA | Notes |
|---|---|---|---|---|---|---|---|
| Lightning 4-step | 4 | 1.0 | euler | simple | 1.0 | Lightning-4steps | Fastest, good quality |
| Lightning 8-step | 8 | 1.0 | euler | simple | 1.0 | Lightning-8steps | Better detail |
| Lightning character | 8 | 2.5 | euler | simple | 1.0 | Lightning-8steps | Best for portraits |
| Standard | 50 | 4.0 | euler | simple | 1.0 | none | Official ComfyUI |
| Golden quality | 50 | 4.5 | euler | simple | 1.0 | none | Community best |
| Character composition | 30 | 4.0 | euler_ancestral | beta | 1.0 | none | Multi-character scenes |
| CopaxTimeless | 30 | 4.0 | res_multistep | sgm_uniform | 1.0 | none | Ultra-realistic |
| UltimateRealism | 30 | 7.5 | euler | simple | 1.0 | none | Product photography |
ModelSamplingAuraFlow
For standard (non-lightning) presets, apply flow matching shift:
{
"class_type": "ModelSamplingAuraFlow",
"inputs": { "model": ["<unet_or_lora>", 0], "shift": 3.1 }
}
Shift=3.1 is the standard value for Qwen Image. Not needed with lightning LoRA (baked into the distillation).
Resolutions
Qwen operates at ~1.6 megapixels natively:
| Aspect | Resolution | Use Case |
|---|---|---|
| Square | 1328x1328 | General |
| Portrait 3:4 | 1104x1472 | Portraits |
| Portrait 2:3 | 1056x1584 | |
| Portrait 9:16 | 928x1664 | Phone format |
| Landscape 4:3 | 1472x1104 | Landscape scenes |
| Landscape 3:2 | 1584x1056 | |
| Landscape 16:9 | 1664x928 | Widescreen |
| Ultra portrait | 1536x2048 | Tall format |
| Video-ready | 832x480 | For WAN 2.2 FLF pipeline |
Approach 1: QwenImageIntegratedKSampler (All-in-One)
The QwenImageIntegratedKSampler custom node handles model patching, conditioning, sampling, and output in a single node. Simplest workflow: 4 nodes for model loading + 1 integrated sampler + 1 save.
Node Inputs
Required:
- model: MODEL (from UNETLoader)
- clip: CLIP (from CLIPLoader, type=qwen_image)
- vae: VAE
- positive_prompt: STRING
- negative_prompt: STRING
- generation_mode: "文生图 text-to-image" or "图生图 image-to-image"
- batch_size: INT (default 1)
- width: INT (default 0, step 8)
- height: INT (default 0, step 8)
- seed: INT
- steps: INT (default 4)
- cfg: FLOAT (default 1)
- sampler_name: euler, dpmpp_2m, etc.
- scheduler: simple, sgm_uniform, beta, etc.
- denoise: FLOAT (default 1)
Optional:
- image1-5: IMAGE (reference images for i2i or multi-ref)
- latent: LATENT
- controlnet_data: CONTROL_NET_DATA
- auraflow_shift: FLOAT (default 3)
- cfg_norm_strength: FLOAT (default 1)
Outputs:
[0] IMAGE — generated image
[1] LATENT — output latent (optional)
[2] IMAGE — scaled input image (for i2i)
Complete Workflow: Integrated Sampler (Lightning 4-Step)
{
"1": { "class_type": "UNETLoader", "inputs": { "unet_name": "qwenImageEditRemix_v10.safetensors", "weight_dtype": "default" }},
"2": { "class_type": "LoraLoaderModelOnly", "inputs": { "model": ["1", 0], "lora_name": "Qwen-Image-Lightning-4steps-V1.0.safetensors", "strength_model": 1.0 }},
"3": { "class_type": "CLIPLoader", "inputs": { "clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors", "type": "qwen_image" }},
"4": { "class_type": "VAELoader", "inputs": { "vae_name": "qwen_image_vae.safetensors" }},
"5": { "class_type": "QwenImageIntegratedKSampler", "inputs": {
"model": ["2", 0],
"clip": ["3", 0],
"vae": ["4", 0],
"positive_prompt": "<detailed natural language prompt>",
"negative_prompt": "",
"generation_mode": "文生图 text-to-image",
"batch_size": 1,
"width": 1024,
"height": 1344,
"seed": 42,
"steps": 4,
"cfg": 1,
"sampler_name": "euler",
"scheduler": "simple",
"denoise": 1,
"auraflow_shift": 3,
"cfg_norm_strength": 1
}},
"6": { "class_type": "SaveImage", "inputs": { "images": ["5", 0], "filename_prefix": "qwen_t2i" }}
}
Approach 2: Separate Component Loading (Standard Pipeline)
More flexible, since it allows inserting additional processing nodes between stages.
Pipeline Flow
UNETLoader → [LoraLoaderModelOnly] → [ModelSamplingAuraFlow (shift=3.1)] → MODEL
CLIPLoader (qwen_image) → CLIP
VAELoader → VAE
CLIPTextEncode (positive) → CONDITIONING
ConditioningZeroOut → negative CONDITIONING
EmptySD3LatentImage (1024x1344) → LATENT
KSampler → VAEDecode → SaveImage
Latent node: use EmptySD3LatentImage, matching the official Comfy-Org
image_qwen_image template. Qwen Image’s latent format is Wan21, so its latent is
16-channel; EmptyLatentImage emits 4. A bare EmptyLatentImage → KSampler still renders,
because ComfyUI’s fix_empty_latent_channels (comfy/sample.py, called by every sampler
node) repeats an all-zero latent up to the model’s channel count. But that rescue is
gated on torch.count_nonzero(latent) == 0, so it stops applying the moment a node inserted
here writes into the latent — which is exactly what this approach is for. Start 16-channel
and the question never arises.
Complete Workflow: Separate Loading (Lightning 4-Step)
{
"1": { "class_type": "UNETLoader", "inputs": { "unet_name": "qwenImageEditRemix_v10.safetensors", "weight_dtype": "default" }},
"2": { "class_type": "LoraLoaderModelOnly", "inputs": { "model": ["1", 0], "lora_name": "Qwen-Image-Lightning-4steps-V1.0.safetensors", "strength_model": 1.0 }},
"3": { "class_type": "CLIPLoader", "inputs": { "clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors", "type": "qwen_image" }},
"4": { "class_type": "VAELoader", "inputs": { "vae_name": "qwen_image_vae.safetensors" }},
"5": { "class_type": "CLIPTextEncode", "inputs": { "clip": ["3", 0], "text": "<detailed natural language prompt>" }},
"6": { "class_type": "ConditioningZeroOut", "inputs": { "conditioning": ["5", 0] }},
"7": { "class_type": "EmptySD3LatentImage", "inputs": { "width": 1024, "height": 1344, "batch_size": 1 }},
"8": { "class_type": "KSampler", "inputs": {
"model": ["2", 0],
"positive": ["5", 0],
"negative": ["6", 0],
"latent_image": ["7", 0],
"seed": 42, "steps": 4, "cfg": 1, "sampler_name": "euler", "scheduler": "simple", "denoise": 1
}},
"9": { "class_type": "VAEDecode", "inputs": { "samples": ["8", 0], "vae": ["4", 0] }},
"10": { "class_type": "SaveImage", "inputs": { "images": ["9", 0], "filename_prefix": "qwen_t2i" }}
}
Complete Workflow: Standard Quality (50-Step)
{
"1": { "class_type": "UNETLoader", "inputs": { "unet_name": "qwenImageEditRemix_v10.safetensors", "weight_dtype": "default" }},
"2": { "class_type": "ModelSamplingAuraFlow", "inputs": { "model": ["1", 0], "shift": 3.1 }},
"3": { "class_type": "CLIPLoader", "inputs": { "clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors", "type": "qwen_image" }},
"4": { "class_type": "VAELoader", "inputs": { "vae_name": "qwen_image_vae.safetensors" }},
"5": { "class_type": "CLIPTextEncode", "inputs": { "clip": ["3", 0], "text": "<detailed natural language prompt>" }},
"6": { "class_type": "ConditioningZeroOut", "inputs": { "conditioning": ["5", 0] }},
"7": { "class_type": "EmptySD3LatentImage", "inputs": { "width": 1328, "height": 1328, "batch_size": 1 }},
"8": { "class_type": "KSampler", "inputs": {
"model": ["2", 0],
"positive": ["5", 0],
"negative": ["6", 0],
"latent_image": ["7", 0],
"seed": 42, "steps": 50, "cfg": 4, "sampler_name": "euler", "scheduler": "simple", "denoise": 1
}},
"9": { "class_type": "VAEDecode", "inputs": { "samples": ["8", 0], "vae": ["4", 0] }},
"10": { "class_type": "SaveImage", "inputs": { "images": ["9", 0], "filename_prefix": "qwen_t2i_hq" }}
}
Negative Conditioning
Always use ConditioningZeroOut for Qwen txt2img:
{
"class_type": "ConditioningZeroOut",
"inputs": { "conditioning": ["<positive_cond>", 0] }
}
Or use an empty string in CLIPTextEncode, but ZeroOut is more explicit and reliable.
QwenImageDiffsynthControlnet
For ControlNet support with Qwen models. Patches the model with a DiffSynth control signal:
Required Inputs:
- model: MODEL
- model_patch: MODEL_PATCH (from DiffSynth ControlNet loader)
- vae: VAE
- image: IMAGE (control image)
- strength: FLOAT (default 1.0)
Optional:
- mask: MASK
Outputs:
[0] MODEL (patched)
DiffSynth ControlNets support: canny, depth, inpaint only (NOT pose).
Concept/Style LoRAs (Installed)
Located in loras/Qwen/:
style/: Figure makers, reality transform, panel painterconcept/: Various concept LoRAsposes/: Pose-specific LoRAscharacter/: Character enhancementanime/: Anime style LoRAstool/: Utility LoRAs (anything2real, gaussian splash)equirectangular projection/: 360 panorama LoRA
Apply with LoraLoaderModelOnly:
{
"class_type": "LoraLoaderModelOnly",
"inputs": {
"model": ["<unet_or_lightning_lora>", 0],
"lora_name": "Qwen\\concept\\hinaQwenImageAsianMixLora_v2.safetensors",
"strength_model": 0.8
}
}
Prompt Style
Natural language, 1 to 3 sentences. Be descriptive:
Good: "Professional portrait of an Asian woman in her late 20s, wearing a cream linen blazer at a Tokyo rooftop café during golden hour, holding a matcha latte, editorial fashion photography, shot on Sony A7III 85mm f/1.4"
Bad: "1girl, cafe, blazer, matcha"
Tips:
- Put text to render in quotes within the prompt
- "photograph" works better than "photorealistic"
- Negative prompts: use NLP-style descriptions, not keyword spam (or use ZeroOut)
VRAM Considerations
| Config | VRAM | Notes |
|---|---|---|
| FP8 UNET + fp8 CLIP + VAE | ~17-18GB | Fits comfortably on RTX 4090 |
| bf16 UNET (edit model) | ~10GB UNET + 7GB CLIP | Also fits well |
- Always
clear_vrambefore switching to Qwen from another model family - Lightning 4-step takes ~3-5s per image
Tips
- QwenImageIntegratedKSampler is the simplest approach for basic txt2img. One node handles everything
- For LoRA stacking or ControlNet, use the separate component pipeline instead
- The integrated sampler's
auraflow_shiftdefaults to 3 (close to the recommended 3.1). Adjust only if needed - For video pipeline output (feeding into WAN FLF), set resolution to 832x480
- CopaxTimeless pick: res_multistep + sgm_uniform at CFG 4.0 for ultra-realistic results
- Multiple concept LoRAs can stack. Reduce individual strength to 0.5-0.7 when combining
Sources
- Official: Comfy-Org workflow template
image_qwen_image.json— https://github.com/Comfy-Org/workflow_templates/blob/main/templates/image_qwen_image.json - Empirical: sampler values, wiring, and prompt notes from working graphs in
packs/and observed renders; not a vendor prompting guide.
| 1 | |
| 2 | name qwen-txt2img |
| 3 | description Build Qwen Image 2512 text-to-image workflows with QwenImageIntegratedKSampler, separate component loading, lightning LoRAs, and fine-tuned model variants |
| 4 | globs |
| 5 | - "**/*.json" |
| 6 | |
| 7 | |
| 8 | # Qwen Image 2512 Text-to-Image Workflows |
| 9 | |
| 10 | ## Overview |
| 11 | |
| 12 | Qwen Image 2512 is the latest (December 2025) text-to-image model from the Qwen family. It uses a vision-language model (Qwen2.5-VL) as the text encoder and generates high-quality images from natural language prompts. Two workflow approaches: |
| 13 | |
| 14 | **QwenImageIntegratedKSampler**: All-in-one node (recommended for simplicity) |
| 15 | **Separate component loading**: UNETLoader + CLIPLoader + VAELoader + standard KSampler (more flexible) |
| 16 | |
| 17 | ## Models |
| 18 | |
| 19 | ### Standard Components |
| 20 | |
| 21 | | Component | Node | Model | Notes | |
| 22 | |-----------|------|-------|-------| |
| 23 | | **UNET** | `UNETLoader` | `qwen_image_2512_fp8_e4m3fn.safetensors` | FP8, not currently installed — download if needed | |
| 24 | | **CLIP** | `CLIPLoader` (type=`qwen_image`) | `qwen_2.5_vl_7b_fp8_scaled.safetensors` | Shared across all Qwen models, in clip/ | |
| 25 | | **VAE** | `VAELoader` | `qwen_image_vae.safetensors` | Qwen-specific VAE (242MB) | |
| 26 | |
| 27 | ### Fine-tuned Variants (Installed) |
| 28 | |
| 29 | | Model | Path | Focus | |
| 30 | |-------|------|-------| |
| 31 | | `qwenImageEditRemix_v10` | `diffusion_models/qwenImageEditRemix_v10.safetensors` | General-purpose remix | |
| 32 | | `qwenUltimateRealism_v11` | UNETLoader path | Product photography, hyper-realistic | |
| 33 | | `copaxTimeless` | UNETLoader path | Ultra-realistic portraits | |
| 34 | | `qwnImageEdit_v16Bf16` | UNETLoader path | Abliterated (uncensored) | |
| 35 | |
| 36 | ## Lightning LoRAs |
| 37 | |
| 38 | ### 4-Step Lightning (General Qwen / txt2img) |
| 39 | |
| 40 | |
| 41 | { |
| 42 | "class_type": "LoraLoaderModelOnly", |
| 43 | "inputs": { |
| 44 | "model": ["<unet_node>", 0], |
| 45 | "lora_name": "Qwen-Image-Lightning-4steps-V1.0.safetensors", |
| 46 | "strength_model": 1.0 |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | |
| 51 | **Settings**: steps=4, cfg=1.0, sampler=euler, scheduler=simple, denoise=1.0 |
| 52 | |
| 53 | ### 8-Step Lightning (Higher Quality) |
| 54 | |
| 55 | |
| 56 | { |
| 57 | "class_type": "LoraLoaderModelOnly", |
| 58 | "inputs": { |
| 59 | "model": ["<unet_node>", 0], |
| 60 | "lora_name": "Qwen-Image-Lightning-8steps-V1.0.safetensors", |
| 61 | "strength_model": 1.0 |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | |
| 66 | **Settings**: steps=8, cfg=1.0 (or 2.5 for character detail), sampler=euler, scheduler=simple |
| 67 | |
| 68 | ## Sampler Settings |
| 69 | |
| 70 | | Preset | Steps | CFG | Sampler | Scheduler | Denoise | LoRA | Notes | |
| 71 | |--------|-------|-----|---------|-----------|---------|------|-------| |
| 72 | | **Lightning 4-step** | 4 | 1.0 | euler | simple | 1.0 | Lightning-4steps | Fastest, good quality | |
| 73 | | **Lightning 8-step** | 8 | 1.0 | euler | simple | 1.0 | Lightning-8steps | Better detail | |
| 74 | | **Lightning character** | 8 | 2.5 | euler | simple | 1.0 | Lightning-8steps | Best for portraits | |
| 75 | | **Standard** | 50 | 4.0 | euler | simple | 1.0 | none | Official ComfyUI | |
| 76 | | **Golden quality** | 50 | 4.5 | euler | simple | 1.0 | none | Community best | |
| 77 | | **Character composition** | 30 | 4.0 | euler_ancestral | beta | 1.0 | none | Multi-character scenes | |
| 78 | | **CopaxTimeless** | 30 | 4.0 | res_multistep | sgm_uniform | 1.0 | none | Ultra-realistic | |
| 79 | | **UltimateRealism** | 30 | 7.5 | euler | simple | 1.0 | none | Product photography | |
| 80 | |
| 81 | ### ModelSamplingAuraFlow |
| 82 | |
| 83 | For standard (non-lightning) presets, apply flow matching shift: |
| 84 | |
| 85 | |
| 86 | { |
| 87 | "class_type": "ModelSamplingAuraFlow", |
| 88 | "inputs": { "model": ["<unet_or_lora>", 0], "shift": 3.1 } |
| 89 | } |
| 90 | |
| 91 | |
| 92 | **Shift=3.1** is the standard value for Qwen Image. Not needed with lightning LoRA (baked into the distillation). |
| 93 | |
| 94 | ## Resolutions |
| 95 | |
| 96 | Qwen operates at ~1.6 megapixels natively: |
| 97 | |
| 98 | | Aspect | Resolution | Use Case | |
| 99 | |--------|-----------|----------| |
| 100 | | Square | 1328x1328 | General | |
| 101 | | Portrait 3:4 | 1104x1472 | Portraits | |
| 102 | | Portrait 2:3 | 1056x1584 | | |
| 103 | | Portrait 9:16 | 928x1664 | Phone format | |
| 104 | | Landscape 4:3 | 1472x1104 | Landscape scenes | |
| 105 | | Landscape 3:2 | 1584x1056 | | |
| 106 | | Landscape 16:9 | 1664x928 | Widescreen | |
| 107 | | Ultra portrait | 1536x2048 | Tall format | |
| 108 | | Video-ready | 832x480 | For WAN 2.2 FLF pipeline | |
| 109 | |
| 110 | ## Approach 1: QwenImageIntegratedKSampler (All-in-One) |
| 111 | |
| 112 | The `QwenImageIntegratedKSampler` custom node handles model patching, conditioning, sampling, and output in a single node. Simplest workflow: 4 nodes for model loading + 1 integrated sampler + 1 save. |
| 113 | |
| 114 | ### Node Inputs |
| 115 | |
| 116 | |
| 117 | Required: |
| 118 | - model: MODEL (from UNETLoader) |
| 119 | - clip: CLIP (from CLIPLoader, type=qwen_image) |
| 120 | - vae: VAE |
| 121 | - positive_prompt: STRING |
| 122 | - negative_prompt: STRING |
| 123 | - generation_mode: "文生图 text-to-image" or "图生图 image-to-image" |
| 124 | - batch_size: INT (default 1) |
| 125 | - width: INT (default 0, step 8) |
| 126 | - height: INT (default 0, step 8) |
| 127 | - seed: INT |
| 128 | - steps: INT (default 4) |
| 129 | - cfg: FLOAT (default 1) |
| 130 | - sampler_name: euler, dpmpp_2m, etc. |
| 131 | - scheduler: simple, sgm_uniform, beta, etc. |
| 132 | - denoise: FLOAT (default 1) |
| 133 | |
| 134 | Optional: |
| 135 | - image1-5: IMAGE (reference images for i2i or multi-ref) |
| 136 | - latent: LATENT |
| 137 | - controlnet_data: CONTROL_NET_DATA |
| 138 | - auraflow_shift: FLOAT (default 3) |
| 139 | - cfg_norm_strength: FLOAT (default 1) |
| 140 | |
| 141 | Outputs: |
| 142 | [0] IMAGE — generated image |
| 143 | [1] LATENT — output latent (optional) |
| 144 | [2] IMAGE — scaled input image (for i2i) |
| 145 | |
| 146 | |
| 147 | ### Complete Workflow: Integrated Sampler (Lightning 4-Step) |
| 148 | |
| 149 | |
| 150 | { |
| 151 | "1": { "class_type": "UNETLoader", "inputs": { "unet_name": "qwenImageEditRemix_v10.safetensors", "weight_dtype": "default" }}, |
| 152 | "2": { "class_type": "LoraLoaderModelOnly", "inputs": { "model": ["1", 0], "lora_name": "Qwen-Image-Lightning-4steps-V1.0.safetensors", "strength_model": 1.0 }}, |
| 153 | "3": { "class_type": "CLIPLoader", "inputs": { "clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors", "type": "qwen_image" }}, |
| 154 | "4": { "class_type": "VAELoader", "inputs": { "vae_name": "qwen_image_vae.safetensors" }}, |
| 155 | "5": { "class_type": "QwenImageIntegratedKSampler", "inputs": { |
| 156 | "model": ["2", 0], |
| 157 | "clip": ["3", 0], |
| 158 | "vae": ["4", 0], |
| 159 | "positive_prompt": "<detailed natural language prompt>", |
| 160 | "negative_prompt": "", |
| 161 | "generation_mode": "文生图 text-to-image", |
| 162 | "batch_size": 1, |
| 163 | "width": 1024, |
| 164 | "height": 1344, |
| 165 | "seed": 42, |
| 166 | "steps": 4, |
| 167 | "cfg": 1, |
| 168 | "sampler_name": "euler", |
| 169 | "scheduler": "simple", |
| 170 | "denoise": 1, |
| 171 | "auraflow_shift": 3, |
| 172 | "cfg_norm_strength": 1 |
| 173 | }}, |
| 174 | "6": { "class_type": "SaveImage", "inputs": { "images": ["5", 0], "filename_prefix": "qwen_t2i" }} |
| 175 | } |
| 176 | |
| 177 | |
| 178 | ## Approach 2: Separate Component Loading (Standard Pipeline) |
| 179 | |
| 180 | More flexible, since it allows inserting additional processing nodes between stages. |
| 181 | |
| 182 | ### Pipeline Flow |
| 183 | |
| 184 | |
| 185 | UNETLoader → [LoraLoaderModelOnly] → [ModelSamplingAuraFlow (shift=3.1)] → MODEL |
| 186 | CLIPLoader (qwen_image) → CLIP |
| 187 | VAELoader → VAE |
| 188 | |
| 189 | CLIPTextEncode (positive) → CONDITIONING |
| 190 | ConditioningZeroOut → negative CONDITIONING |
| 191 | |
| 192 | EmptySD3LatentImage (1024x1344) → LATENT |
| 193 | |
| 194 | KSampler → VAEDecode → SaveImage |
| 195 | |
| 196 | |
| 197 | **Latent node:** use `EmptySD3LatentImage`, matching the official Comfy-Org |
| 198 | `image_qwen_image` template. Qwen Image’s latent format is `Wan21`, so its latent is |
| 199 | 16-channel; `EmptyLatentImage` emits 4. A bare `EmptyLatentImage → KSampler` still renders, |
| 200 | because ComfyUI’s `fix_empty_latent_channels` (`comfy/sample.py`, called by every sampler |
| 201 | node) repeats an **all-zero** latent up to the model’s channel count. But that rescue is |
| 202 | gated on `torch.count_nonzero(latent) == 0`, so it stops applying the moment a node inserted |
| 203 | here writes into the latent — which is exactly what this approach is for. Start 16-channel |
| 204 | and the question never arises. |
| 205 | |
| 206 | ### Complete Workflow: Separate Loading (Lightning 4-Step) |
| 207 | |
| 208 | |
| 209 | { |
| 210 | "1": { "class_type": "UNETLoader", "inputs": { "unet_name": "qwenImageEditRemix_v10.safetensors", "weight_dtype": "default" }}, |
| 211 | "2": { "class_type": "LoraLoaderModelOnly", "inputs": { "model": ["1", 0], "lora_name": "Qwen-Image-Lightning-4steps-V1.0.safetensors", "strength_model": 1.0 }}, |
| 212 | "3": { "class_type": "CLIPLoader", "inputs": { "clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors", "type": "qwen_image" }}, |
| 213 | "4": { "class_type": "VAELoader", "inputs": { "vae_name": "qwen_image_vae.safetensors" }}, |
| 214 | "5": { "class_type": "CLIPTextEncode", "inputs": { "clip": ["3", 0], "text": "<detailed natural language prompt>" }}, |
| 215 | "6": { "class_type": "ConditioningZeroOut", "inputs": { "conditioning": ["5", 0] }}, |
| 216 | "7": { "class_type": "EmptySD3LatentImage", "inputs": { "width": 1024, "height": 1344, "batch_size": 1 }}, |
| 217 | "8": { "class_type": "KSampler", "inputs": { |
| 218 | "model": ["2", 0], |
| 219 | "positive": ["5", 0], |
| 220 | "negative": ["6", 0], |
| 221 | "latent_image": ["7", 0], |
| 222 | "seed": 42, "steps": 4, "cfg": 1, "sampler_name": "euler", "scheduler": "simple", "denoise": 1 |
| 223 | }}, |
| 224 | "9": { "class_type": "VAEDecode", "inputs": { "samples": ["8", 0], "vae": ["4", 0] }}, |
| 225 | "10": { "class_type": "SaveImage", "inputs": { "images": ["9", 0], "filename_prefix": "qwen_t2i" }} |
| 226 | } |
| 227 | |
| 228 | |
| 229 | ### Complete Workflow: Standard Quality (50-Step) |
| 230 | |
| 231 | |
| 232 | { |
| 233 | "1": { "class_type": "UNETLoader", "inputs": { "unet_name": "qwenImageEditRemix_v10.safetensors", "weight_dtype": "default" }}, |
| 234 | "2": { "class_type": "ModelSamplingAuraFlow", "inputs": { "model": ["1", 0], "shift": 3.1 }}, |
| 235 | "3": { "class_type": "CLIPLoader", "inputs": { "clip_name": "qwen_2.5_vl_7b_fp8_scaled.safetensors", "type": "qwen_image" }}, |
| 236 | "4": { "class_type": "VAELoader", "inputs": { "vae_name": "qwen_image_vae.safetensors" }}, |
| 237 | "5": { "class_type": "CLIPTextEncode", "inputs": { "clip": ["3", 0], "text": "<detailed natural language prompt>" }}, |
| 238 | "6": { "class_type": "ConditioningZeroOut", "inputs": { "conditioning": ["5", 0] }}, |
| 239 | "7": { "class_type": "EmptySD3LatentImage", "inputs": { "width": 1328, "height": 1328, "batch_size": 1 }}, |
| 240 | "8": { "class_type": "KSampler", "inputs": { |
| 241 | "model": ["2", 0], |
| 242 | "positive": ["5", 0], |
| 243 | "negative": ["6", 0], |
| 244 | "latent_image": ["7", 0], |
| 245 | "seed": 42, "steps": 50, "cfg": 4, "sampler_name": "euler", "scheduler": "simple", "denoise": 1 |
| 246 | }}, |
| 247 | "9": { "class_type": "VAEDecode", "inputs": { "samples": ["8", 0], "vae": ["4", 0] }}, |
| 248 | "10": { "class_type": "SaveImage", "inputs": { "images": ["9", 0], "filename_prefix": "qwen_t2i_hq" }} |
| 249 | } |
| 250 | |
| 251 | |
| 252 | ## Negative Conditioning |
| 253 | |
| 254 | Always use `ConditioningZeroOut` for Qwen txt2img: |
| 255 | |
| 256 | |
| 257 | { |
| 258 | "class_type": "ConditioningZeroOut", |
| 259 | "inputs": { "conditioning": ["<positive_cond>", 0] } |
| 260 | } |
| 261 | |
| 262 | |
| 263 | Or use an empty string in `CLIPTextEncode`, but ZeroOut is more explicit and reliable. |
| 264 | |
| 265 | ## QwenImageDiffsynthControlnet |
| 266 | |
| 267 | For ControlNet support with Qwen models. Patches the model with a DiffSynth control signal: |
| 268 | |
| 269 | |
| 270 | Required Inputs: |
| 271 | - model: MODEL |
| 272 | - model_patch: MODEL_PATCH (from DiffSynth ControlNet loader) |
| 273 | - vae: VAE |
| 274 | - image: IMAGE (control image) |
| 275 | - strength: FLOAT (default 1.0) |
| 276 | |
| 277 | Optional: |
| 278 | - mask: MASK |
| 279 | |
| 280 | Outputs: |
| 281 | [0] MODEL (patched) |
| 282 | |
| 283 | |
| 284 | **DiffSynth ControlNets support**: canny, depth, inpaint only (NOT pose). |
| 285 | |
| 286 | ## Concept/Style LoRAs (Installed) |
| 287 | |
| 288 | Located in `loras/Qwen/`: |
| 289 | `style/`: Figure makers, reality transform, panel painter |
| 290 | `concept/`: Various concept LoRAs |
| 291 | `poses/`: Pose-specific LoRAs |
| 292 | `character/`: Character enhancement |
| 293 | `anime/`: Anime style LoRAs |
| 294 | `tool/`: Utility LoRAs (anything2real, gaussian splash) |
| 295 | `equirectangular projection/`: 360 panorama LoRA |
| 296 | |
| 297 | Apply with `LoraLoaderModelOnly`: |
| 298 | |
| 299 | |
| 300 | { |
| 301 | "class_type": "LoraLoaderModelOnly", |
| 302 | "inputs": { |
| 303 | "model": ["<unet_or_lightning_lora>", 0], |
| 304 | "lora_name": "Qwen\\concept\\hinaQwenImageAsianMixLora_v2.safetensors", |
| 305 | "strength_model": 0.8 |
| 306 | } |
| 307 | } |
| 308 | |
| 309 | |
| 310 | ## Prompt Style |
| 311 | |
| 312 | Natural language, 1 to 3 sentences. Be descriptive: |
| 313 | |
| 314 | |
| 315 | Good: "Professional portrait of an Asian woman in her late 20s, wearing a cream linen blazer at a Tokyo rooftop café during golden hour, holding a matcha latte, editorial fashion photography, shot on Sony A7III 85mm f/1.4" |
| 316 | Bad: "1girl, cafe, blazer, matcha" |
| 317 | |
| 318 | |
| 319 | Tips: |
| 320 | Put text to render in quotes within the prompt |
| 321 | "photograph" works better than "photorealistic" |
| 322 | Negative prompts: use NLP-style descriptions, not keyword spam (or use ZeroOut) |
| 323 | |
| 324 | ## VRAM Considerations |
| 325 | |
| 326 | | Config | VRAM | Notes | |
| 327 | |--------|------|-------| |
| 328 | | FP8 UNET + fp8 CLIP + VAE | ~17-18GB | Fits comfortably on RTX 4090 | |
| 329 | | bf16 UNET (edit model) | ~10GB UNET + 7GB CLIP | Also fits well | |
| 330 | |
| 331 | **Always `clear_vram`** before switching to Qwen from another model family |
| 332 | Lightning 4-step takes ~3-5s per image |
| 333 | |
| 334 | ## Tips |
| 335 | |
| 336 | **QwenImageIntegratedKSampler** is the simplest approach for basic txt2img. One node handles everything |
| 337 | For **LoRA stacking** or **ControlNet**, use the separate component pipeline instead |
| 338 | The integrated sampler's `auraflow_shift` defaults to 3 (close to the recommended 3.1). Adjust only if needed |
| 339 | For **video pipeline** output (feeding into WAN FLF), set resolution to 832x480 |
| 340 | **CopaxTimeless pick**: res_multistep + sgm_uniform at CFG 4.0 for ultra-realistic results |
| 341 | Multiple concept LoRAs can stack. Reduce individual strength to 0.5-0.7 when combining |
| 342 | |
| 343 | ## Sources |
| 344 | |
| 345 | **Official:** Comfy-Org workflow template `image_qwen_image.json` — https://github.com/Comfy-Org/workflow_templates/blob/main/templates/image_qwen_image.json |
| 346 | **Empirical:** sampler values, wiring, and prompt notes from working graphs in `packs/` and observed renders; not a vendor prompting guide. |
| 347 |
Discussion
From GitHub
2 comments on 1 threadFixed on `main` in cfa3416 (PR #2767). **What shipped:** the 3 `EmptyLatentImage` sites in `plugin/skills/qwen-txt2img/SKILL.md` (Approach 2 pipeline diagram + both separate-component examples) are now `EmptySD3LatentImage`, matching the official Comfy-Org `image_qwen_image` template — which is now cited under `## Sources` **Official:**, where the entry previously read `none found`. **Your second request was deliberately not implemented,** and the reason matters more than the swap. There is no wrong channel/layout contract to test for. ComfyUI's `common_ksampler` calls `comfy.sample.fix_empty_… read the rest