{"record":{"id":"bf6412564fa65ee3","repo":"sgl-project/sglang","slug":"v-shape-must-match-k-shape-got-v-shape-vs-k-sh","errorCode":null,"errorMessage":"v shape must match k shape, got {v.shape} vs {k.shape}","messagePattern":"v shape must match k shape, got (.+?) vs (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/aot/python/sgl_kernel/metal.py","lineNumber":86,"sourceCode":"        raise ValueError(\"rope_pool_fused expects pool tensors to be 3-D\")\n    q_shape = tuple(q.shape)\n    k_shape = tuple(k.shape)\n    v_shape = tuple(v.shape)\n    positions_shape = tuple(positions.shape)\n    slots_shape = tuple(slots.shape)\n    k_pool_shape = tuple(k_pool.shape)\n    v_pool_shape = tuple(v_pool.shape)\n\n    if q_shape != (q_shape[0], num_qo_heads, head_dim):\n        raise ValueError(\n            \"q shape must be [num_tokens, num_qo_heads, head_dim], \" f\"got {q.shape}\"\n        )\n    if k_shape != (q_shape[0], num_kv_heads, head_dim):\n        raise ValueError(\n            \"k shape must be [num_tokens, num_kv_heads, head_dim], \" f\"got {k.shape}\"\n        )\n    if v_shape != k_shape:\n        raise ValueError(f\"v shape must match k shape, got {v.shape} vs {k.shape}\")\n    if positions_shape != (q_shape[0],) or slots_shape != (q_shape[0],):\n        raise ValueError(\"positions/slots must have one entry per token\")\n    if k_pool_shape[1:] != (num_kv_heads, head_dim):\n        raise ValueError(f\"k_pool has incompatible shape {k_pool.shape}\")\n    if v_pool_shape != k_pool_shape:\n        raise ValueError(\n            f\"v_pool shape must match k_pool shape, got {v_pool.shape} vs {k_pool.shape}\"\n        )\n    if q.dtype != k.dtype or q.dtype != v.dtype:\n        raise ValueError(\"q/k/v dtypes must match\")\n    if k_pool.dtype != q.dtype or v_pool.dtype != q.dtype:\n        raise ValueError(\"pool dtypes must match q/k/v dtype\")\n\n    return _metal.rope_pool_fused(\n        q,\n        k,\n        v,\n        positions,","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/aot/python/sgl_kernel/metal.py#L68-L104","documentation":"rope_pool_fused requires v to have exactly the same shape as k ([num_tokens, num_kv_heads, head_dim]). This error fires when v's shape differs from k, meaning the K and V projections are inconsistent for this call.","triggerScenarios":"Passing v with a different token count, head count, or head_dim than k; passing a v sliced differently from k; misconfigured projection producing mismatched K/V widths.","commonSituations":"Splitting a fused QKV projection with wrong slice boundaries so V gets a different width than K; partial slicing during chunked prefill where v was sliced but k was not; copy-paste of shapes from a different layer.","solutions":["Assert v.shape == k.shape before the call and reshape/slice v to match k","Fix QKV split indices: k = qkv[..., q_size:q_size+kv_size].reshape(...); v = qkv[..., q_size+kv_size:].reshape(...) with identical kv sizes","Log both shapes to find which dimension diverges"],"exampleFix":"# before\nk = qkv[:, :kv_size].view(N, kv_heads, D)\nv = qkv[:, kv_size:].view(N, kv_heads, D)  # off-by-one slice -> wrong token/head count\n\n# after\nk = qkv[..., q_size:q_size+kv_size].reshape(N, kv_heads, D)\nv = qkv[..., q_size+kv_size:].reshape(N, kv_heads, D)\nassert v.shape == k.shape","handlingStrategy":"validation","validationCode":"assert v.shape == k.shape, (v.shape, k.shape)","typeGuard":"def kv_same_shape(k, v) -> bool:\n    return k.shape == v.shape","tryCatchPattern":null,"preventionTips":["Split fused QKV projections with verified slice boundaries","Add an assert v.shape == k.shape right after splitting"],"tags":["shape-validation","rope","kv-projection","metal","sgl-kernel"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}