Z-Image i2L v2 — Sample (ControlNet)
Structure from ControlNet, style from i2L — read the loader gotcha first
- pipe
- lora
- control_image
- negative_lora
- image
The most powerful node in the pack, and the easiest to get wrong. Sample (ControlNet) generates an image whose structure comes from a control map - depth, canny, pose, tile, whatever the Union ControlNet speaks - and whose style comes from your i2L LoRA. Composition you control, look you extracted from reference images. That combination is where image-to-LoRA stops being a novelty and becomes a workflow.
The gotcha, and it's a real one: the ControlNet this pack loads is PAI/Z-Image-Turbo-Fun-Controlnet-Union-2.1, and it was trained for the Turbo model, not Z-Image base. So the Loader has to be set to base_model: z-image-turbo and load_controlnet: true, or this node either errors or produces noise. The defaults reflect that: cfg_scale is 1.0 (guidance-distilled Turbo, so CFG above ~1 just burns the image), num_inference_steps is 30, and sigma_shift is 0. At CFG 1 the negative_lora branch is inert - there's no negative pass to attach it to, so don't bother with the gray-image trick here.
The inputs: pipe and lora (your i2L style LoRA), control_image (the map - depth/canny/pose/tile matching the Union), prompt, control_scale (0.7, the strength of the structure condition; 0.65–0.9 is the healthy range for these unions), seed, cfg_scale (1), num_inference_steps (30), sigma_shift (0), and width/height (both 1024). Output: image.
Mechanically it wraps the pipe's controlnet input in a ControlNetInput(image=..., scale=control_scale) and samples. Control applies across the whole run - this pack doesn't implement the two-pass step-cutoff trick the community uses for the best Turbo ControlNet quality, so if you want that, you'd build it outside this pack. What you get here is the simple, single-pass version, and it's good enough for most structural jobs.
Troubleshooting: the classic failure is "No ControlNet is loaded on the pipeline" - you didn't check load_controlnet on the Loader; re-run it and it downloads the Union from ModelScope. Feeding a control map that doesn't match your prompt (a pose map with a "person" prompt is fine, but a depth map of a room with a prompt about a car) gives you structure you didn't ask for. And the one that catches everyone: this node is Turbo - the Loader must be on z-image-turbo, not the default z-image, or you get noise.
Install
Installs as part of the pack: ComfyUI Manager (search ComfyUI_ZImageI2L_v2) or git clone https://github.com/jzhang-POP/ComfyUI_ZImageI2L_v2 into ComfyUI/custom_nodes/. The dependency that bites is DiffSynth-Studio, which must come from git because v2 needs its Diffusion Templates API:
git clone https://github.com/modelscope/DiffSynth-Studio.git
cd DiffSynth-Studio && pip install -e . && cd ..
pip install -r ComfyUI/custom_nodes/ComfyUI_ZImageI2L_v2/requirements.txt
Restart ComfyUI. The first Loader run downloads both the Z-Image models and the ControlNet Union - tens of gigabytes total, one-time.
Inputs (13)
| Name | Type | Default | Description |
|---|---|---|---|
| pipe | ZIMAGE_PIPE | — | |
| lora | ZIMAGE_LORA | — | |
| control_image | IMAGE | Control map (depth/canny/pose/tile...) matching the Union ControlNet. | |
| prompt | STRING | a cat is sitting on a stone | — |
| control_scale | FLOAT | 0.700–2 | — |
| seed | INT | 00–18446744073709550000 | — |
| cfg_scale | FLOAT | 1.00–30 | — |
| num_inference_steps | INT | 301–200 | — |
| sigma_shift | FLOAT | 0.00–20 | — |
| width | INT | 1024256–4096 | — |
| height | INT | 1024256–4096 | — |
| negative_loraopt | ZIMAGE_LORA | — | |
| negative_promptopt | STRING | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |