{"record":{"id":"121e92e0e2071707","repo":"sgl-project/sglang","slug":"unexpected-a-log-shape-a-log-shape-expected-nu","errorCode":null,"errorMessage":"Unexpected A_log shape: {A_log.shape}; expected numel={HV}","messagePattern":"Unexpected A_log shape: (.+?); expected numel=(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/cutedsl_kda.py","lineNumber":1347,"sourceCode":"        HV=HV,\n        use_initial_state=True,\n        use_qk_l2norm=True,\n        stream=stream,\n    )\n\n    _compiled_kernels[key] = compiled_kernel\n    logger.info(\n        \"CuTe DSL KDA kernel compiled: \"\n        f\"N={N}, H={H}, HV={HV}, K={K}, V={V}, pool_size={pool_size}, \"\n        f\"pool_strides={tuple(h0_source.stride())}, \"\n        f\"small_batch={use_small_batch}, varlen={is_varlen_decode}\"\n    )\n    return compiled_kernel\n\n\ndef _normalize_A_log(A_log: torch.Tensor, HV: int) -> torch.Tensor:\n    if A_log.numel() != HV:\n        raise ValueError(f\"Unexpected A_log shape: {A_log.shape}; expected numel={HV}\")\n    return A_log.reshape(HV).contiguous()\n\n\ndef _normalize_dt_bias(dt_bias: torch.Tensor, HV: int, K: int) -> torch.Tensor:\n    if dt_bias.numel() != HV * K:\n        raise ValueError(\n            f\"Unexpected dt_bias shape: {dt_bias.shape}; expected numel={HV * K}\"\n        )\n    return dt_bias.reshape(HV, K).contiguous()\n\n\ndef _normalize_kda_a(a, *, is_varlen_decode, N, HV, K):\n    \"\"\"Normalize `a` to match the compile-time shape expected by the kernel.\n\n    varlen kernel compiled shape: (N, HV, K)  -- 3D\n    dense kernel compiled shape:  (N, 1, HV, K) -- 4D\n    \"\"\"\n    if is_varlen_decode:","sourceCodeStart":1329,"sourceCodeEnd":1365,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/cutedsl_kda.py#L1329-L1365","documentation":"The KDA fused update helper _normalize_A_log requires the A_log gating parameter to contain exactly HV elements (one scalar per head) so it can be reshaped to (HV,). A mismatched element count raises ValueError with the expected numel.","triggerScenarios":"Calling cutedsl_fused_sigmoid_gating_kda_update with A_log whose numel != HV — e.g. per-head-per-key layout of shape (HV, K) from a checkpoint, or a scalar/expanded tensor when the model uses fused heads.","commonSituations":"Loading a KDA (Kimi Delta Attention) checkpoint whose A_log was stored with a different head layout (e.g. (num_kv_heads*K,) vs fused (HV,)); configuring the kernel with the wrong HV value (unfused vs fused head count) for the same weights.","solutions":["Set HV to match A_log.numel() if the weights are the source of truth (one gate per head)","If A_log has shape (HV, K) due to checkpoint layout, reduce over K or fix the loader so A_log is per-head","Verify with assert A_log.numel() == HV before calling the fused update"],"exampleFix":"# before: A_log shape (HV, K) -> HV*K elements -> ValueError\nupdate = cutedsl_fused_sigmoid_gating_kda_update(A_log, ...)\n# after\nassert A_log.numel() == HV\nupdate = cutedsl_fused_sigmoid_gating_kda_update(A_log.reshape(HV), ...)","handlingStrategy":"validation","validationCode":"assert A_log.numel() == HV, f'A_log numel {A_log.numel()} != HV {HV}'","typeGuard":"def is_valid_a_log(A_log, HV: int) -> bool:\n    return A_log.numel() == HV","tryCatchPattern":null,"preventionTips":["Validate A_log/dt_bias shapes once at model load","Keep a single source of truth for HV in config; never recompute it in multiple places"],"tags":["kda","linear-attention","shape-validation","cutedsl"],"backgroundTag":"tensor-shape-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}