sgl-project/sglang · error · ValueError

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

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).

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)

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.

Related errors


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