ZImage SDNQ Control Loader
Loading Z-Image with its Fun ControlNet Union, without fighting diffusers
- pipeline
ZImageSDNQControlPipelineLoader is the bigger sibling of the base loader. It loads the same Z-Image model, but instead of the plain transformer it loads the transformer plus the Fun ControlNet Union weights from Alibaba-PAI - the single control model that handles Canny, Depth, Pose, HED, MLSD, inpainting, and Tile modes. The output is a ZIMAGE_CONTROL_PIPELINE that only the control-family samplers (ZImageSDNQSamplerControl, ZImageSDNQSamplerInpaint, ZImageSDNQSamplerTileUpscale) consume. If your workflow is about structure, inpainting, or upscaling, this is the loader you want, not the base one.
Everything from the base loader applies here - same model_source, precision, device, dtype, quantized_matmul, trust_remote_code, local_files_only, low_cpu_mem_usage, and the model_source_custom override. Read that article for the install story; this one adds three control-specific knobs.
The control-specific inputs
- control_weights_path - the dropdown of
.safetensorsfiles found undermodels/controlnet/. This is where you put the Fun ControlNet Union weights (v2.1 is the current sweet spot - it fixed a 2.0 bug and runs ~35% faster). Defaults to<manual>, meaning you're expected to pick or type a path. - control_config -
auto(default),2.1-lite,2.1,2.0,1.0, orcustom. This isn't a model choice, it's a geometry choice: how the control branches are wired into the transformer and how many channels the control input has. Version 1.0 uses 16 channels and six injection points; 2.0 and 2.1 use 33 channels across fifteen layers, with 2.1 fixing how control noise feeds the refiner.2.1-liteis the same architecture with only three injection points - lighter and faster, for when you just need the gist of the control.autoreads your weights file and infers the config from its layer layout, which is the right default. You only reach forcustom(pluscontrol_config_path) when you're rolling your own geometry. - control_weights_path_custom - same escape-hatch pattern as
model_source_custom: any string here overrides the dropdown.
How it works
Under the hood it builds a full control pipeline: tokenizer, text encoder (Qwen3-4B), VAE, scheduler, and a ZImageControlTransformer2DModel that merges the base transformer with the control weights per the resolved config. If the model is an SDNQ quantized checkpoint, the control transformer gets loaded through the quantized path too - that's the control_quantized machinery, and it's the part that makes low-VRAM control workflows viable.
Two behaviors to know before you wire it up:
- Loading the control pipeline evicts the base pipeline. The pack keeps exactly one base session and one control session cached, and loading one clears the other. So don't build a graph that holds both a base T2I pipeline and a control pipeline resident at once - every re-queue will thrash reloads. Use one or the other per workflow.
control_context_scalein the samplers is your control-strength dial. The union ControlNet on Z-Image Turbo has a known quirk: applied at full strength across all steps it partially breaks the distillation and quality suffers. The classic workaround is the step cutoff - strong control early, released for the final steps. This pack doesn't expose step cutoffs; insteadcontrol_context_scale(default 0.8 in the samplers) is the single strength knob. If controlled output looks overcooked, dial that down before you touch anything else.
Install and model placement
Same install as the pack: ComfyUI Manager (search "Z-Image SDNQ") or git clone https://github.com/GeneralShan/comfyui-zimage-sdnq into custom_nodes, restart. Needs ComfyUI >= 0.17.0, plus diffusers and sdnq (required), and timm + opencv-python-headless for the control path specifically:
pip install sdnq diffusers timm opencv-python-headless
Models go where ComfyUI already looks: diffusers folders under models/diffusers/, control weights under models/controlnet/. And the local_files_only gotcha from the base loader applies double here - with <manual> selected, nothing auto-downloads by default, so drop the files in place yourself or flip the toggle.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| model_source | COMBO | <manual> | Local diffusers model folder. Use <manual> to provide a custom path or HF ID. |
| precision | COMBO | auto | 4 options: auto, full, q8, q4 |
| device | STRING | auto | — |
| dtype | STRING | auto | — |
| quantized_matmul | COMBO | auto | 3 options: auto, enable, disable |
| control_config | COMBO | auto | 6 options: auto, 2.1-lite, 2.1, 2.0, 1.0, custom |
| control_config_path | STRING | — | |
| control_weights_path | COMBO | <manual> | 1 options: <manual> |
| trust_remote_code | BOOLEAN | false | — |
| local_files_only | BOOLEAN | true | — |
| low_cpu_mem_usage | BOOLEAN | true | — |
| model_source_customopt | STRING | Overrides model_source when set. | |
| control_weights_path_customopt | STRING | Overrides control_weights_path when set. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| pipeline | ZIMAGE_CONTROL_PIPELINE | — |