{"record":{"id":"16ba9373071a2f7a","repo":"sgl-project/sglang","slug":"expected-v-g-shape-expected-shape","errorCode":null,"errorMessage":"expected v/g shape {expected_shape}","messagePattern":"expected v/g shape (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/kimi_k3/kda_decode_mtp.py","lineNumber":989,"sourceCode":"    ReplaySSM: passing the four replayssm_* rings switches the kernel to\n    CACHE_RING mode — per-step raw inputs go to the rings (consumed by the\n    commit-time exact fold, see kda_replayssm_spec_decode.py) and the per-step\n    intermediate_ssm state snapshots are skipped, so intermediate_ssm may be\n    None.\n\n    Passing all three onorm_* arguments fuses gated RMSNorm into the recurrence\n    kernel.\n    \"\"\"\n    import torch\n\n    H = x_q.shape[2]\n    N = cu_seqlens.numel() - 1\n    T = x_q.shape[1]\n    expected_shape = (1, T, H, TILE_K)\n    if tuple(x_q.shape) != expected_shape or tuple(x_k.shape) != expected_shape:\n        raise ValueError(f\"expected q/k shape {expected_shape}\")\n    if tuple(x_v.shape) != expected_shape or tuple(g.shape) != expected_shape:\n        raise ValueError(f\"expected v/g shape {expected_shape}\")\n    if tuple(beta.shape) != (1, T, H):\n        raise ValueError(f\"expected beta shape {(1, T, H)}\")\n    # T // N == 1 is num_spec == 0: one token per request, i.e. a plain decode\n    # step. The backend never dispatches here for it (that is the dedicated\n    # decode kernel's job), but the layout is legal and benchmarks compare the\n    # two at this point, so the wrapper accepts it.\n    if N <= 0 or T % N != 0 or T // N < 1:\n        raise ValueError(\n            f\"DSpARK KDA MTP requires a fixed 1 + num_spec dense tokens per \"\n            f\"request; got T={T}, N={N}\"\n        )\n    num_spec = T // N - 1\n    if recurrent_state.shape[1:] != (H, TILE_K, TILE_K):\n        raise ValueError(\"expected recurrent state layout [pool, H, V=128, K=128]\")\n    if (\n        recurrent_state.dtype != torch.float32\n        or tuple(recurrent_state.stride()[-3:]) != (TILE_K * TILE_K, TILE_K, 1)\n        or recurrent_state.stride(0) % 4 != 0","sourceCodeStart":971,"sourceCodeEnd":1007,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/kimi_k3/kda_decode_mtp.py#L971-L1007","documentation":"Same dense-layout contract as q/k: the DSpARK KDA MTP kernel requires v and the DSpARK gate g to be [1, T, H, TILE_K] tensors. This check fires when v or g violates that layout (wrong batch dim, token dim, heads, or head dim != 128).","triggerScenarios":"Passing x_v or g shaped [T, H, D], [B, T, H, D] with B != 1, or with head dim != 128 to fused_kda_decode_mtp_dspark.","commonSituations":"Gate tensor g produced with a squeezed/unsqueezed dim compared to v; head_dim-64 model variants; mismatched reshape between q/k path and v/g path in a custom MTP wrapper.","solutions":["Reshape both x_v and g to [1, T, H, 128] to match q/k","Check that g (the DSpARK gate) has the same [H, 128] trailing dims as v, not a scalar-per-head layout","Confirm head dim is 128 or use the generic backend"],"exampleFix":"# before\nv = v.view(T, H, 128); g = g.view(T, H, 128)\nfused_kda_decode_mtp_dspark(q, k, v, g, ...)\n# after\nv = v.view(1, T, H, 128); g = g.view(1, T, H, 128)\nfused_kda_decode_mtp_dspark(q, k, v, g, ...)","handlingStrategy":"validation","validationCode":"assert x_v.shape == (1, T, H, 128) and g.shape == (1, T, H, 128)","typeGuard":"def is_dspark_vg(x: torch.Tensor, T: int, H: int) -> bool:\n    return tuple(x.shape) == (1, T, H, 128)","tryCatchPattern":null,"preventionTips":["Reuse the same reshape helper for v and g as for q/k","Never broadcast the gate g against v — materialize full [H,128] g","Test with a synthetic MTP batch asserting all four tensor shapes"],"tags":["kda","mtp","shape-validation","dspark"],"backgroundTag":"invalid-shape-argument","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}