Nodes/ComfyUI-GGUF-Loader/Qwen-Image ControlNet Loader ⚡
ComfyUI Node

Qwen-Image ControlNet Loader ⚡

One loader for three Qwen-Image ControlNet formats — it figures out which you have

By ChrisColeTech·Created about a month ago·Updated 3 days ago· 10
Qwen-Image ControlNet Loader ⚡
    • qwen_control
    control_name

    The annoying thing about Qwen-Image ControlNets is that they're not one thing. There's the InstantX/Union checkpoint, the Qwen-Image-Fun ControlNet, and the DiffSynth canny/depth/inpaint patches - three formats that attach to the model through two completely different ComfyUI mechanisms. Some workflows make you know which one you downloaded and pick the matching loader. This node takes a single control_name dropdown, figures out which mechanism the file needs, and does the right thing. The source calls itself "a dispatcher, not a reimplementation," and that's exactly right.

    The two mechanisms it has to juggle

    • DiffSynth patches (canny/depth/inpaint - files like qwen_image_canny_diffsynth_controlnet.safetensors) are a MODEL_PATCH. They attach to the MODEL itself via DiffSynthCnetPatch. The loader detects these by checking for the one signature that's unique to that format: controlnet_blocks.0.y_rms.weight.
    • InstantX/Union and Qwen-Image-Fun are both real ControlNet objects. They attach to CONDITIONING the way a classic ControlNet does, via comfy.controlnet.load_controlnet_state_dict(). Fun lands here too - despite the name, it's a genuine ControlNet architecture, and comfy's own dispatcher already recognizes its signature internally. This loader doesn't reimplement any of that; it falls through to core.

    So the detection is a single signature check plus a fallthrough - simple, and robust because it leans on ComfyUI core's own code rather than reimplementing detection for each format.

    The one input, one output

    • control_name - picked from models/model_patches or models/controlnet (the node resolves both folders, so drop your file in whichever one you keep ControlNets in).
    • qwen_control (QWEN_IMAGE_CONTROL) - this is a wrapper type tagging which attachment point the loaded checkpoint needs. It exists because of the two mechanisms: the node tells the downstream img2img node which socket to use, so you never have to know.

    Wire qwen_control into Qwen-Image img2img's qwen_control input. The img2img node routes to whichever attachment the checkpoint needs - DiffSynthCnetPatch on a cloned MODEL for patches, or the standard set_cond_hint() conditioning path for InstantX/Union/Fun.

    Installing it

    Part of the ComfyUI-GGUF-Loader pack under 🤖 CCTech/Qwen-Image. ComfyUI Manager → search "ComfyUI-GGUF-Loader" → install → restart, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/ChrisColeTech/ComfyUI-GGUF-Loader
    cd ComfyUI-GGUF-Loader
    pip install -r requirements.txt
    

    Common issues

    The main practical gotcha is preprocessing, which no loader can solve for you: the DiffSynth canny, depth, and inpaint patches each want a different control map, and the file itself doesn't say which preprocessor it needs. That's why Qwen-Image img2img has a control_mode input - manual (you connect control_image yourself), auto_canny, or auto_depth. Pick the mode that matches the checkpoint you loaded. If a canny patch gets a depth map, you'll get edges interpreted as depth, and the output will look wrong in a way that's hard to untangle. And remember: qwen_control with nothing usable to attach raises immediately, but a control_image connected with no qwen_control loaded is just ignored with a warning - so a "silently not controlling anything" workflow is usually the second case.

    Category🤖 CCTech/Qwen-Image

    Inputs (1)

    NameTypeDefaultDescription
    control_nameCOMBOAn InstantX/Union or Fun ControlNet checkpoint, or a DiffSynth canny/depth/inpaint patch, from models/model_patches or models/controlnet.

    Outputs (1)

    NameTypeDescription
    qwen_controlQWEN_IMAGE_CONTROL