xai-org/x-algorithm · error · ValueError

Varlen block sparsity requires sparse_block_size[0]={base_m_

Error message

Varlen block sparsity requires sparse_block_size[0]={base_m_block} (= q_stage * tile_m); got {sparse_block_size_q}.

What it means

For varlen inputs (cu_total_m_blocks provided), the query-side sparse block size must be exactly q_stage * m_block_size (tile_m scaled by the query stage factor). An explicit sparse_block_size_q differing from that value is rejected.

Source

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

    num_head: int,
    seqlen_q: int,
    seqlen_k: int,
    block_size: tuple[int, int],
    q_stage: int,
) -> tuple[BlockSparseTensorsTorch, Tuple[Tuple[bool, ...], ...] | None, int]:
    m_block_size, n_block_size = block_size
    if tensors.block_size is None:
        sparse_block_size_q, sparse_block_size_kv = None, n_block_size
    else:
        sparse_block_size_q, sparse_block_size_kv = tensors.block_size
    if sparse_block_size_kv != n_block_size:
        raise ValueError(
            f"Block sparsity requires sparse_block_size[1]={n_block_size} to match tile_n."
        )
    if tensors.cu_total_m_blocks is not None:
        base_m_block = q_stage * m_block_size
        if sparse_block_size_q is not None and sparse_block_size_q != base_m_block:
            raise ValueError(
                f"Varlen block sparsity requires sparse_block_size[0]={base_m_block} "
                f"(= q_stage * tile_m); got {sparse_block_size_q}."
            )
        total_m_blocks = tensors.mask_block_cnt.shape[-1]
        total_n_blocks = tensors.mask_block_idx.shape[-1]
        expected_count_shape = (num_head, total_m_blocks)
        expected_index_shape = (num_head, total_n_blocks)
        q_subtile_factor = 1
    else:
        expected_count_shape, expected_index_shape, q_subtile_factor = (
            infer_block_sparse_expected_shapes(
                tensors,
                batch_size=batch_size,
                num_head=num_head,
                seqlen_q=seqlen_q,
                seqlen_k=seqlen_k,
                m_block_size=m_block_size,
                n_block_size=n_block_size,

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Set block_size[0] to q_stage * tile_m, or clear tensors.block_size to None so the correct default is used
  2. Rebuild the varlen mask with the kernel's current q_stage and tile_m
  3. Verify cu_total_m_blocks, seqlen_q and the mask M-block count are mutually consistent

Example fix

# before
tensors = BlockSparseTensorsTorch(..., block_size=(64, 128),
                                  cu_total_m_blocks=cu)     # q_stage=2, tile_m=64

# after
tensors = BlockSparseTensorsTorch(..., block_size=(128, 128),   # 2*64
                                  cu_total_m_blocks=cu)
# or block_size=None
Defensive patterns

Strategy: validation

Validate before calling

expected_q = q_stage * m_block_size
assert tensors.block_size is None or tensors.block_size[0] == expected_q, \
    (tensors.block_size, expected_q)

Prevention

When it happens

Trigger: Varlen forward run with tensors.cu_total_m_blocks set and tensors.block_size[0] set to a value other than q_stage * tile_m; e.g. block_size=(128, 128) when q_stage=2 and tile_m=64 (expected 128... mismatches when using 64).

Common situations: Using a fixed block-size mask for varlen training; upgrading the kernel where q_stage changed; mask built for packed sequences with a different m-block granularity.

Related errors


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