Kandinsky2.2 Unet Decoder
The Unet Decoder
- decoder
- latents
- image_embeds
- negative_image_embeds
- LATENT
This is the workhorse. The Prior Loader and its encoder nodes handle the "what do we want to draw" half of Kandinsky 2.2; the Unet Decoder is the "draw it" half - a full UNet denoising pass over latents, conditioned on the image embeddings the prior produced. If a Kandinsky 2.2 graph has a single most important node, it's this one.
How it works
Kandinsky 2.2's decoder is a classic UNet diffusion pass, but with two things you won't see in a Stable Diffusion sampler node. First, it's conditioned on image_embeds passed as added conditioning rather than CLIP text embeddings - which is why everything upstream has to go through this pack's PRIOR_LATENT type. Second, this UNet predicts noise plus a variance term (learned-variance style), so the node runs CFG on the noise, re-attaches the variance, and only then steps the scheduler. That's why its default guidance_scale of 4 is half the prior's default of 8 - they're different stages tuning different things.
It also honors the strength slider the way img2img expects: lower strength starts the denoise loop at a later timestep, keeping more of the source image from the Image Latents node; strength 1 means full denoise from pure noise.
Inputs and output
decoder- theDECODERoutput from the Decoder Loader.latents- from Latents (text-to-image) or Image Latents (img2img), optionally after a Hint Combiner.image_embeds,negative_image_embeds- thePRIOR_LATENTpair from the text/positive encoders or Image Encoder.strength(default 1) - how much of the starting image survives; the img2img dial.num_inference_steps(default 20),guidance_scale(default 4),seed.
Output: LATENT - denoised latents, which go into the MovQ Decoder for pixels. This node is not an image output node.
Installing it
Manual clone, per the README (not in ComfyUI Manager's list):
cd ComfyUI/custom_nodes
git clone https://github.com/vsevolod-oparin/comfyui-kandinsky22
cd comfyui-kandinsky22
python -s -m pip install -r requirements.txt
Models into ComfyUI/models/checkpoints:
git clone --depth 1 https://huggingface.co/kandinsky-community/kandinsky-2-2-prior
git clone --depth 1 https://huggingface.co/kandinsky-community/kandinsky-2-2-decoder
git clone --depth 1 https://huggingface.co/kandinsky-community/kandinsky-2-2-controlnet-depth
Gotchas
- Every port is required. Missing an embed port or wiring the wrong latent source is the most common way a Kandinsky graph just silently produces garbage. The simple workflow even uses two positive text encoders - one for
image_embeds, one encoding a "low quality, bad quality" phrase intonegative_image_embeds. - Depth needs the right decoder. If you attach a hint via the Hint Combiner, the Decoder Loader must be set to
kandinsky-2-2-controlnet-depth, or the hint is ignored. The README says so in bold; treat that as prophecy. - Slow is normal. An 80-step decoder pass at 768×768 on top of a 20-step prior is not quick, and models shuffle between GPU and CPU between stages. It's a 2023 model doing 2023 speeds.
- Dependency pin. Old
diffuserscommit +accelerate==0.27.2inrequirements.txtcan break other custom nodes sharing the environment.
Kandinsky 2.2 is long dead in the community, but if you're here, you already found the interesting part - this node is where its distinctive painterly look actually happens.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| decoder | DECODER | — | |
| latents | LATENT | — | |
| strength | FLOAT | 1.000–1 | — |
| image_embeds | PRIOR_LATENT | — | |
| negative_image_embeds | PRIOR_LATENT | — | |
| num_inference_steps | INT | 201–10000 | — |
| guidance_scale | FLOAT | 4.00–100 | — |
| seed | INT | 00–18446744073709550000 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |