sgl-project/sglang · error · ValueError

x must be [1, S, C], got {list(x.shape)}

Error message

x must be [1, S, C], got {list(x.shape)}

What it means

forward requires the packed latent input x to be a 3-D tensor of shape [1, S, C] — batch dim must be exactly 1 since packing replaces batching. Any other rank or batch size raises this ValueError.

Source

Thrown at python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py:2440

                cu_seqlens.tolist()
                if raw_cu_seqlens_host is None
                else raw_cu_seqlens_host
            )
        )
        # max_seqlen_q is set to cu_seqlens[1] (`used`, the real/non-padding
        # row count) by construction -- already a plain host int here, so
        # ring can reuse it as real_seq_len below with no new device sync.
        max_seqlen = int(self._psp_field(psp, "packed_seq_params", "max_seqlen_q"))
        refiner_psp = _required_kwarg(kwargs, "refiner_packed_seq_params")
        refiner_cu = self._psp_field(
            refiner_psp, "refiner_packed_seq_params", "cu_seqlens_q"
        ).to(torch.int32)
        refiner_max = int(
            self._psp_field(refiner_psp, "refiner_packed_seq_params", "max_seqlen_q")
        )

        if x.dim() != 3 or x.shape[0] != 1:
            raise ValueError(f"x must be [1, S, C], got {list(x.shape)}")
        seq_len = int(x.shape[1])
        if token_tags is not None and token_tags.shape[0] != seq_len:
            raise ValueError(
                "token_tags must cover the full packed sequence "
                f"({seq_len}), got {token_tags.shape[0]}."
            )
        if inverse_indices.shape[0] != seq_len:
            raise ValueError(
                f"inverse_indices must be [{seq_len}], got {list(inverse_indices.shape)}"
            )
        device = x.device
        if subblock_sparse_query_block_mask is not None and not isinstance(
            subblock_sparse_query_block_mask, torch.Tensor
        ):
            raise ValueError("subblock_sparse_query_block_mask must be a tensor")
        self._resolve_attention_backend_once()

        # Row split is 2D: ring first (an outer, contiguous ring_chunk_len

View on GitHub (pinned to 0132848349)

Solutions

  1. Pack all sequences into a single [1, S_total, C] tensor with corresponding cu_seqlens/packed_seq_params
  2. If you have multiple samples, run them sequentially or use packing metadata rather than the batch dim
  3. Check x.unsqueeze(0) if you have a bare [S,C] tensor

Example fix

// before
out = model(x=latents)          # latents is [2, S, C]
// after
packed = torch.cat(samples, dim=1).unsqueeze(0)  # [1, S_total, C]
out = model(x=packed, ...)
Defensive patterns

Strategy: validation

Validate before calling

assert x.dim() == 3 and x.shape[0] == 1, f"expected [1,S,C], got {tuple(x.shape)}"

Type guard

def is_packed_input(x) -> bool:
    return torch.is_tensor(x) and x.dim() == 3 and x.shape[0] == 1

Prevention

When it happens

Trigger: Passing a [B,S,C] tensor with B>1, a 2-D [S,C] tensor, or an unbatched [S,C,1] layout to forward.

Common situations: Porting code from a batched diffusion-model API that accepted [B,S,C]; forgetting to pack/concatenate per-sample sequences into the packed [1,S,C] format.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/d580a8cfb5616d96. Report an issue: GitHub.