{"record":{"id":"5a60024a8a99b357","repo":"sgl-project/sglang","slug":"hunyuan3d-paint-expects-square-latents-and-a-match","errorCode":null,"errorMessage":"Hunyuan3D Paint expects square latents and a matching view count.","messagePattern":"Hunyuan3D Paint expects square latents and a matching view count\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/hunyuan3d_paint.py","lineNumber":330,"sourceCode":"        normal_imgs: torch.Tensor | None = None,\n        position_imgs: torch.Tensor | None = None,\n        camera_info_gen: torch.Tensor,\n        camera_info_ref: torch.Tensor,\n        ref_scale: float | torch.Tensor = 1.0,\n        mva_scale: float | torch.Tensor = 1.0,\n        position_attn_mask: dict[int, torch.Tensor] | None = None,\n        timestep_cond: torch.Tensor | None = None,\n        cross_attention_kwargs: dict[str, Any] | None = None,\n        added_cond_kwargs: dict[str, torch.Tensor] | None = None,\n        return_dict: bool = True,\n    ) -> StableDiffusionUNetOutput | tuple[torch.Tensor]:\n        if timestep_cond is not None or cross_attention_kwargs is not None:\n            raise ValueError(\"Hunyuan3D Paint does not use extra UNet conditioning.\")\n        if added_cond_kwargs is not None:\n            raise ValueError(\"Hunyuan3D Paint does not use added conditioning.\")\n        batch_size, num_generated, _, height, width = sample.shape\n        if height != width or num_generated != num_in_batch:\n            raise ValueError(\n                \"Hunyuan3D Paint expects square latents and a matching view count.\"\n            )\n\n        camera_gen = rearrange(\n            camera_info_gen + self.max_num_ref_images, \"b n -> (b n)\"\n        )\n        inputs = [sample]\n        if normal_imgs is not None:\n            inputs.append(normal_imgs)\n        if position_imgs is not None:\n            inputs.append(position_imgs)\n        sample = rearrange(torch.cat(inputs, dim=2), \"b n c h w -> (b n) c h w\")\n        encoder_gen = encoder_hidden_states.unsqueeze(1).repeat(1, num_generated, 1, 1)\n        encoder_gen = rearrange(encoder_gen, \"b n l c -> (b n) l c\")\n\n        if not condition_embed_dict:\n            num_reference = ref_latents.shape[1]\n            camera_ref = rearrange(camera_info_ref, \"b n -> (b n)\")","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/hunyuan3d_paint.py#L312-L348","documentation":"The paint UNet requires square spatial latents (height == width) and that sample.shape[1] (num_generated views) equals the num_in_batch the model/pipeline was configured with, because multiview/reference attention rearranges '(b n) l c' tensors using that count. A mismatch raises this ValueError early in forward.","triggerScenarios":"Passing non-square latents (e.g. 64x48) or a sample whose view dimension differs from num_in_batch (e.g. batch of 6 views while num_in_batch=4).","commonSituations":"Generating a non-square canvas; changing the number of generated views without updating the pipeline's num_in_batch; reshaping latents incorrectly before the denoising loop.","solutions":["Make the latent height equal to width (square generation)","Ensure sample's view count equals num_in_batch (both the tensor layout and the pipeline setting)","Regenerate latents with the pipeline's own prepare_latents so shapes stay consistent"],"exampleFix":"# before\nsample = torch.randn(b, 6, 4, 64, 48)  # 6 views, num_in_batch=4, non-square\n\n# after\nsample = torch.randn(b, 4, 4, 64, 64)  # 4 views, square latents","handlingStrategy":"validation","validationCode":"b, n, _, h, w = sample.shape\nassert h == w and n == num_in_batch, f'{h}x{w} with {n} views vs num_in_batch={num_in_batch}'","typeGuard":"def latents_valid(sample: torch.Tensor, num_in_batch: int) -> bool:\n    _, n, _, h, w = sample.shape\n    return h == w and n == num_in_batch","tryCatchPattern":null,"preventionTips":["Generate square latents via the pipeline's prepare_latents","Keep the view-count config and the latent batch layout derived from one variable","Validate shapes once before the denoising loop"],"tags":["runtime","shape-mismatch","multiview","diffusion"],"backgroundTag":"latent-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}