{"record":{"id":"ee92e9312f85c763","repo":"sgl-project/sglang","slug":"z-image-text-embeddings-must-have-shape-seq-dim","errorCode":null,"errorMessage":"Z-Image text embeddings must have shape [seq, dim] or [batch, seq, dim]","messagePattern":"Z-Image text embeddings must have shape \\[seq, dim\\] or \\[batch, seq, dim\\]","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/configs/pipeline_configs/zimage.py","lineNumber":232,"sourceCode":"    def _split_text_embeds_for_dit(self, batch, *, negative: bool = False):\n        \"\"\"Return per-request text tensors, trimming padded batched embeddings.\"\"\"\n        embeds = batch.negative_prompt_embeds if negative else batch.prompt_embeds\n        if embeds is None:\n            return None\n\n        if isinstance(embeds, (list, tuple)):\n            if not embeds:\n                return []\n            embeds = embeds[0]\n\n        if not torch.is_tensor(embeds):\n            return embeds\n\n        if embeds.ndim == 2:\n            return [self._pad_text_embed_for_dit(embeds)]\n\n        if embeds.ndim != 3:\n            raise ValueError(\n                \"Z-Image text embeddings must have shape [seq, dim] or [batch, seq, dim]\"\n            )\n\n        seq_lens = self.require_text_seq_lens(\n            batch,\n            0,\n            negative=negative,\n            expected_batch_size=int(embeds.shape[0]),\n        )\n        return [\n            self._pad_text_embed_for_dit(embeds[idx, :seq_len].contiguous())\n            for idx, seq_len in enumerate(seq_lens)\n        ]\n\n    def _caption_rope_length(self, prompt_embeds, batch, *, negative: bool = False):\n        \"\"\"Return the shared caption RoPE length for current text embeddings.\"\"\"\n        if torch.is_tensor(prompt_embeds):\n            if prompt_embeds.ndim == 2:","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/configs/pipeline_configs/zimage.py#L214-L250","documentation":"Z-Image pipeline conditioning code accepts text embeddings only as a 2-D [seq, dim] tensor or a 3-D [batch, seq, dim] tensor. The splitter _split_text_embeds_for_dit raises this when embeds.ndim is neither 2 nor 3, i.e. the tensor coming from the text encoder has an unexpected rank (1-D, 4-D, etc.).","triggerScenarios":"Calling get_pos_prompt_embeds(batch) or get_neg_prompt_embeds(batch) on the Z-Image pipeline config when the text encoder returned embeddings with ndim not in (2, 3) — e.g. a pooled [batch, dim] vector, a 1-D [dim] tensor, or a 4-D tensor from a custom encoder wrapper.","commonSituations":"Swapping in a custom text encoder or encoder wrapper that squeezes/unsqueezes dims incorrectly; passing pooled prompt embeddings instead of sequence embeddings; upstream changes in the multimodal encoder output shape after a version bump.","solutions":["Check the tensor shape fed to the pipeline: print text_embeds.shape before calling; ensure it is [seq, dim] (single prompt) or [batch, seq, dim] (batched)","If your encoder returns [batch, dim] pooled output, re-export per-token sequence embeddings instead — pooled vectors are not supported here","If you have [batch*seq, dim] flattened output, reshape to [batch, seq, dim] before passing it in","Add an assertion/reshape in your encoder wrapper: embeds = embeds.reshape(-1, embeds.shape[-1]) for 2-D or embeds[:, None, :] style fix depending on your data"],"exampleFix":"# before\nembeds = text_encoder(prompt)  # returns [batch, dim] pooled -> ValueError\npipe.get_pos_prompt_embeds(batch)\n\n# after\nembeds = text_encoder(prompt)          # [seq, dim] or [batch, seq, dim]\nassert embeds.ndim in (2, 3), embeds.shape\npipe.get_pos_prompt_embeds(batch)","handlingStrategy":"validation","validationCode":"embeds = get_text_embeds(...)\nassert embeds.ndim in (2, 3), f\"expected [seq, dim] or [batch, seq, dim], got {embeds.shape}\"\nif embeds.ndim == 1:\n    embeds = embeds.unsqueeze(0)  # [dim] -> [1, dim] only if that is semantically a 1-token seq","typeGuard":"def is_valid_text_embeds(t) -> bool:\n    return hasattr(t, \"ndim\") and t.ndim in (2, 3)","tryCatchPattern":null,"preventionTips":["Always assert embeds.ndim in (2,3) right after the text encoder call","Never pass pooled [batch, dim] encoder outputs to Z-Image conditioning","Add shape logging in encoder wrappers to catch rank changes early"],"tags":["z-image","multimodal","tensor-shape","text-embeddings","validation"],"backgroundTag":"invalid-tensor-shape","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}