{"record":{"id":"b349949cbf153515","repo":"sgl-project/sglang","slug":"name-must-be-non-decreasing","errorCode":null,"errorMessage":"{name} must be non-decreasing","messagePattern":"(.+?) must be non-decreasing","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/layers/attention/backends/ascend_fa.py","lineNumber":49,"sourceCode":"        raise ValueError(f\"{name} must be a 1D int32 or int64 tensor\")\n    if cu_seqlens_host is not None and len(cu_seqlens_host) != cu_seqlens.numel():\n        raise ValueError(f\"{name} and its host copy must have the same length\")\n\n    boundaries = tuple(\n        int(value)\n        for value in (\n            cu_seqlens.tolist() if cu_seqlens_host is None else cu_seqlens_host\n        )\n    )\n    if len(boundaries) < 2 or boundaries[0] != 0:\n        raise ValueError(f\"{name} must start with 0 and contain at least one sequence\")\n    if boundaries[-1] != total_tokens:\n        raise ValueError(\n            f\"{name} must end at the packed token count {total_tokens}, \"\n            f\"got {boundaries[-1]}\"\n        )\n    if any(stop < start for start, stop in zip(boundaries[:-1], boundaries[1:])):\n        raise ValueError(f\"{name} must be non-decreasing\")\n    return boundaries\n\n\ndef fused_infer_attention_varlen(\n    q: torch.Tensor,\n    k: torch.Tensor,\n    v: torch.Tensor,\n    cu_seqlens_q: torch.Tensor,\n    cu_seqlens_k: torch.Tensor,\n    *,\n    cu_seqlens_q_host: Sequence[int] | None = None,\n    cu_seqlens_k_host: Sequence[int] | None = None,\n    softmax_scale: float | None = None,\n    return_softmax_lse: bool = False,\n) -> torch.Tensor | tuple[torch.Tensor, torch.Tensor]:\n    tensors = {\"q\": q, \"k\": k, \"v\": v}\n    invalid_layouts = [name for name, tensor in tensors.items() if tensor.ndim != 3]\n    if invalid_layouts:","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/layers/attention/backends/ascend_fa.py#L31-L67","documentation":"_packed_boundaries requires the cumulative boundary sequence to be non-decreasing (each stop >= start). Since cu_seqlens are cumulative sums of nonnegative lengths, any decrease indicates corrupted or misordered data — usually negative sequence lengths or a bad host copy.","triggerScenarios":"Passing cu_seqlens values that decrease anywhere, e.g. [0, 10, 7, 20], or a cu_seqlens_host list built with negative/garbage lengths (e.g. mismatched int parsing).","commonSituations":"Arithmetic bugs when computing boundaries manually instead of cumsum; a corrupted host copy from a previous batch; sign errors after rebase arithmetic.","solutions":["Always construct boundaries via torch.tensor(lens, dtype=torch.int32).cumsum(0) padded with a leading 0 rather than manual arithmetic","Validate lengths are nonnegative before cumsum: assert all(l >= 0 for l in lens)","If using cu_seqlens_host, verify it matches a freshly computed cumsum of the current lengths"],"exampleFix":"# before\ncu = torch.tensor([0, 10, 7, 20], dtype=torch.int32)  # decreases\n# after\nlens = [10, 0, 13]\ncu = torch.nn.functional.pad(torch.tensor(lens, dtype=torch.int32).cumsum(0), (1, 1), value=0)  # [0,10,10,23,23]... use [0]+cumsum","handlingStrategy":"validation","validationCode":"b = cu.tolist()\nassert all(b[i] <= b[i+1] for i in range(len(b)-1)), \"cu_seqlens must be non-decreasing\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build boundaries only via cumsum of nonnegative lengths","Sanity-check lengths >= 0 before cumsum"],"tags":["npu","ascend","varlen","packed-sequences","validation"],"backgroundTag":"malformed-cumulative-seqlens","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}