{"record":{"id":"4a16abbd29f0b0ed","repo":"sgl-project/sglang","slug":"subblock-sparse-query-block-mask-must-be-a-tensor","errorCode":null,"errorMessage":"subblock_sparse_query_block_mask must be a tensor","messagePattern":"subblock_sparse_query_block_mask must be a tensor","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py","lineNumber":2455,"sourceCode":"        )\n\n        if x.dim() != 3 or x.shape[0] != 1:\n            raise ValueError(f\"x must be [1, S, C], got {list(x.shape)}\")\n        seq_len = int(x.shape[1])\n        if token_tags is not None and token_tags.shape[0] != seq_len:\n            raise ValueError(\n                \"token_tags must cover the full packed sequence \"\n                f\"({seq_len}), got {token_tags.shape[0]}.\"\n            )\n        if inverse_indices.shape[0] != seq_len:\n            raise ValueError(\n                f\"inverse_indices must be [{seq_len}], got {list(inverse_indices.shape)}\"\n            )\n        device = x.device\n        if subblock_sparse_query_block_mask is not None and not isinstance(\n            subblock_sparse_query_block_mask, torch.Tensor\n        ):\n            raise ValueError(\"subblock_sparse_query_block_mask must be a tensor\")\n        self._resolve_attention_backend_once()\n\n        # Row split is 2D: ring first (an outer, contiguous ring_chunk_len\n        # slice of the packed sequence), Ulysses second (an inner slice\n        # within this rank's ring chunk). Only Ulysses shards heads inside\n        # attention -- ring instead ring-rotates each rank's local KV chunk\n        # and online-softmax merges partial outputs (see\n        # _minimax_h3_attention_core_impl), so it has no head constraint.\n        ulysses_ws, ulysses_rank = get_ulysses_ctx()\n        ring_ws, ring_rank = get_ring_ctx()\n        sp_ws = ulysses_ws * ring_ws\n        local_seq_len = seq_len\n        if sp_ws > 1:\n            if seq_len % sp_ws:\n                raise ValueError(\n                    f\"packed seq_len {seq_len} not divisible by the combined \"\n                    f\"sequence-parallel world size {sp_ws} \"\n                    f\"(ulysses={ulysses_ws} x ring={ring_ws})\"","sourceCodeStart":2437,"sourceCodeEnd":2473,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py#L2437-L2473","documentation":"subblock_sparse_query_block_mask, when not None, must be a torch.Tensor — the downstream block-sparse attention API consumes tensor masks only. Passing e.g. a numpy array, list, or a BlockMask object raises this.","triggerScenarios":"Providing a numpy ndarray, nested list, or a flash-attention BlockMask-style object where a dense tensor query block mask is expected.","commonSituations":"Adapting masks produced by another attention library (nested lists from Python scheduling code, numpy from preprocessing) without converting to torch.","solutions":["Convert with torch.as_tensor(mask, device=x.device) before passing","Or pass None if no subblock sparse query mask is needed for this task"],"exampleFix":"// before\nmodel(x=packed, subblock_sparse_query_block_mask=np_mask, ...)\n// after\nmodel(x=packed, subblock_sparse_query_block_mask=torch.as_tensor(np_mask, device=packed.device), ...)","handlingStrategy":"type-guard","validationCode":"if subblock_sparse_query_block_mask is not None:\n    subblock_sparse_query_block_mask = torch.as_tensor(subblock_sparse_query_block_mask, device=x.device)","typeGuard":"def is_tensor_mask(m) -> bool:\n    return m is None or torch.is_tensor(m)","tryCatchPattern":null,"preventionTips":["Convert numpy/list masks to torch at the boundary","Keep mask dtypes/devices aligned with x"],"tags":["minimax-h3","sparse-attention","type-validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}