{"record":{"id":"0d90fe5556cddf5b","repo":"sgl-project/sglang","slug":"block-sparse-tensors-context-require-block-size-k","errorCode":null,"errorMessage":"Block sparse tensors{context} require BLOCK_SIZE_KV={base_n_block}.","messagePattern":"Block sparse tensors(.+?) require BLOCK_SIZE_KV=(.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py","lineNumber":336,"sourceCode":"    sparse_block_size_q: int | None = None,\n    sparse_block_size_kv: int | None = None,\n) -> Tuple[Tuple[int, int, int], Tuple[int, int, int, int], int]:\n    \"\"\"Infer shapes and scaling for block-sparse tensors.\n\n    Expectations:\n    - mask_block_cnt is (B, H, M) and mask_block_idx is (B, H, M, N).\n    - Batch/head dims may be 1 for broadcast, or match the requested sizes.\n    - sparse_block_size_kv must match tile_n.\n    - sparse_block_size_q must be a multiple of q_stage * tile_m.\n    - If sparse_block_size_q is omitted and seqlen_q/num_m_blocks is ambiguous,\n      the caller must provide block_size to disambiguate. TODO will make this required in a future PR.\n    \"\"\"\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","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py#L318-L354","documentation":"Raised when the configured KV block size of the block-sparse mask does not match the attention kernel's BLOCK_SIZE_KV (n_block_size). FA4 block-sparse requires the sparse mask's KV granularity to equal the kernel tile size, otherwise indices would reference invalid KV tiles.","triggerScenarios":"Calling infer_block_sparse_expected_shapes / normalize_block_sparse_config with sparse_block_size_kv != n_block_size (the kernel's KV tile, e.g. 128 vs a mask built with 64).","commonSituations":"Building a BlockMask with BLOCK_SIZE_KV=64 while the flash attention op is configured with n_block_size=128, or upgrading the kernel default tile size without regenerating the mask.","solutions":["Set the sparse mask's KV block size to the kernel's BLOCK_SIZE_KV (e.g. rebuild BlockMask with matching block size)","Pass sparse_block_size_kv equal to n_block_size when calling the op"],"exampleFix":"// before\nBlockMask(block_size_kv=64, ...)\n// after\nBlockMask(block_size_kv=128, ...)  # == kernel BLOCK_SIZE_KV","handlingStrategy":"validation","validationCode":"assert sparse_block_size_kv in (None, n_block_size), f'must equal BLOCK_SIZE_KV={n_block_size}'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive the mask's KV block size from the kernel's tile size constant","Rebuild masks whenever the kernel tile config changes"],"tags":["block-sparse","block-size","configuration","attention"],"backgroundTag":"config-value-mismatch","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}