xai-org/x-algorithm · error · ValueError

Block sparse tensors{context} require BLOCK_SIZE_KV={base_n_

Error message

Block sparse tensors{context} require BLOCK_SIZE_KV={base_n_block}.

What it means

infer_block_sparse_expected_shapes (via normalize_block_sparse_config) enforces that the KV block size of the sparse metadata equals the kernel's BLOCK_SIZE_KV (n_block_size). If the user supplies sparse_block_size_kv different from the kernel's n_block_size, the block indices cannot be mapped to kernel tiles and the call is rejected.

Source

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

    tensors: BlockSparseTensorsTorch,
    *,
    batch_size: int,
    num_head: int,
    seqlen_q: int,
    seqlen_k: int,
    m_block_size: int,
    n_block_size: int,
    q_stage: int,
    context: str,
    sparse_block_size_q: int | None = None,
    sparse_block_size_kv: int | None = None,
) -> Tuple[Tuple[int, int, int], Tuple[int, int, int, int], int]:
    base_m_block = q_stage * m_block_size
    base_n_block = n_block_size
    if sparse_block_size_kv is None:
        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}."

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Set sparse_block_size_kv=None so it defaults to base_n_block (n_block_size)
  2. Regenerate mask_block_cnt/idx with block size equal to n_block_size
  3. Align the kernel config so n_block_size matches the metadata's KV block size

Example fix

# before
cfg = normalize_block_sparse_config(..., sparse_block_size=(64, 128))  # 128 != n_block_size

# after
cfg = normalize_block_sparse_config(..., sparse_block_size=(64, None))  # kv defaults to n_block_size
Defensive patterns

Strategy: validation

Validate before calling

assert sparse_block_size_kv in (None, n_block_size), f"kv block size must equal BLOCK_SIZE_KV={n_block_size}"

Prevention

When it happens

Trigger: Calling the config API with sparse_block_size_kv set to a value != n_block_size (e.g. 128 vs kernel tile 64), or constructing mask tensors with a different KV granularity than the attention kernel was configured with.

Common situations: Changing the kernel tile size (n_block_size) without regenerating the block-sparse metadata; reusing sparse schedules computed for a different model/config; copying example code that assumed a different BLOCK_SIZE_KV.

Related errors


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