{"record":{"id":"c859d5d34d7a716a","repo":"sgl-project/sglang","slug":"kda-dt-bias-must-be-a-contiguous-1d-or-2d-tensor","errorCode":null,"errorMessage":"KDA `dt_bias` must be a contiguous 1D or 2D tensor.","messagePattern":"KDA `dt_bias` must be a contiguous 1D or 2D tensor\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/helion/kda_replayssm.py","lineNumber":709,"sourceCode":"    ssm_state_indices: torch.Tensor,\n    write_pos: torch.Tensor,\n    force_flush: torch.Tensor | None = None,\n    use_qk_l2norm_in_kernel: bool = False,\n    lower_bound: float | None = None,\n) -> tuple[torch.Tensor, torch.Tensor]:\n    \"\"\"Run one buffered KDA decode step using caller-owned ReplaySSM state.\n\n    Allocates nothing persistent: the caller owns ``d_cache`` / ``k_cache`` /\n    ``g_cache`` and is responsible for advancing ``write_pos`` modulo the ring\n    length after a non-flush step and resetting it to zero after a natural or\n    forced flush. ``initial_state`` is both the checkpoint read (h0) and the\n    flush-only checkpoint write (ht), in place.\n    \"\"\"\n    batch = mixed_qkv.size(0)\n    if a.ndim not in (2, 3) or not a.is_contiguous():\n        raise ValueError(\"KDA `a` must be a contiguous 2D or 3D tensor.\")\n    if dt_bias.ndim not in (1, 2) or not dt_bias.is_contiguous():\n        raise ValueError(\"KDA `dt_bias` must be a contiguous 1D or 2D tensor.\")\n    flat_a = a.view(batch, -1)\n    flat_dt_bias = dt_bias.view(-1)\n    _, num_q_heads, num_v_heads, key_dim, value_dim = validate_packed_decode_inputs(\n        mixed_qkv,\n        flat_a,\n        b,\n        A_log,\n        flat_dt_bias,\n        initial_state,\n        out,\n        ssm_state_indices,\n    )\n\n    if write_pos.ndim != 1 or write_pos.dtype is not torch.int32:\n        raise ValueError(\"`write_pos` must be a 1D int32 tensor.\")\n    if write_pos.shape != (batch,):\n        raise ValueError(f\"`write_pos` must have shape {(batch,)}.\")\n    if force_flush is not None and (","sourceCodeStart":691,"sourceCodeEnd":727,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/helion/kda_replayssm.py#L691-L727","documentation":"The replayssm decode flattens dt_bias with dt_bias.view(-1) before validation, so dt_bias must be 1D or 2D and contiguous. Anything else (3D+, non-contiguous, or an expanded tensor) makes the view illegal, and this guard raises a descriptive error before that happens.","triggerScenarios":"Passing dt_bias stored as [HV, K] but made non-contiguous via slicing/transpose, or a 3D [1, HV, K] tensor, into helion_fused_recurrent_kda_replayssm_decode.","commonSituations":"Loading dt_bias from a checkpoint and slicing off a leading batch dim incorrectly; broadcasting dt_bias across time steps with expand; reusing a test helper that returns a non-contiguous tensor.","solutions":["Flatten and make contiguous: dt_bias = dt_bias.reshape(-1).contiguous()","Load dt_bias as [HV, K] and pass it directly, or squeeze() stray singleton dims","Verify numel == HV*K after flattening (the downstream validate will check)"],"exampleFix":"// before\ndt_bias = layer.dt_bias.unsqueeze(0).expand(T, -1, -1)  # 3D, expanded\n// after\ndt_bias = layer.dt_bias.reshape(-1).contiguous()  # [HV*K]","handlingStrategy":"validation","validationCode":"if dt_bias.ndim not in (1, 2) or not dt_bias.is_contiguous():\n    dt_bias = dt_bias.reshape(-1).contiguous()","typeGuard":"def valid_replay_dt_bias(t: torch.Tensor) -> bool:\n    return t.ndim in (1, 2) and t.is_contiguous()","tryCatchPattern":null,"preventionTips":["Flatten dt_bias once at model load and cache the flattened tensor","Don't expand parameters across time/batch dims"],"tags":["kda","replayssm","contiguity","parameter-shape"],"backgroundTag":"tensor-not-contiguous","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}