sgl-project/sglang · error · TypeError

Unexpected SD2 mid block: {type(mid_block).__name__}.

Error message

Unexpected SD2 mid block: {type(mid_block).__name__}.

What it means

_replace_transformer_blocks walks the SD2 UNet expecting unet.mid_block to be a UNetMidBlock2DCrossAttn so it can patch its first attention block (layer 'mid_0_0'). If the mid block is any other type, this TypeError is raised before patching.

Source

Thrown at python/sglang/multimodal_gen/runtime/models/dits/hunyuan3d_paint.py:187

                f"Expected BasicTransformerBlock, got {type(transformer).__name__}."
            )
        model.transformer_blocks[0] = Hunyuan3DPaintTransformerBlock(
            transformer,
            layer_name,
            use_multiview_attention=use_multiview_attention,
            use_reference_attention=use_reference_attention,
            is_turbo=is_turbo,
        )

    for block_index, block in enumerate(unet.down_blocks):
        if not isinstance(block, CrossAttnDownBlock2D):
            continue
        for attention_index, attention in enumerate(block.attentions):
            replace(attention, f"down_{block_index}_{attention_index}_0")

    mid_block = unet.mid_block
    if not isinstance(mid_block, UNetMidBlock2DCrossAttn):
        raise TypeError(f"Unexpected SD2 mid block: {type(mid_block).__name__}.")
    replace(mid_block.attentions[0], "mid_0_0")

    for block_index, block in enumerate(unet.up_blocks):
        if not isinstance(block, CrossAttnUpBlock2D):
            continue
        for attention_index, attention in enumerate(block.attentions):
            replace(attention, f"up_{block_index}_{attention_index}_0")


@torch.no_grad()
def compute_voxel_grid_mask(
    position: torch.Tensor, grid_resolution: int = 8
) -> torch.Tensor:
    position = position.half()
    _, _, _, height, width = position.shape
    if height % grid_resolution != 0 or width % grid_resolution != 0:
        raise ValueError(
            f"Position map {height}x{width} is not divisible by {grid_resolution}."

View on GitHub (pinned to 0132848349)

Solutions

  1. Load the Stable Diffusion 2.x UNet this pipeline expects
  2. Pin the diffusers version listed in the repo requirements
  3. If using a custom UNet, add support for its mid-block type before calling this function

Example fix

# before
_replace_transformer_blocks(sd1_unet, ...)  # mid block type differs

# after
unet = UNet2DConditionModel.from_pretrained("stabilityai/stable-diffusion-2-1", subfolder="unet")
_replace_transformer_blocks(unet, ...)
Defensive patterns

Strategy: type-guard

Validate before calling

from diffusers.models.unets.unet_2d_blocks import UNetMidBlock2DCrossAttn
assert isinstance(unet.mid_block, UNetMidBlock2DCrossAttn), type(unet.mid_block).__name__

Type guard

def is_sd2_mid_block(unet) -> bool:
    from diffusers.models.unets.unet_2d_blocks import UNetMidBlock2DCrossAttn
    return isinstance(unet.mid_block, UNetMidBlock2DCrossAttn)

Prevention

When it happens

Trigger: Calling _replace_transformer_blocks on a UNet whose mid_block is not UNetMidBlock2DCrossAttn — e.g. a UNet with a different mid-block config, a custom architecture, or a non-SD2 checkpoint.

Common situations: Loading a SD1/SDXL or custom UNet into the Hunyuan3D Paint pipeline; diffusers version differences in mid-block classes.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/32818c411b7d2704. Report an issue: GitHub.