# PiD Super-Resolution Decode

import { Steps, Aside, Tabs, TabItem } from '@astrojs/starlight/components'

**PiD** (Pixel Diffusion Decoder) is an alternative way to turn a model's latents into an image. Instead of the usual VAE decode, it runs a short pixel-space diffusion that produces a **4× super-resolved** result in a single, few-step pass — so a 512×512 generation comes out as a detailed 2048×2048 image.

Because it decodes in pixel space and is conditioned on your prompt, PiD often recovers finer texture and edge detail than a plain VAE decode followed by an upscaler.

<Aside type="note">
In the **Generate** tab and on the **Canvas**, PiD replaces the VAE decode step of a generation — you enable it *before* generating, it is not applied to a finished image. To run PiD over an image you already have, use the separate **PiD Upscale (4x)** node in the Workflow editor ([see below](#running-pid-on-an-existing-image)).
</Aside>

## Supported models

PiD works with these base models:

| Base model | PiD decoder to install |
|---|---|
| FLUX.1 | PiD Decoder FLUX |
| FLUX.2 Klein (4B / 9B) | PiD Decoder FLUX.2 |
| FLUX.3 Klein / Klein Base | **PiD Decoder FLUX.2** (FLUX.3 shares FLUX.2's VAE) |
| Stable Diffusion 3 | PiD Decoder SD3 |
| SDXL | PiD Decoder SDXL |
| Z-Image / Z-Image Turbo | **PiD Decoder FLUX** (Z-Image shares FLUX.1's VAE) |
| Qwen-Image | PiD Decoder Qwen-Image |
| MOSS-Image | **PiD Decoder FLUX.2** (MOSS-Image shares FLUX.2's VAE) |

<Aside type="tip">
Z-Image has no PiD decoder of its own — when a Z-Image model is active, the decoder picker lists the **FLUX** decoders. That's expected. Likewise, MOSS-Image uses the **FLUX.2** decoders.
</Aside>

## What you need to install

PiD needs two extra models, both available in **Model Manager → Starter Models**:

<Steps>
1. A **PiD Decoder** for your base model (e.g. *PiD Decoder FLUX (2K)*). Some bases offer a *2K* and a *2K-to-4K* preset; SDXL and Qwen-Image ship only the *2K-to-4K* preset.
2. The **Gemma 2 2B (PiD caption encoder)** — PiD uses it to condition the decode on your prompt. It installs automatically as a dependency of any PiD decoder, and is shared across all of them.
</Steps>

A first-generation PiD decoder download is roughly 5 GB, a PiD 1.5 decoder download roughly 2.8 GB (1.6 GB for its int8 build), and the shared Gemma-2 encoder is roughly 5 GB. Once loaded, a decoder runs in full precision and takes about 5.6 GB in either generation; the PiD 1.5 int8 build keeps its transformer layers in int8 and takes about 2 GB.

<Aside type="note">
Most Starter Models install NVIDIA's first-generation PiD checkpoints, which are spread over both the `checkpoints/` and the `checkpoints_deprecated/` folder of the `nvidia/PiD` repository depending on the backbone and preset. NVIDIA's second generation, **PiD 1.5**, exists for FLUX.1, FLUX.2 and Qwen-Image in the *2K-to-4K* preset. All three are Starter Models (*PiD 1.5 Decoder FLUX*, *PiD 1.5 Decoder FLUX.2*, *PiD 1.5 Decoder Qwen-Image*), installed from Comfy-Org's single-file builds. Both generations decode through the same nodes.

Only the `_4step` builds work: the files without it are NVIDIA's undistilled teacher decoders, which need a different sampler, and are rejected during model identification. The `_4step_int8_convrot` builds (each PiD 1.5 decoder has an *int8* Starter Model) keep the decoder's transformer layers in int8: about 2 GB once loaded instead of 5.6 GB, with output practically identical to the full-precision build.
</Aside>

The Gemma-2 caption encoder can also be a single-file **GGUF** (e.g. `gemma-2-2b-it-Q4_K_M.gguf`) that you install manually: InvokeAI loads it natively, keeping the large projection weights quantized instead of expanding them in memory, which cuts the encoder's footprint noticeably. Only Gemma-2-**2b** GGUFs are accepted — PiD's caption projection is fixed to their 2304-dim hidden state.

## Enabling PiD

Open the **Generation** settings for a supported model and expand the advanced options. You'll find a **PiD Decode** control with three modes:

<Tabs>
  <TabItem label="Off">
    Standard VAE decode. No PiD models required.
  </TabItem>
  <TabItem label="Fit">
    Generate at the requested size, decode 4× with PiD, then downscale the result back to the requested size. This is the safe default and works everywhere — the output matches your bounding box exactly, so it composites cleanly on the Canvas.
  </TabItem>
  <TabItem label="Native">
    Treat the requested dimensions as the **4× target**: the image is generated at target ÷ 4 and PiD's full 4× output is used directly (no downscale), preserving all of the added detail. Great when you want a large, highly-detailed result.
  </TabItem>
</Tabs>

When PiD mode is not *Off*, pick your **PiD Decoder** and **Gemma-2 Encoder** below the mode selector. The **PiD Steps** control (default 4) sets how many decode steps run — the released checkpoints are trained for 4.

PiD is available in both the **Generate** tab (text-to-image) and on the **Canvas** (image-to-image), in both Fit and Native modes.

In the Workflow editor, each base has its own PiD decode node, such as *Latents to Image - Qwen-Image + PiD (4x SR)*. They take the denoised latent as the model produced it; only the **FLUX.2** node also needs the FLUX.2 VAE connected, because it reads the VAE's latent statistics to bring the latent into the form PiD was trained on.

## Running PiD on an existing image

Everything above describes PiD as a *decode* step: it needs the latent the model just produced, so it only exists inside a generation. If you want to push an image you already have through PiD, the Workflow editor has a separate **PiD Upscale (4x)** node.

It encodes your image with the FLUX VAE and hands the resulting latent to the PiD decoder, giving a 4× result in one pass — the PiD analogue of an ESRGAN / SUPIR upscale. Connect a FLUX VAE, a **FLUX** PiD decoder and the Gemma-2 encoder, and optionally give it a caption describing the image (the decoder is caption-conditioned; an empty caption is the cheapest option but usually the weaker result).

<Aside type="caution">
This node is a **prototype** and FLUX-only in both directions: it requires the FLUX.1 VAE (which Z-Image also uses; a VAE of another family is rejected) and a FLUX PiD decoder. Since the input is a plain image rather than the generating model's own latent, results are less faithful than PiD used as a decode.
</Aside>

## Tips & limitations

On GPUs with limited VRAM, enable the experimental PiD memory optimizations in `invokeai.yaml`, then restart InvokeAI:

```yaml
pid_memory_optimization: true
```

This setting applies to every supported PiD decoder. It reduces peak activation and sampler memory by processing parts of the pixel pathway in chunks and by running the sampler's intermediates in float32 instead of float64 — measured on an RTX 4090, a 2048px decode takes about 2.7–3.4 GB of VRAM on top of the decoder instead of 5.5–6.1 GB, and a 4096px decode about 11–14 GB, which fits on a 24 GB card only with this setting enabled. Decoding speed is roughly unchanged.

It is disabled by default because it **changes the decoded image**. The combined optimized path is not guaranteed to be bit-exact with the default path: chunking can change GPU kernel and reduction choices, while the float32 sampler math differs from the default float64 path. The few-step sampler amplifies that into a small but real difference (~43 dB PSNR — visually indistinguishable, numerically not identical). A seed that reproduced an image with the setting off will not reproduce it exactly with the setting on, and because this is a server-wide `invokeai.yaml` option it is not recorded in image metadata — each decode logs that it ran optimized instead.

- **Turn off "Scale Before Processing"** on the Canvas when using PiD — PiD already decodes at 4×, so pre-scaling would inflate the work and is blocked.
- **Inpaint / Outpaint** are not supported with PiD yet; use text-to-image or image-to-image.
- **SDXL Refiner** cannot be combined with PiD — disable one of them.
- PiD's memory use scales with the *output* resolution. A 2048px output needs only a little more headroom than a normal decode, but Native mode at large target sizes (e.g. a 4096px result) is significantly heavier.
- Turbo variants (e.g. Z-Image Turbo) work as usual — the low step count / no-CFG only affects generation; PiD's own step count is separate.

<Aside type="caution">
The PiD decoder *code* is Apache-2.0, but NVIDIA releases the pretrained *weights* under a non-commercial / research license. Keep that in mind if you redistribute the checkpoints.
</Aside>