Generated reference · ComfyUI workflow · zimage

Z-Image Controlled Text-to-Image

Z-Image text-to-image steered by a control image through the Fun-Controlnet-Union 2.1 patch (canny, depth, pose or tile), on the base or a Civitai Turbo finetune, with an optional Z-Image LoRA. Translated from …

zimage25nodesGPU A5000out image~77sv1.0.0

On this page

Z-Image text-to-image steered by a control image through the Fun-Controlnet-Union 2.1 patch (canny, depth, pose or tile), on the base or a Civitai Turbo finetune, with an optional Z-Image LoRA. Translated from Comfy-Org/workflow_templates@aaac56dd templates/image_z_image_turbo_fun_union_controlnet.json: ModelPatchLoader + QwenImageDiffsynthControlnet (strength 1), core Canny (low 0.1, high 0.32), the control image through ImageScaleToMaxDimension (lanczos, 1024) and GetImageSize into EmptySD3LatentImage, ModelSamplingAuraFlow shift 3, res_multistep + simple, Turbo at 8 steps and CFG 1 with the negative zeroed. The base schedule (25 steps, CFG 4, a real negative) is templates/image_z_image.json's. Depth runs the core Depth Anything 3 nodes with the values of templates/utility_depth_anything3_image_depth_estimation.json. Choosing a Turbo checkpoint selects the Turbo union patch and the 8-step schedule through checkpoint_profile.

25Graph nodes
23Node classes
13Inputs
15Models

Tags: zimagerunpod-serverlessvolume-backedtext-to-imagecontrolnet

Inputs (13)#

The typed parameter surface callers bind when they request this workflow. Enum options and numeric bounds are the values the workflow document declares.

promptstringrequireddefault Realistic photo, close-up of a latina model peeking through pine branches, dappled sunlight on her face, natural, moody, smooth skin, a little bit film grain.
Positive prompt in natural prose (the default is the upstream union-controlnet template's prompt)
negative_promptstringdefault
Negative prompt, honoured by the base checkpoint (CFG-guided). A Turbo checkpoint samples at CFG 1 with the negative zeroed (ConditioningZeroOut, as the upstream template does), so this text is not encoded for it.
checkpointenumdefault zimage-base-bf16
Z-Image checkpoint on the network volume (see zimage-txt2img). The base loads the Z-Image Fun-Controlnet-Union 2.1 patch; the two Turbo checkpoints load the Turbo Fun-Controlnet-Union 2.1 2602 8-step patch and run 8 steps at CFG 1 with the negative zeroed, whatever steps and cfg say.
options: zimage-base-bf16cyberrealistic-zimage-turbo-v8-bf16zimage-turbo-bf16-aio
stepsintegerdefault 25min 8max 60
Sampling steps for the base checkpoint (25 is the upstream base template's value). Not used by a Turbo checkpoint, which always runs 8.
cfgfloatdefault 4.0min 1.0max 10.0
Classifier-free guidance for the base checkpoint (4 is the upstream base template's value). Not used by a Turbo checkpoint, which always samples at 1.
seedintegerdefault -1
Random seed (-1 = random)
control_imageimagerequired
The image the control is extracted from. It is scaled so its longest side is 1024 (lanczos) and the output takes its aspect ratio at that size, as the upstream template does with ImageScaleToMaxDimension and GetImageSize.
controlenumdefault canny
Which control the union patch receives. canny = ComfyUI's core Canny at the upstream template's thresholds (0.1 / 0.32); depth = core Depth Anything 3 (mono large, 504 px, V2-style near-white depth, the upstream Depth Anything 3 template's values); pose = controlnet_aux DWPose (body, hands and face, the settings the motion catalog's pose control uses); tile = controlnet_aux TilePreprocessor at its node defaults (3 pyrUp iterations, 512 px), since no upstream template sets them.
options: cannydepthposetile
control_strengthfloatdefault 1.0min 0.0max 2.0
Union patch strength (QwenImageDiffsynthControlnet.strength; 1.0 is the upstream template's value). The node accepts -10..10; this catalog offers 0..2.
control_end_fractionfloatdefault 1.0min 0.1max 1.0
The share of the sampling steps that run with the control, ending at step round(steps x fraction) of the effective schedule (25 by default on the base, 8 on Turbo). The union patch node has no start/end input, so below 1.0 the sampler is split into two KSamplerAdvanced passes over the same schedule: the controlled model up to the end step (leftover noise kept), then the same model without the patch to the end, adding no noise (so the seed only acts in the first pass). At 1.0 the second pass is absent and the graph samples once, as the upstream template does. A documented approximation: res_multistep restarts its multistep history at the split.
batch_sizeintegerdefault 1min 1max 1
Images per run. Pinned to 1: the output takes the control image's size at a longest side of 1024 (up to 1 MP), where the executor's resolution-scaled batch cap (C.12.19) allows one latent.
loraenumdefault none
Optional Z-Image LoRA (A.03.02; see zimage-txt2img). none leaves the graph without a LoRA loader.
options: nonephotoreal-betternudes-v3realistic-snapshot-v5breast-sliderdetail-sliderdetaildaemonz-v1.1
lora_strengthfloatdefault 1.0min -2.0max 2.0
LoRA strength on the model (LoraLoaderModelOnly.strength_model).

ComfyUI node graph (25)#

The executable ComfyUI prompt graph: 25 nodes across 23 distinct node classes, wired by 21 data dependencies. Nodes tinted green come from a custom node pack this workflow declares; the rest are ComfyUI core / baked-community classes.

flowchart TD n0["1: UNETLoader"] n1["2: CLIPLoader"] n2["3: VAELoader"] n3["4: CheckpointLoaderSimple"] n4["5: LoraLoaderModelOnly"] n5["6: ModelSamplingAuraFlow"] n6["7: CLIPTextEncode"] n7["8: CLIPTextEncode"] n8["9: ConditioningZeroOut"] n9["10: LoadImage"] n10["11: ImageScaleToMaxDimension"] n11["12: GetImageSize"] n12["13: EmptySD3LatentImage"] n13["14: Canny"] n14["15: LoadDA3Model"] n15["16: DA3Inference"] n16["17: DA3Render"] n17["18: DWPreprocessor"] n18["19: TilePreprocessor"] n19["20: ModelPatchLoader"] n20["21: QwenImageDiffsynthControlnet"] n21["22: KSamplerAdvanced"] n22["23: KSamplerAdvanced"] n23["24: VAEDecode"] n24["25: SaveImage"] n6 -->|conditioning| n8 n9 -->|image| n10 n10 -->|image| n11 n11 -->|width| n12 n11 -->|height| n12 n10 -->|image| n13 n14 -->|da3_model| n15 n10 -->|image| n15 n15 -->|da3_geometry| n16 n10 -->|image| n17 n10 -->|image| n18 n5 -->|model| n20 n19 -->|model_patch| n20 n20 -->|model| n21 n6 -->|positive| n21 n12 -->|latent_image| n21 n5 -->|model| n22 n6 -->|positive| n22 n21 -->|latent_image| n22 n22 -->|samples| n23 n23 -->|images| n24
Data-flow DAG — scroll to zoom, drag to pan.

Nodes (25)#

1UNETLoadercore
unet_name = {{checkpoint_map[checkpoint]}} tmplweight_dtype = default
outputs: MODEL
2CLIPLoadercore
clip_name = qwen_3_4b.safetensorstype = lumina2device = default
outputs: CLIP
3VAELoadercore
vae_name = ae.safetensors
outputs: VAE
4CheckpointLoaderSimplecore
ckpt_name = {{checkpoint_map[checkpoint]}} tmpl
outputs: MODELCLIPVAE
5LoraLoaderModelOnlycore
model = {{loader_refs[checkpoint_profile[checkpoint].loader].model}} tmpllora_name = {{lora_map[lora]}} tmplstrength_model = {{lora_strength}} tmpl
outputs: MODEL
6ModelSamplingAuraFlowcore
model = {{lora_ref if lora != 'none' else loader_refs[checkpoint_profile[checkpoint].loader].model}} tmplshift = 3
outputs: MODEL
7CLIPTextEncodecore
text = {{constructed_prompt}} tmplclip = {{loader_refs[checkpoint_profile[checkpoint].loader].clip}} tmpl
outputs: CONDITIONING
8CLIPTextEncodecore
text = {{negative_prompt}} tmplclip = {{loader_refs[checkpoint_profile[checkpoint].loader].clip}} tmpl
outputs: CONDITIONING
9ConditioningZeroOutcore
conditioning = ◂ node 7 · out[0]
outputs: CONDITIONING
10LoadImagecore
image = {{control_image}} tmpl
outputs: IMAGEMASK
11ImageScaleToMaxDimensioncore
image = ◂ node 10 · out[0]upscale_method = lanczoslargest_size = 1024
outputs: IMAGE
12GetImageSizecore
image = ◂ node 11 · out[0]
outputs: INTINTINT
13EmptySD3LatentImagecore
width = ◂ node 12 · out[0]height = ◂ node 12 · out[1]batch_size = {{batch_size}} tmpl
outputs: LATENT
14Cannycore
image = ◂ node 11 · out[0]low_threshold = 0.1high_threshold = 0.32
outputs: IMAGE
15LoadDA3Modelcore
model_name = depth_anything_3_mono_large.safetensorsweight_dtype = default
outputs: DA3_MODEL
16DA3Inferencecore
da3_model = ◂ node 15 · out[0]image = ◂ node 11 · out[0]resolution = 504resize_method = upper_bound_resizemode = mono
outputs: DA3_GEOMETRY
17DA3Rendercore
da3_geometry = ◂ node 16 · out[0]output = depthoutput.normalization = v2_styleoutput.apply_sky_clip = false
outputs: IMAGE
18DWPreprocessorcore
image = ◂ node 11 · out[0]detect_hand = enabledetect_body = enabledetect_face = enableresolution = 512bbox_detector = yolox_l.onnxpose_estimator = dw-ll_ucoco_384.onnxscale_stick_for_xinsr_cn = disable
outputs: IMAGEPOSE_KEYPOINT
19TilePreprocessorcore
image = ◂ node 11 · out[0]pyrUp_iters = 3resolution = 512
outputs: IMAGE
20ModelPatchLoadercore
name = {{checkpoint_profile[checkpoint].union_patch}} tmpl
outputs: MODEL_PATCH
21QwenImageDiffsynthControlnetcore
model = ◂ node 6 · out[0]model_patch = ◂ node 20 · out[0]vae = {{loader_refs[checkpoint_profile[checkpoint].loader].vae}} tmplimage = {{control_source_map[control]}} tmplstrength = {{control_strength}} tmpl
outputs: MODEL
22KSamplerAdvancedcore
model = ◂ node 21 · out[0]add_noise = enablenoise_seed = {{seed}} tmplsteps = {{distilled_schedule.steps if checkpoint_profile[checkpoint].distilled else steps}} tmplcfg = {{distilled_schedule.cfg if checkpoint_profile[checkpoint].distilled else cfg}} tmplsampler_name = res_multistepscheduler = simplepositive = ◂ node 7 · out[0]negative = {{checkpoint_profile[checkpoint].negative}} tmpllatent_image = ◂ node 13 · out[0]start_at_step = 0end_at_step = {{int(round((distilled_schedule.steps if checkpoint_profile[checkpoint].distilled else steps) * control_end_fraction))}} tmplreturn_with_leftover_noise = {{'enable' if control_end_fraction < 1.0 else 'disable'}} tmpl
outputs: LATENT
23KSamplerAdvancedcore
model = ◂ node 6 · out[0]add_noise = disablenoise_seed = {{seed}} tmplsteps = {{distilled_schedule.steps if checkpoint_profile[checkpoint].distilled else steps}} tmplcfg = {{distilled_schedule.cfg if checkpoint_profile[checkpoint].distilled else cfg}} tmplsampler_name = res_multistepscheduler = simplepositive = ◂ node 7 · out[0]negative = {{checkpoint_profile[checkpoint].negative}} tmpllatent_image = ◂ node 22 · out[0]start_at_step = {{int(round((distilled_schedule.steps if checkpoint_profile[checkpoint].distilled else steps) * control_end_fraction))}} tmplend_at_step = 10000return_with_leftover_noise = disable
outputs: LATENT
24VAEDecodecore
samples = ◂ node 23 · out[0]vae = {{loader_refs[checkpoint_profile[checkpoint].loader].vae}} tmpl
outputs: IMAGE
25SaveImagecore
images = ◂ node 24 · out[0]filename_prefix = isis/zimage-txt2img-control

Prompt construction#

template
{base_prompt}

Variables (1)#

base_prompt
{{prompt}} tmpl

Parameter banks (9)#

The prompt / configuration lookup tables this workflow keys into from its inputs — the vocabulary that turns a style / palette / preset selection into graph parameters.

option_policy (2)#

checkpoint
{"zimage-base-bf16": {"distribution": "service", "content": "neutral"}, "cyberrealistic-zimage-turbo-v8-bf16": {"distribution": "service", "content": "racy"}, "zimage-turbo-bf16-aio": {"distribution": "service", "content": "neutral"}}
lora
{"photoreal-betternudes-v3": {"distribution": "service", "content": "explicit"}, "realistic-snapshot-v5": {"distribution": "service", "content": "neutral"}, "breast-slider": {"distribution": "service", "content": "racy"}, "detail-slider": {"distribution": "service", "content": "neutral"}, "detaildaemonz-v1.1": {"distribution": "service", "content": "neutral"}}

checkpoint_map (3)#

zimage-base-bf16
z_image_bf16.safetensors
cyberrealistic-zimage-turbo-v8-bf16
cyberrealistic_zimage_turbo_v8_bf16.safetensors
zimage-turbo-bf16-aio
zimage_turbo_bf16_aio.safetensors

checkpoint_profile (3)#

zimage-base-bf16
{"loader": "unet", "distilled": false, "negative": ["8", 0], "union_patch": "Z-Image-Fun-Controlnet-Union-2.1.safetensors"}
cyberrealistic-zimage-turbo-v8-bf16
{"loader": "unet", "distilled": true, "negative": ["9", 0], "union_patch": "Z-Image-Turbo-Fun-Controlnet-Union-2.1-2602-8steps.safetensors"}
zimage-turbo-bf16-aio
{"loader": "aio", "distilled": true, "negative": ["9", 0], "union_patch": "Z-Image-Turbo-Fun-Controlnet-Union-2.1-2602-8steps.safetensors"}

distilled_schedule (2)#

steps
8
cfg
1.0

loader_refs (2)#

unet
{"model": ["1", 0], "clip": ["2", 0], "vae": ["3", 0]}
aio
{"model": ["4", 0], "clip": ["4", 1], "vae": ["4", 2]}

lora_ref (2)#

50

control_source_map (4)#

canny
140
depth
170
pose
180
tile
190

lora_map (6)#

none
photoreal-betternudes-v3
zimage-photoreal-betternudes-v3.safetensors
realistic-snapshot-v5
zimage-realistic-snapshot-v5.safetensors
breast-slider
zimage-breast-slider.safetensors
detail-slider
zimage-detail-slider.safetensors
detaildaemonz-v1.1
zimage-detaildaemonz-v1.1.safetensors

requires_families (5)#

zimagezimage-cyberrealisticzimage-aiozimage-controlcontrolnet-aux

Models & dependencies#

Custom node packs (1)#

The non-core ComfyUI node classes this graph requires; the RunPod worker image the workflow runs on must bake or install a pack that provides every one of them.

comfyui_controlnet_aux

Models required (15)#

z_image_bf16.safetensors
cyberrealistic_zimage_turbo_v8_bf16.safetensors
zimage_turbo_bf16_aio.safetensors
qwen_3_4b.safetensors
ae.safetensors
Z-Image-Fun-Controlnet-Union-2.1.safetensors
Z-Image-Turbo-Fun-Controlnet-Union-2.1-2602-8steps.safetensors
depth_anything_3_mono_large.safetensors
yolox_l.onnx
dw-ll_ucoco_384.onnx
zimage-photoreal-betternudes-v3.safetensors
zimage-realistic-snapshot-v5.safetensors
zimage-breast-slider.safetensors
zimage-detail-slider.safetensors
zimage-detaildaemonz-v1.1.safetensors

Output contract#

What a successful run of this workflow returns.

type
image
format
png

Taxonomy & routing#

How the control plane classifies this workflow — from the committed workflow-taxonomy-registry.json. It drives the consistency / control surface the agentic director can exercise over the workflow.

assetFamily
portrait-hero-image-bundle
outputPackageProfile
image-single-profile
controlModalities
controlnet-cannycontrolnet-depthcontrolnet-posemodel-locksampler-scheduler-lockseed-lock
consistencyDimensions
identitylightingenvironment
notes
Z-Image with a Fun-Controlnet-Union 2.1 control image (canny, depth, pose, tile); a Turbo checkpoint selects the Turbo patch and the 8-step schedule.