{"record":{"id":"0983433bfd793f11","repo":"sgl-project/sglang","slug":"block-sparse-tensors-context-have-block-size-spa","errorCode":null,"errorMessage":"Block sparse tensors{context} have block size {sparse_block_size_q}, which must be a multiple of {base_m_block}.","messagePattern":"Block sparse tensors(.+?) have block size (.+?), which must be a multiple of (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py","lineNumber":356,"sourceCode":"        )\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\n    mask_block_cnt = tensors.mask_block_cnt\n    mask_block_idx = tensors.mask_block_idx\n    if mask_block_cnt is None or mask_block_idx is None:\n        raise ValueError(\n            \"mask_block_cnt and mask_block_idx must be provided for block sparsity.\"\n        )\n    if mask_block_cnt.ndim != 3 or mask_block_idx.ndim != 4:\n        raise ValueError(","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py#L338-L374","documentation":"Raised when the inferred or provided q sparse block size is not a multiple of the kernel's q tile size (q_stage * m_block_size). FA4 iterates q in tiles of base_m_block, so a finer-grained mask cannot be honored.","triggerScenarios":"sparse_block_size_q=64 while the kernel's base_m_block=128; raises during normalize_block_sparse_config.","commonSituations":"Using a BlockMask built for a different kernel configuration (smaller q blocks) with the current FA4 tile size.","solutions":["Rebuild the mask with a q block size that is a multiple of the kernel's q tile (e.g. 128 or 256)","Change the kernel's q_stage/m_block_size so base_m_block divides sparse_block_size_q"],"exampleFix":"// before\nBlockMask(block_size_q=64, ...)\n// after\nBlockMask(block_size_q=128, ...)  # multiple of kernel q tile","handlingStrategy":"validation","validationCode":"assert sparse_block_size_q % base_m_block == 0, 'q block size must be multiple of kernel q tile'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose mask q block size >= kernel q tile and a multiple","Pin kernel tile sizes when reusing masks across versions"],"tags":["block-sparse","block-size","alignment"],"backgroundTag":"block-size-misaligned","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}