sgl-project/sglang · error · ValueError
The native SD2 UNet currently supports only the Hunyuan3D fo
Error message
The native SD2 UNet currently supports only the Hunyuan3D four-level SD2.1 block layout.
What it means
The native SD2 UNet implementation only supports the exact Hunyuan3D-style SD2.1 architecture: a fixed four-level down/up block layout (DownBlock2D + 3 CrossAttnDownBlock2D; UpBlock2D + 3 CrossAttnUpBlock2D). Any other block layout fails config validation.
Source
Thrown at python/sglang/multimodal_gen/runtime/models/dits/stable_diffusion.py:88
)
parsed.validate()
return parsed
def validate(self) -> None:
expected_down = (
"CrossAttnDownBlock2D",
"CrossAttnDownBlock2D",
"CrossAttnDownBlock2D",
"DownBlock2D",
)
expected_up = (
"UpBlock2D",
"CrossAttnUpBlock2D",
"CrossAttnUpBlock2D",
"CrossAttnUpBlock2D",
)
if self.down_block_types != expected_down or self.up_block_types != expected_up:
raise ValueError(
"The native SD2 UNet currently supports only the Hunyuan3D "
"four-level SD2.1 block layout."
)
if len(self.block_out_channels) != 4 or len(self.attention_head_dim) != 4:
raise ValueError("Hunyuan3D SD2.1 UNet requires four channel stages.")
if self.layers_per_block != 2 or self.transformer_layers_per_block != 1:
raise ValueError(
"Hunyuan3D SD2.1 UNet requires two ResNet layers and one "
"transformer layer per block."
)
if not self.use_linear_projection:
raise ValueError("Hunyuan3D SD2.1 checkpoints require linear projection.")
@dataclass
class StableDiffusionUNetOutput:
sample: torch.Tensor
View on GitHub (pinned to 0132848349)
Solutions
- Use the Hunyuan3D SD2.1 UNet config: down_block_types=(DownBlock2D, CrossAttnDownBlock2D x3), up_block_types=(UpBlock2D, CrossAttnUpBlock2D x3)
- For non-Hunyuan3D SD2 checkpoints, use diffusers' UNet2DConditionModel instead of this native path
- Verify block_out_channels and attention_head_dim both have 4 entries and layers_per_block=2
Example fix
# before cfg.down_block_types = ["CrossAttnDownBlock2D"] * 4 # after cfg.down_block_types = ["DownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D"] cfg.up_block_types = ["UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D"]
Defensive patterns
Strategy: validation
Validate before calling
EXPECTED_DOWN = ("DownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D")
EXPECTED_UP = ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")
assert tuple(cfg.down_block_types) == EXPECTED_DOWN and tuple(cfg.up_block_types) == EXPECTED_UP Type guard
def is_hunyuan3d_sd2_layout(cfg) -> bool:
return (tuple(cfg.down_block_types) == ("DownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D")
and tuple(cfg.up_block_types) == ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")) Prevention
- Only feed Hunyuan3D SD2.1 checkpoints to the native path; use diffusers for other SD2 variants
When it happens
Trigger: Loading a UNet config (e.g. via from_dict) whose down_block_types/up_block_types deviate from the Hunyuan3D SD2.1 layout — different depth, mid-block-only variants, or vanilla SD configs with reordered blocks.
Common situations: Pointing the loader at a vanilla Stable Diffusion 2 config or a community fine-tune with modified block types; version drift where config JSON keys were renamed and defaults fell back to a mismatched layout.
Related errors
- Hunyuan3D SD2.1 UNet requires four channel stages.
- Hunyuan3D SD2.1 UNet requires two ResNet layers and one tran
- Hunyuan3D SD2.1 checkpoints require linear projection.
- The Hunyuan3D SD2.1 UNet has no added conditioning.
- bad compress_ratio {compress_ratio}
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/7f8cb9d0224a0486.
Report an issue: GitHub.