{"record":{"id":"09a43ccdf753ab34","repo":"sgl-project/sglang","slug":"invalid-packed-mixed-qkv-last-dim-qkv-dim-for-09a43c","errorCode":null,"errorMessage":"Invalid packed `mixed_qkv` last dim={qkv_dim} for HV={HV}, V={V}.","messagePattern":"Invalid packed `mixed_qkv` last dim=(.+?) for HV=(.+?), V=(.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/helion/kda_decode.py","lineNumber":315,"sourceCode":"    if b.shape[1] != HV:\n        raise ValueError(\n            f\"`b` must have shape [B, HV] with HV={HV} (got b.shape={tuple(b.shape)}).\"\n        )\n    if A_log.numel() != HV:\n        raise ValueError(f\"`A_log` must have {HV} elements (got {A_log.numel()}).\")\n    if dt_bias.numel() != HV * K:\n        raise ValueError(\n            f\"`dt_bias` must have {HV * K} elements (got {dt_bias.numel()}).\"\n        )\n    if out.shape != (B, 1, HV, V):\n        raise ValueError(\n            f\"`out` must have shape {(B, 1, HV, V)} (got out.shape={tuple(out.shape)}).\"\n        )\n\n    qkv_dim = mixed_qkv.shape[1]\n    qk_dim = qkv_dim - HV * V\n    if qk_dim <= 0 or qk_dim % 2 != 0:\n        raise ValueError(\n            f\"Invalid packed `mixed_qkv` last dim={qkv_dim} for HV={HV}, V={V}.\"\n        )\n    q_dim = qk_dim // 2\n    if q_dim % K != 0:\n        raise ValueError(\n            f\"Invalid packed Q size {q_dim}: must be divisible by K={K}. \"\n            \"KDA packed decode requires num_q_heads == num_k_heads and \"\n            \"head_q_dim == head_k_dim.\"\n        )\n    H = q_dim // K\n    if H <= 0 or HV % H != 0:\n        raise ValueError(\n            f\"Invalid head config inferred from mixed_qkv: H={H}, HV={HV}.\"\n        )\n    return B, H, HV, K, V\n\n\ndef helion_fused_recurrent_kda_packed_decode(","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/helion/kda_decode.py#L297-L333","documentation":"mixed_qkv packs query, key and value projections along dim 1. After subtracting the value part (HV*V), the remaining qk width must be positive and even (Q and K equal width). validate_packed_decode_inputs raises when the remaining width is <= 0 or odd, meaning the packed layout is not the expected [q | k | v] split.","triggerScenarios":"Passing mixed_qkv containing only q and v (no k), a qkv fused tensor with Q and K of different widths, or a tensor whose dim 1 includes an extra gate segment.","commonSituations":"Model projects q/k/v with head_q_dim != head_k_dim; a fused qkv linear whose output width was changed but the kernel expectation wasn't; feeding the wrong projection output into the fused decode.","solutions":["Verify mixed_qkv.shape[1] == 2*num_q_heads*head_k_dim + num_v_heads*head_v_dim","Ensure the qkv projection orders segments as [Q, K, V] with Q and K of equal total width","If head_q_dim != head_k_dim, this packed kernel cannot be used — fall back to the unpacked path"],"exampleFix":"// before\nqkv = self.qkv_proj(x)  # widths Q=2K... mismatched\n// after\nassert qkv.shape[1] == 2*H*K + HV*V\nqkv = self.qkv_proj(x)","handlingStrategy":"validation","validationCode":"HV, V = initial_state.shape[-3], initial_state.shape[-2]\nqkv_dim = mixed_qkv.shape[1]\nassert qkv_dim > HV * V and (qkv_dim - HV * V) % 2 == 0, qkv_dim","typeGuard":"def valid_packed_qkv(qkv: torch.Tensor, hv: int, v: int) -> bool:\n    rest = qkv.shape[1] - hv * v\n    return rest > 0 and rest % 2 == 0","tryCatchPattern":null,"preventionTips":["Assert the projection width formula 2*H*K + HV*V in model __init__","Keep qkv segment order fixed as [Q, K, V]"],"tags":["kda","helion","packed-layout","qkv","shape-validation"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}