[Core] Add batch parallel VAE decode (#8162)
Signed-off-by: QianCyrus <101633534+QianCyrus@users.noreply.github.com>
This commit is contained in:
1 parent
2bcd1e449a
commit
c2cd13c009
12 files changed
+460
-37
No files matched your search
@@ -1,12 +1,12 @@
|
||||
# VAE Parallelism Guide
|
||||
|
||||
|
||||
## Table of Content
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Quick Start](#quick-start)
|
||||
- [Example Script](#example-script)
|
||||
- [Configuration Parameters](#configuration-parameters)
|
||||
- [Batch Parallel Decode](#batch-parallel-decode)
|
||||
- [Best Practices](#best-practices)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Summary](#summary)
|
||||
@@ -15,23 +15,22 @@
|
||||
|
||||
## Overview
|
||||
|
||||
VAE parallelism distributes VAE (Variational AutoEncoder) decode/encode work across multiple GPUs. This guide covers VAE patch/tile parallelism, which splits latent space into spatial tiles or patches, and Wan spatial-shard decode, which shards decoder feature maps along height or width.
|
||||
VAE parallelism distributes VAE (Variational AutoEncoder) decode/encode work across multiple GPUs. This guide covers patch/tile parallelism, batch parallel decode for image VAEs, and Wan spatial-shard decode. Patch/tile parallelism divides images into spatial regions; batch parallel decode assigns complete images to ranks.
|
||||
|
||||
This is particularly useful for:
|
||||
|
||||
- **High-resolution image generation** where VAE decode can become a memory bottleneck
|
||||
- **Memory-constrained environments** where the VAE decode activation peak exceeds available VRAM
|
||||
- **Multi-GPU setups** where you want to leverage distributed resources for the VAE stage
|
||||
|
||||
See supported models list in [Supported Models](../../diffusion_features.md#supported-models).
|
||||
|
||||
|
||||
VAE patch parallelism uses two strategies based on image size:
|
||||
|
||||
| Strategy | Use Case | How It Works | Overlap Handling | Output Quality |
|
||||
|----------|----------|--------------|------------------|----------------|
|
||||
| **Tiled Decode** | Large images (triggers VAE tiling) | Distributes existing VAE tiling computation across ranks. Each rank decodes a subset of overlapping tiles. | Uses VAE's native `blend_v` and `blend_h` functions to seamlessly merge overlapping regions | Bit-identical (same logic as single-GPU tiling) |
|
||||
| **Patch Decode** | Small images (no VAE tiling) | Splits latent into spatial patches with halos. Each rank decodes one patch with boundary context. | Halo regions provide edge context; core regions are directly stitched without blending | Near-identical (diff < 0.5%, visually imperceptible) |
|
||||
|
||||
| Strategy | Use Case | How It Works | Overlap Handling | Output Quality |
|
||||
| ---------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| **Tiled Decode** | Large images (triggers VAE tiling) | Distributes existing VAE tiling computation across ranks. Each rank decodes a subset of overlapping tiles. | Uses VAE's native `blend_v` and `blend_h` functions to seamlessly merge overlapping regions | Bit-identical (same logic as single-GPU tiling) |
|
||||
| **Patch Decode** | Small images (no VAE tiling) | Splits latent into spatial patches with halos. Each rank decodes one patch with boundary context. | Halo regions provide edge context; core regions are directly stitched without blending | Near-identical (diff < 0.5%, visually imperceptible) |
|
||||
|
||||
VAE Patch Parallelism **reuses the DiT process group** (`dit_group`) and does not initialize a separate ProcessGroup. This means:
|
||||
|
||||
@@ -110,19 +109,80 @@ vllm serve Tongyi-MAI/Z-Image-Turbo --omni --port 8091 \
|
||||
|
||||
In `DiffusionParallelConfig`:
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `vae_patch_parallel_size` | int | 1 | Number of GPUs for VAE patch/tile parallelism. Set to 2 or higher to enable. Should typically match `tensor_parallel_size` as they share the same process group. |
|
||||
| `vae_parallel_mode` | str | `"tile"` | VAE parallel decode strategy: `"tile"` (default tile/patch parallel decode), `"spatial_shard_height"`, or `"spatial_shard_width"` (spatially-sharded decode, Wan only). See [Spatially-Sharded Decode](#spatially-sharded-decode-wan). |
|
||||
| Parameter | Type | Default | Description |
|
||||
| ------------------------- | ------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `vae_patch_parallel_size` | int | 1 | Number of ranks requested for VAE parallelism, including batch mode. Set to 2 or higher to enable. Batch mode caps this degree at the existing worker group size. |
|
||||
| `vae_parallel_mode` | str | `"tile"` | `"tile"` for tile/patch decode, `"batch"` for complete-image batch decode, or `"spatial_shard_height"` / `"spatial_shard_width"` for Wan spatial-shard decode. |
|
||||
|
||||
Additional requirements:
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `vae_use_tiling` | bool | False | Must be set to `True` when using VAE patch parallelism. |
|
||||
| Parameter | Type | Default | Description |
|
||||
| ---------------- | ------ | --------- | ------------------------------------------------------- |
|
||||
| `vae_use_tiling` | bool | False | Must be set to `True` when using VAE patch parallelism. |
|
||||
|
||||
!!! note "Automatic VAE Tiling"
|
||||
When `vae_patch_parallel_size > 1` and the model has a distributed VAE (`DistributedVaeMixin`), the system automatically sets `vae_use_tiling=True` if not already enabled.
|
||||
When `vae_patch_parallel_size > 1` and the model has a distributed VAE (`DistributedVaeMixin`), tile and spatial-shard modes automatically enable `vae_use_tiling`. Batch mode preserves the requested tiling setting.
|
||||
|
||||
---
|
||||
|
||||
## Batch Parallel Decode
|
||||
|
||||
Set `vae_parallel_mode="batch"` to distribute complete images across ranks during
|
||||
VAE decode. This mode supports pipelines that load `DistributedAutoencoderKL`
|
||||
or `DistributedAutoencoderKLFlux2`, including FLUX.2-dev and FLUX.2 Klein. Klein
|
||||
selects the distributed VAE only for batch mode; its default path is unchanged.
|
||||
Selecting this mode for an
|
||||
unsupported VAE, including Wan, raises an error at model initialization.
|
||||
|
||||
For a pipeline already using two tensor-parallel workers, select batch decode
|
||||
with these Python settings:
|
||||
|
||||
```python
|
||||
parallel_config = DiffusionParallelConfig(
|
||||
tensor_parallel_size=2,
|
||||
vae_patch_parallel_size=2,
|
||||
vae_parallel_mode="batch",
|
||||
)
|
||||
sampling_params = OmniDiffusionSamplingParams(num_outputs_per_prompt=2)
|
||||
```
|
||||
|
||||
The corresponding serving flags are `--vae-patch-parallel-size 2
|
||||
--vae-parallel-mode batch`. Keep the existing DiT parallelism configuration;
|
||||
the VAE degree does not allocate extra workers. Send a request for multiple
|
||||
images to use the batch split.
|
||||
|
||||
Each rank decodes a contiguous part of the image batch through its native VAE
|
||||
decoder. Results are reassembled in the original image order and made available
|
||||
on every worker. With two images and four workers, two workers decode one image
|
||||
each. With five images and four workers, the assigned batch sizes are 2, 1, 1,
|
||||
and 1. Workers without images still participate in the required communication.
|
||||
|
||||
**Constraints and behavior:**
|
||||
|
||||
- Batch mode and distributed tile/patch mode are mutually exclusive. Encoding
|
||||
uses the native local path, including native tiling when enabled, rather than
|
||||
distributing spatial tiles across workers.
|
||||
- Batch size one, VAE degree one, or a single worker uses native decode on each
|
||||
worker. Batch mode does not automatically switch to distributed tile/patch
|
||||
decode for a single image, even with `vae_use_tiling=True`. To distribute a
|
||||
single image across workers, select `vae_parallel_mode="tile"` on a pipeline
|
||||
that supports distributed tile/patch decoding.
|
||||
- Data parallelism, pipeline parallelism, and CFG parallelism must each have
|
||||
degree one because this implementation communicates over the worker WORLD
|
||||
group. Tensor and sequence parallelism may supply the shared workers.
|
||||
- Batch mode does not force tiling. Explicit native VAE tiling and slicing
|
||||
settings remain in effect within each rank's assigned batch and on the
|
||||
single-image fallback. Native tiling splits an image locally on one worker;
|
||||
it does not add cross-worker tile parallelism to batch mode.
|
||||
- It does not merge independent serving requests. The VAE must receive a batch
|
||||
containing multiple images, for example through `num_outputs_per_prompt`.
|
||||
|
||||
Splitting the batch can reduce per-rank decoder work and activation memory, but
|
||||
collecting decoded images adds communication and buffers. Measure complete
|
||||
request latency and memory for the intended model, image count, and resolution.
|
||||
This feature has no universal speedup or memory-saving guarantee. Changing the
|
||||
decoder batch shape can also change floating-point rounding; validate generated
|
||||
outputs when selecting a deployment configuration.
|
||||
|
||||
---
|
||||
|
||||
@@ -194,7 +254,8 @@ python3 benchmarks/diffusion/diffusion_benchmark_serving.py \
|
||||
### Common Issue 1: Model Not Support VAE Patch Parallel
|
||||
|
||||
**Symptoms**:
|
||||
```
|
||||
|
||||
```text
|
||||
WARNING: vae_patch_parallel_size=2 is set but VAE patch parallelism is NOT enabled for xxxPipeline; ignoring.
|
||||
```
|
||||
|
||||
@@ -217,7 +278,6 @@ if vae_pp_size > 1 and not is_distributed_vae:
|
||||
|
||||
2. To add support for a new model, implement `DistributedVaeMixin` on its VAE class (contributions are welcome).
|
||||
|
||||
|
||||
### Common Issue 2: `vae_patch_parallel_size` Exceeds DiT Process Group Size
|
||||
|
||||
**Symptoms**: Shows warning message, and vae patch parallel size is resized to DiT process group size
|
||||
@@ -227,6 +287,7 @@ if vae_pp_size > 1 and not is_distributed_vae:
|
||||
**Recommendation**: Always set `vae_patch_parallel_size` to be no greater than your DiT process group size.
|
||||
|
||||
Note that the size of DiT process group size equals to:
|
||||
|
||||
```text
|
||||
dit_parallel_size = data_parallel_size
|
||||
× cfg_parallel_size
|
||||
@@ -235,7 +296,8 @@ dit_parallel_size = data_parallel_size
|
||||
× tensor_parallel_size
|
||||
|
||||
```
|
||||
_sequence_parallel_size = ulysses_degree × ring_degree_
|
||||
|
||||
`sequence_parallel_size = ulysses_degree × ring_degree`
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in new issue
Block a user