sgl-project/sglang · error · ValueError
Block sparse tensors{context} m-block dimension {num_m_block
Error message
Block sparse tensors{context} m-block dimension {num_m_blocks} does not match sparse_block_size_q={sparse_block_size_q}. Set BlockSparseTensorsTorch.block_size to match the BlockMask BLOCK_SIZE. What it means
Raised when the m-block dimension of the mask does not match the number of q blocks implied by sparse_block_size_q (expected_m_blocks = ceildiv(seqlen_q, sparse_block_size_q)). Usually means the BlockMask was built with a different q block size than recorded/requested.
Source
Thrown at python/sglang/kernels/ops/attention/flash_attn/cute/block_sparsity.py:400
raise ValueError(
f"Block sparse tensors{context} {dim_name} dim must be {tgt} or 1."
)
for dim_name, cur, tgt in (
("batch", mask_block_idx.shape[0], expected_index_shape[0]),
("head", mask_block_idx.shape[1], expected_index_shape[1]),
):
if cur != tgt and cur != 1:
raise ValueError(
f"Block sparse tensors{context} {dim_name} dim must be {tgt} or 1."
)
if mask_block_cnt.shape[2] != mask_block_idx.shape[2]:
raise ValueError(
f"Block sparse tensors{context} must share the same m-block dimension."
)
# [Note] Allow Compact block sparse indices: FA4 only accesses indices 0..cnt-1
# per query tile, so idx.shape[3] can be <= expected_n_blocks.
if mask_block_idx.shape[3] > expected_n_blocks:
raise ValueError(
f"Block sparse tensors{context} n-block dimension must be <= {expected_n_blocks}."
)
if expected_m_blocks != num_m_blocks:
raise ValueError(
f"Block sparse tensors{context} m-block dimension {num_m_blocks} does not match "
f"sparse_block_size_q={sparse_block_size_q}. "
f"Set BlockSparseTensorsTorch.block_size to match the BlockMask BLOCK_SIZE."
)
return expected_count_shape, expected_index_shape, q_subtile_factor
def get_block_sparse_expected_shapes_bwd(
batch_size: int,
num_head: int,
seqlen_q: int,
seqlen_k: int,
m_block_size: int,
n_block_size: int,View on GitHub (pinned to 0132848349)
Solutions
- Set BlockSparseTensorsTorch.block_size to the BlockMask's BLOCK_SIZE so sparse_block_size_q matches the mask layout
- Rebuild the mask with q block size consistent with the current seqlen_q
- Recheck that seqlen_q (e.g. including spec-decode extra tokens) matches mask construction
Example fix
// before tensors = BlockSparseTensorsTorch(cnt, idx) # block_size unset // after tensors = BlockSparseTensorsTorch(cnt, idx, block_size=(128, 128)) # match BlockMask
Defensive patterns
Strategy: validation
Validate before calling
expected_m = (seqlen_q + sparse_block_size_q - 1) // sparse_block_size_q assert mask_block_idx.shape[2] == expected_m
Prevention
- Set BlockSparseTensorsTorch.block_size to the BlockMask BLOCK_SIZE
- Ensure seqlen_q at call time matches mask construction
When it happens
Trigger: num_m_blocks=64 from the mask but ceildiv(seqlen_q, sparse_block_size_q)=32, during normalize_block_sparse_config.
Common situations: BlockSparseTensorsTorch.block_size not set (or stale) after converting a BlockMask, so sparse_block_size_q defaults incorrectly; or seqlen_q changed between mask build and call.
Related errors
- {tensor_name}{context_clause} with shape {tensor.shape} cann
- Block sparse tensors{context} require BLOCK_SIZE_KV={base_n_
- Block sparse tensors{context} have block size {sparse_block_
- Block sparse tensors{context} must have shapes (B, H, M) and
- Block sparse tensors{context} {dim_name} dim must be {tgt} o
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/963781c441169027.
Report an issue: GitHub.