{"record":{"id":"d2a1e9415d5eb445","repo":"sgl-project/sglang","slug":"block-sparse-tensors-context-require-explicit-spa","errorCode":null,"errorMessage":"Block sparse tensors{context} require explicit sparse_block_size[0] to disambiguate block size for seqlen_q={seqlen_q} and num_m_blocks={num_m_blocks}.","messagePattern":"Block sparse tensors(.+?) require explicit sparse_block_size\\[0\\] to disambiguate block size for seqlen_q=(.+?) and num_m_blocks=(.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py","lineNumber":348,"sourceCode":"    \"\"\"\n    base_m_block = q_stage * m_block_size\n    base_n_block = n_block_size\n    if sparse_block_size_kv is None:\n        sparse_block_size_kv = base_n_block\n    if sparse_block_size_kv != base_n_block:\n        raise ValueError(\n            f\"Block sparse tensors{context} require BLOCK_SIZE_KV={base_n_block}.\"\n        )\n    if tensors.mask_block_idx is None:\n        raise ValueError(\n            \"mask_block_cnt and mask_block_idx must be provided for block sparsity.\"\n        )\n    num_m_blocks = tensors.mask_block_idx.shape[2]\n\n    if sparse_block_size_q is None:\n        sparse_block_size_q = get_sparse_q_block_size(tensors, seqlen_q)\n        if sparse_block_size_q is None and base_m_block != 1:\n            raise ValueError(\n                f\"Block sparse tensors{context} require explicit sparse_block_size[0] \"\n                f\"to disambiguate block size for seqlen_q={seqlen_q} and num_m_blocks={num_m_blocks}.\"\n            )\n        if sparse_block_size_q is None:\n            sparse_block_size_q = ceildiv(seqlen_q, num_m_blocks)\n\n    if sparse_block_size_q % base_m_block != 0:\n        raise ValueError(\n            f\"Block sparse tensors{context} have block size {sparse_block_size_q}, \"\n            f\"which must be a multiple of {base_m_block}.\"\n        )\n\n    expected_m_blocks = ceildiv(seqlen_q, sparse_block_size_q)\n    expected_n_blocks = ceildiv(seqlen_k, sparse_block_size_kv)\n    q_subtile_factor = sparse_block_size_q // base_m_block\n    expected_count_shape = (batch_size, num_head, expected_m_blocks)\n    expected_index_shape = (batch_size, num_head, expected_m_blocks, expected_n_blocks)\n","sourceCodeStart":330,"sourceCodeEnd":366,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py#L330-L366","documentation":"Raised when sparse_block_size_q cannot be inferred: seqlen_q is divisible such that multiple q-block sizes could produce the observed num_m_blocks, and base_m_block != 1, so the layout is ambiguous. The user must pass sparse_block_size[0] explicitly.","triggerScenarios":"Calling normalize_block_sparse_config without sparse_block_size_q, with seqlen_q that doesn't unambiguously map to num_m_blocks (e.g. seqlen_q=4096, num_m_blocks=32 could be q-block 128) and kernel q_stage*m_block_size != 1.","commonSituations":"Dynamically-shaped workloads where seqlen_q varies and the block size was only implied by the mask construction.","solutions":["Pass sparse_block_size=(sparse_block_size_q, kv_size) explicitly to the op/normalize call","Rebuild the BlockMask recording its q block size so it can be supplied later"],"exampleFix":"// before\nout = fa(q, k, v, block_sparse_tensors=tensors)\n// after\nout = fa(q, k, v, block_sparse_tensors=tensors, sparse_block_size=(128, 128))","handlingStrategy":"validation","validationCode":"if seqlen_q % num_m_blocks == 0 and base_m_block != 1 and sparse_block_size_q is None:\n    sparse_block_size_q = seqlen_q // num_m_blocks  # pass explicitly","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass sparse_block_size explicitly when seqlen_q can vary","Store the mask's q block size alongside the tensors"],"tags":["block-sparse","ambiguous-config","shape-inference"],"backgroundTag":"ambiguous-configuration","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}