{"record":{"id":"10398a9c16e89d74","repo":"sgl-project/sglang","slug":"expected-x-shape-1-to-be-even-for-split-rotary","errorCode":null,"errorMessage":"Expected x.shape[-1] to be even for split rotary, got {last}.","messagePattern":"Expected x\\.shape\\[-1\\] to be even for split rotary, got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/adapter/ltx_2_connector.py","lineNumber":46,"sourceCode":"def apply_split_rotary_emb(\n    x: torch.Tensor, freqs: Tuple[torch.Tensor, torch.Tensor]\n) -> torch.Tensor:\n    cos, sin = freqs\n\n    x_dtype = x.dtype\n    needs_reshape = False\n    if x.ndim != 4 and cos.ndim == 4:\n        # cos is (#b, h, t, r) -> reshape x to (b, h, t, dim_per_head)\n        # The cos/sin batch dim may only be broadcastable, so take batch size from x\n        b = x.shape[0]\n        _, h, t, _ = cos.shape\n        x = x.reshape(b, t, h, -1).transpose(1, 2)\n        needs_reshape = True\n\n    # Split last dim (2*r) into (d=2, r)\n    last = x.shape[-1]\n    if last % 2 != 0:\n        raise ValueError(\n            f\"Expected x.shape[-1] to be even for split rotary, got {last}.\"\n        )\n    r = last // 2\n\n    # (..., 2, r)\n    split_x = x.reshape(*x.shape[:-1], 2, r)\n    first_x = split_x[..., :1, :]  # (..., 1, r)\n    second_x = split_x[..., 1:, :]  # (..., 1, r)\n\n    cos_u = cos.unsqueeze(-2)  # broadcast to (..., 1, r) against (..., 2, r)\n    sin_u = sin.unsqueeze(-2)\n\n    out = split_x * cos_u\n    first_out = out[..., :1, :]\n    second_out = out[..., 1:, :]\n\n    first_out.addcmul_(-sin_u, second_x)\n    second_out.addcmul_(sin_u, first_x)","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/adapter/ltx_2_connector.py#L28-L64","documentation":"ValueError from apply_split_rotary_emb: the 'split' rotary embedding variant requires the last dimension of x to be even so it can be reshaped into (2, r). An odd last dim means head_dim is odd, which is incompatible with split rotary.","triggerScenarios":"Calling the LTX-2 connector attention forward with rope_type='split' and a head_dim (x.shape[-1]) that is odd, e.g. head_dim=57 after projection.","commonSituations":"Loading an LTX-2 checkpoint with unusual head dims; manual model configs where dim_head is odd; accidental transpose/reshape upstream leaving an odd trailing dim.","solutions":["Use an even head_dim in the model config","Switch rope_type to 'interleaved' if the checkpoint supports it","Check upstream reshapes: ensure x is (b, h, t, head_dim) with even head_dim before this call"],"exampleFix":"// before\nattn = LTXConnector(..., dim_head=57, rope_type=\"split\")\n// after\nattn = LTXConnector(..., dim_head=64, rope_type=\"split\")","handlingStrategy":"validation","validationCode":"assert head_dim % 2 == 0, f\"split rope needs even head_dim, got {head_dim}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate head_dim even when configuring rope_type='split'","Fall back to 'interleaved' for odd head dims"],"tags":["rope","shape-validation","ltx-2"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}