xai-org/x-algorithm · error · ValueError

Block sparse tensors{context} have block size {sparse_block_

Error message

Block sparse tensors{context} have block size {sparse_block_size_q}, which must be a multiple of {base_m_block}.

What it means

After resolving sparse_block_size_q (explicit or inferred), it must be divisible by base_m_block (q_stage * m_block_size), because each sparse Q block must contain an integer number of kernel M-tiles. Otherwise the block boundaries cannot align with kernel tiles.

Source

Thrown at phoenix/xrex/cutedsl/ranker_fa4/block_sparsity.py:327

        sparse_block_size_kv = base_n_block
    if sparse_block_size_kv != base_n_block:
        raise ValueError(f"Block sparse tensors{context} require BLOCK_SIZE_KV={base_n_block}.")
    if tensors.mask_block_idx is None:
        raise ValueError("mask_block_cnt and mask_block_idx must be provided for block sparsity.")
    num_m_blocks = tensors.mask_block_idx.shape[2]

    if sparse_block_size_q is None:
        sparse_block_size_q = get_sparse_q_block_size(tensors, seqlen_q)
        if sparse_block_size_q is None and base_m_block != 1:
            raise ValueError(
                f"Block sparse tensors{context} require explicit sparse_block_size[0] "
                f"to disambiguate block size for seqlen_q={seqlen_q} and num_m_blocks={num_m_blocks}."
            )
        if sparse_block_size_q is None:
            sparse_block_size_q = ceildiv(seqlen_q, num_m_blocks)

    if sparse_block_size_q % base_m_block != 0:
        raise ValueError(
            f"Block sparse tensors{context} have block size {sparse_block_size_q}, "
            f"which must be a multiple of {base_m_block}."
        )

    expected_m_blocks = ceildiv(seqlen_q, sparse_block_size_q)
    expected_n_blocks = ceildiv(seqlen_k, sparse_block_size_kv)
    q_subtile_factor = sparse_block_size_q // base_m_block
    expected_count_shape = (batch_size, num_head, expected_m_blocks)
    expected_index_shape = (batch_size, num_head, expected_m_blocks, expected_n_blocks)

    mask_block_cnt = tensors.mask_block_cnt
    mask_block_idx = tensors.mask_block_idx
    if mask_block_cnt is None or mask_block_idx is None:
        raise ValueError("mask_block_cnt and mask_block_idx must be provided for block sparsity.")
    if mask_block_cnt.ndim != 3 or mask_block_idx.ndim != 4:
        raise ValueError(
            f"Block sparse tensors{context} must have shapes (B, H, M) and (B, H, M, N)."
        )

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Pick sparse_block_size_q as a multiple of base_m_block (e.g. 1x or 2x of q_stage * m_block_size)
  2. Adjust q_stage/m_block_size so their product divides your sparse Q block size
  3. Regenerate mask tensors with an aligned block size

Example fix

# before
normalize_block_sparse_config(..., sparse_block_size=(96, None))  # 96 % 64 != 0

# after
normalize_block_sparse_config(..., sparse_block_size=(128, None))  # 128 = 2 * 64
Defensive patterns

Strategy: validation

Validate before calling

base_m = q_stage * m_block_size
assert sparse_block_size_q % base_m == 0, f"{sparse_block_size_q} not divisible by {base_m}"

Prevention

When it happens

Trigger: Passing a Q block size like 96 when base_m_block is 64 (96 % 64 != 0), or an inferred ceildiv(seqlen_q, num_m_blocks) that is not a multiple of the kernel's M-tile size.

Common situations: Choosing an arbitrary sparse block size for compression without considering the kernel tile size; small seqlen_q where ceildiv yields a non-aligned value; changing q_stage/m_block_size in kernel config without regenerating sparse metadata.

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/8495aecf7986b589. Report an issue: GitHub.