sgl-project/sglang · error · TypeError
Expected BasicTransformerBlock, got {type(transformer).__nam
Error message
Expected BasicTransformerBlock, got {type(transformer).__name__}. What it means
During _replace_transformer_blocks, the replace() helper expects the first transformer block of each attention module to be a diffusers BasicTransformerBlock so it can wrap it into a Hunyuan3DPaintTransformerBlock. If the checkpoint/module already uses a different block type, a TypeError is raised.
Source
Thrown at python/sglang/multimodal_gen/runtime/models/dits/hunyuan3d_paint.py:168
encoder_hidden_states=encoder_hidden_states,
attention_mask=encoder_attention_mask,
)
return hidden_states + self.transformer.ff(
self.transformer.norm3(hidden_states)
)
def _replace_transformer_blocks(
unet: StableDiffusionUNet2DConditionModel,
*,
use_multiview_attention: bool,
use_reference_attention: bool,
is_turbo: bool,
) -> None:
def replace(model: Transformer2DModel, layer_name: str) -> None:
transformer = model.transformer_blocks[0]
if not isinstance(transformer, BasicTransformerBlock):
raise TypeError(
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):View on GitHub (pinned to 0132848349)
Solutions
- Use the diffusers version this code was developed against (check the repo's requirements/pin)
- Make sure you call _replace_transformer_blocks only once per UNet
- Verify you are loading the expected SD2.x UNet architecture, not a custom variant
Example fix
# before
_replace_transformer_blocks(custom_unet, ...) # custom blocks
# 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.transformers.transformer_2d import BasicTransformerBlock assert isinstance(model.transformer_blocks[0], BasicTransformerBlock), type(model.transformer_blocks[0])
Type guard
def is_basic_transformer_block(model) -> bool:
from diffusers.models.transformers.transformer_2d import BasicTransformerBlock
return isinstance(model.transformer_blocks[0], BasicTransformerBlock) Prevention
- Pin the diffusers version from the repo requirements
- Replace blocks once, then mark the model (e.g. attribute flag) to prevent double replacement
- Add an isinstance smoke check before running the full pipeline
When it happens
Trigger: Calling _replace_transformer_blocks on a UNet whose attentions' transformer_blocks[0] is not BasicTransformerBlock — e.g. a custom/different diffusers version's block class, an already-replaced block, or a non-SD2 UNet.
Common situations: diffusers version drift changing the block class; running the replacement twice on the same UNet; using a UNet architecture other than the expected Stable Diffusion 2.x one.
Related errors
- Unexpected SD2 mid block: {type(mid_block).__name__}.
- Unsupported type {type(data)}
- All tensors must have the same data type
- Z-Image transformer has no `rotary_emb`. It likely loaded vi
- Model path '{model_path}' is already registered for pipeline
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/978ae3901c65462e.
Report an issue: GitHub.