{"record":{"id":"ae4708bd3cc8e86b","repo":"sgl-project/sglang","slug":"unexpected-rope-rank-cos-ndim","errorCode":null,"errorMessage":"Unexpected RoPE rank: {cos.ndim}","messagePattern":"Unexpected RoPE rank: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/sana_wm_refiner_transformer.py","lineNumber":79,"sourceCode":"        patch_size,\n        patch_size,\n    )\n    return (\n        tokens.permute(0, 4, 1, 5, 2, 6, 3, 7).flatten(6, 7).flatten(4, 5).flatten(2, 3)\n    )\n\n\ndef _slice_rope(\n    rope: tuple[torch.Tensor, torch.Tensor], start: int, end: Optional[int] = None\n) -> tuple[torch.Tensor, torch.Tensor]:\n    \"\"\"Slice along token axis for either interleaved (rank-3) or split (rank-4).\"\"\"\n    cos, sin = rope\n    end_ = end if end is not None else cos.shape[-2 if cos.ndim == 4 else 1]\n    if cos.ndim == 3:\n        return cos[:, start:end_], sin[:, start:end_]\n    if cos.ndim == 4:\n        return cos[:, :, start:end_, :], sin[:, :, start:end_, :]\n    raise ValueError(f\"Unexpected RoPE rank: {cos.ndim}\")\n\n\ndef _streaming_self_attention(\n    attn: LTX2Attention,\n    hidden_states: torch.Tensor,\n    video_rotary_emb: tuple[torch.Tensor, torch.Tensor],\n    n_context_tokens: int,\n) -> torch.Tensor:\n    \"\"\"Streaming SLA: context attends to context only, current attends to context+current.\n\n    Mirrors NVlabs `inference_sana_wm.py::_streaming_self_attention`.\n    \"\"\"\n    seq_len = hidden_states.shape[1]\n    if n_context_tokens <= 0 or n_context_tokens >= seq_len:\n        return attn(hidden_states, context=None, pe=video_rotary_emb)\n\n    ctx_rope = _slice_rope(video_rotary_emb, 0, n_context_tokens)\n    out_ctx = attn(","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/sana_wm_refiner_transformer.py#L61-L97","documentation":"_slice_rope accepts RoPE cos/sin of rank 3 (B, L, D) or rank 4 (B, H, L, D) and slices along the sequence axis. Any other rank (e.g. rank 2 plain (L, D)) raises this ValueError.","triggerScenarios":"Passing video_rotary_emb to the refiner's streaming self-attention where cos/sin are 2-D (L, D) — as produced by some RoPE helpers that omit batch/head dims — or a mistakenly unsqueezed 5-D tensor.","commonSituations":"Swapping in a different rotary embedding utility that returns unbatched tables; refiner fed RoPE computed for the base SANA-WM transformer with a different layout.","solutions":["Unsqueeze rank-2 tables to rank 3: cos[None], sin[None] (or broadcast to (B, L, D)) before passing","Use the RoPE helper expected by the refiner to build video_rotary_emb","Add an assert cos.ndim in (3, 4) at your call site"],"exampleFix":"# before\nrope = (cos, sin)  # each (L, D)\n# after\nrope = (cos.unsqueeze(0), sin.unsqueeze(0))  # (1, L, D)","handlingStrategy":"type-guard","validationCode":"assert cos.ndim in (3, 4) and sin.ndim == cos.ndim","typeGuard":"def valid_rope(rope) -> bool:\n    cos, sin = rope\n    return cos.ndim in (3, 4) and sin.ndim == cos.ndim and cos.shape[-2 if cos.ndim==4 else -2] == sin.shape[-2]","tryCatchPattern":null,"preventionTips":["Use the refiner's own RoPE builder; normalize rank-2 tables with unsqueeze(0)"],"tags":["sana-wm","rope","tensor-rank","refiner"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}