sgl-project/sglang · error · ValueError

Feature size mismatch

Error message

Feature size mismatch: {features.size(0)} vs {lengths.sum().item()}

What it means

group_by_length splits a packed feature tensor into per-sample chunks using the supplied lengths; it asserts features.size(0) equals lengths.sum(). A mismatch means the features and lengths describe different amounts of data (e.g. padded vs packed features, wrong lengths tensor).

Solutions

  1. Ensure features is the packed (concatenated along dim 0) tensor produced by encode_batch, not the padded batch tensor
  2. Recompute lengths from the same features tensor: lengths = torch.tensor([f.size(0) for f in feats])
  3. Verify lengths.sum().item() == features.size(0) before calling (see validation snippet)

Example fix

// before
grouped = group_by_length(padded_features, lengths, max_length=4096)
// after
packed = torch.cat([f for f in feats], dim=0)
lengths = torch.tensor([f.size(0) for f in feats])
grouped = group_by_length(packed, lengths, max_length=4096)
Defensive patterns

Strategy: validation

Validate before calling

assert features.size(0) == lengths.sum().item(), (
    features.shape, lengths.tolist())
out = group_by_length(features, lengths, max_length)

Type guard

def lengths_match(features: torch.Tensor, lengths: torch.Tensor) -> bool:
    return features.dim() == 2 and features.size(0) == int(lengths.sum().item())

Try / catch

try:
    grouped = group_by_length(features, lengths, max_length)
except ValueError as e:
    raise RuntimeError(f"packing invariant broken: {e}") from e

Prevention

When it happens

Trigger: Calling group_by_length(features, lengths, max_length) where features was padded (batch-major) instead of packed, or lengths counts frames for a different feature tensor / was computed pre-padding.

Common situations: Audio batch encoding pipelines where an upstream op pads features before packing; off-by-one or unit mismatch between encoder frame counts and lengths; reusing lengths from a previous batch.

Understand the failure class

Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.

Related errors


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

Appendix: source

Thrown at python/sglang/srt/models/mimo_audio.py:815

    def get_output_length(self, mel_len):
        tgt_len = mel_len + 3 - self.config.kernel_size
        return (tgt_len + 2 - self.config.kernel_size) // self.config.stride_size + 1

    @torch.no_grad()
    def encode(self, mels, input_lens, use_quantizer=True):
        input_features = mels
        encoder_output_length = self.get_output_length(input_lens)
        hidden_states, hidden_states_packed, encoder_output_length, codes = (
            self.encoder.encode(
                input_features, input_lens=input_lens, use_quantizer=use_quantizer
            )
        )
        return hidden_states, hidden_states_packed, encoder_output_length, codes


def group_by_length(features: torch.Tensor, lengths: torch.Tensor, max_length: int):
    if features.size(0) != lengths.sum().item():
        raise ValueError(
            f"Feature size mismatch: {features.size(0)} vs {lengths.sum().item()}"
        )

    split_points = []
    current_sum = 0

    for i, seq_len in enumerate(lengths):
        if current_sum + seq_len > max_length and current_sum > 0:
            split_points.append(i)
            current_sum = seq_len.item()
        else:
            current_sum += seq_len.item()

    # Convert split points to group sizes
    group_sizes = []
    prev = 0
    for point in split_points:
        group_sizes.append(point - prev)

View on GitHub (pinned to 0132848349)