vllm-project/vllm · error · ValueError

`a` must have at least 1 dimension.

Error message

`a` must have at least 1 dimension.

What it means

fusedQuantizeMx() packs tensor `a` into MX FP4 (e2m1) blocks with e8m0 shared scales; the kernel's launch math (rows = numel/last_dim, col blocks of 32) requires a to be at least 1-D. A 0-dim scalar tensor (a.dim() == 0) cannot be block-quantized, so it is rejected up front.

Source

Thrown at vllm/_custom_ops.py:4096

        a: torch.Tensor, b: torch.Tensor, xh_e2m1: torch.Tensor, xh_e8m0: torch.Tensor
    ):
        return xh_e2m1, xh_e8m0


if hasattr(torch.ops._qutlass_C, "fusedQuantizeMxAbsMax"):

    @register_fake("_qutlass_C::fusedQuantizeMxAbsMax")
    def _fake_fused_quantize_mx_absmax(
        a: torch.Tensor, b: torch.Tensor, xh_e2m1: torch.Tensor, xh_e8m0: torch.Tensor
    ):
        return xh_e2m1, xh_e8m0


def fusedQuantizeMx(
    a: torch.Tensor, b: torch.Tensor, *, method: Literal["quest", "abs_max"] = "quest"
) -> tuple[torch.Tensor, torch.Tensor]:
    if a.dim() == 0:
        raise ValueError("`a` must have at least 1 dimension.")
    if a.size(-1) % 32 != 0:
        raise ValueError(f"last dim of `a` must be divisible by 32, got {a.size(-1)}.")
    if b.device != a.device:
        raise ValueError("`a` and `b` must be on the same device.")

    xh_e2m1 = torch.empty(
        *a.shape[:-1], a.size(-1) // 2, dtype=torch.uint8, device=a.device
    )

    rows, cols = a.numel() // a.size(-1), a.size(-1) // 32
    n_row_blocks = cdiv(rows, 128)
    n_col_blocks = cdiv(cols, 4)
    padded_rows = n_row_blocks * 128
    padded_cols = n_col_blocks * 4

    xh_e8m0 = torch.empty(
        padded_rows, padded_cols, dtype=torch.float8_e8m0fnu, device=a.device
    )

View on GitHub (pinned to c794754062)

Solutions

  1. Keep at least one dimension: use .reshape(1, -1) or .unsqueeze(0) on the scalar tensor before calling
  2. Fix upstream code that over-squeezes (replace x.squeeze() with x.squeeze(-2) or dimension-specific squeeze)

Example fix

# before
q, s = ops.fusedQuantizeMx(score.squeeze(), b)  # 0-dim -> raises
# after
q, s = ops.fusedQuantizeMx(score.reshape(1, -1), b)
Defensive patterns

Strategy: validation

Validate before calling

assert a.dim() >= 1, f"a must be >=1-D, got shape {tuple(a.shape)}"

Type guard

def is_quantizable_mx(a: torch.Tensor) -> bool:
    return a.dim() >= 1 and a.size(-1) % 32 == 0

Prevention

When it happens

Trigger: Calling vllm._custom_ops.fusedQuantizeMx(a, b) where a was created via torch.tensor(3.0), .item()-like reduction to scalar shape, or .squeeze() over all dims.

Common situations: Aggressive squeeze() in preprocessing pipelines collapsing a (1,1,d) K-quantization tensor to 0-d; passing a scalar similarity instead of a row vector in sparse-attention (quest) index quantization.

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/4f9b961ff798a076. Report an issue: GitHub.