{"record":{"id":"3c0205854d2a2307","repo":"sgl-project/sglang","slug":"qwen-image-layered-requires-generated-latent-shape","errorCode":null,"errorMessage":"Qwen-Image-Layered requires generated latent shapes.","messagePattern":"Qwen-Image-Layered requires generated latent shapes\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/configs/pipeline_configs/qwen_image.py","lineNumber":822,"sourceCode":"        ).to(device=device)\n\n        cond_kwargs = {\n            \"txt_seq_lens\": txt_seq_lens,\n            \"img_shapes\": img_shapes,\n            \"freqs_cis\": (img_cache, txt_cache),\n            \"additional_t_cond\": torch.tensor([0], device=device, dtype=torch.long),\n            \"encoder_hidden_states_mask\": encoder_hidden_states_mask,\n        }\n        return cond_kwargs\n\n    def _unpad_and_unpack_latents(self, latents, batch):\n        channels = self.dit_config.arch_config.in_channels\n        batch_size = latents.shape[0]\n\n        img_shapes = batch.img_shapes\n        generated_shapes = img_shapes[0][:-1] if img_shapes and img_shapes[0] else []\n        if not generated_shapes:\n            raise ValueError(\"Qwen-Image-Layered requires generated latent shapes.\")\n        if len({tuple(shape) for shape in generated_shapes}) != 1:\n            raise ValueError(\n                \"Qwen-Image-Layered generated latent shapes must match, got \"\n                f\"{generated_shapes}.\"\n            )\n        layers = len(generated_shapes)\n        _, latent_height, latent_width = generated_shapes[0]\n        height = 2 * int(latent_height)\n        width = 2 * int(latent_width)\n\n        latents = maybe_unpad_latents(latents, batch)\n        latents = latents.view(\n            batch_size, layers, height // 2, width // 2, channels // 4, 2, 2\n        )\n        latents = latents.permute(0, 1, 4, 2, 5, 3, 6)\n\n        latents = latents.reshape(\n            batch_size, layers, channels // (2 * 2), height, width","sourceCodeStart":804,"sourceCodeEnd":840,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/configs/pipeline_configs/qwen_image.py#L804-L840","documentation":"The Qwen-Image-Layered variant needs the per-layer generated latent shapes from batch.img_shapes to unpad and unpack latents into layers. If img_shapes is empty or its first entry carries no generated shapes (only e.g. a final shape), _unpad_and_unpack_latents cannot proceed and raises.","triggerScenarios":"Running the layered pipeline on a batch where img_shapes was never populated or img_shapes[0][:-1] is empty — typically because a non-layered QwenImage path built the batch, or img_shapes was stripped/serialized incorrectly.","commonSituations":"Reusing a batch object constructed for plain QwenImage with the Layered config; downstream code (scheduler, serialization) dropping the nested img_shapes field; calling post_denoising_loop manually without going through prepare_latents that records shapes.","solutions":["Use the Qwen-Image-Layered pipeline end-to-end so prepare/encode steps populate batch.img_shapes with per-layer generated shapes","Verify batch.img_shapes is a non-empty nested list where each entry has [generated_shape..., final_shape]; fix serialization if it flattens it","Rebuild the batch via the layered pipeline's prep path before post_denoising_loop"],"exampleFix":"# before\nlatents = pipe.post_denoising_loop(batch_without_img_shapes)\n\n# after\nbatch = pipe.prepare_batch(...)  # layered pipeline populates batch.img_shapes\nlatents = pipe.post_denoising_loop(batch)","handlingStrategy":"validation","validationCode":"shapes = batch.img_shapes[0][:-1] if batch.img_shapes and batch.img_shapes[0] else []\nassert shapes, \"Layered pipeline requires populated batch.img_shapes with per-layer generated shapes\"","typeGuard":"def is_layered_batch(batch) -> bool:\n    return bool(batch.img_shapes) and len(batch.img_shapes[0]) > 1","tryCatchPattern":null,"preventionTips":["Always build batches through the Layered pipeline's prepare path","Assert img_shapes is populated before post_denoising_loop","Verify serialization round-trips the nested img_shapes structure"],"tags":["qwen-image","layered-generation","latent-shapes","missing-metadata"],"backgroundTag":"missing-required-metadata","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}