sgl-project/sglang · error · ValueError

refined prompt embeddings must have hidden width {self.hidde

Error message

refined prompt embeddings must have hidden width {self.hidden_size}, got {int(text_embed.shape[-1])}

What it means

Raised when externally supplied refined prompt embeddings have a last-dimension (hidden width) that does not equal self.hidden_size of the DiT. The refiner path requires embeddings already in the model's hidden size before slicing/casting to bfloat16.

Source

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

            # BCG turns this request-varying host constant into a scalar input
            # so different live lengths can replay one padded-text signature.
            # _embed is an eager graph break, so this value is read outside
            # captured CUDA graphs.
            text_len = int(refined_prompt_embeds_length.item())
        else:
            text_len = int(refined_prompt_embeds_length)
        if text_len <= 0 or text_len > int(text_embeddings_selected.shape[0]):
            raise ValueError(
                "refiner cu_seqlens live text length must be in "
                f"[1, {int(text_embeddings_selected.shape[0])}], got {text_len}"
            )
        text_pos = text_pos[:text_len]
        if refined_prompt_embeds_length is not None:
            text_embed = text_embeddings_selected[:text_len].to(
                device=device, dtype=_BF16_DTYPE
            )
            if int(text_embed.shape[-1]) != self.hidden_size:
                raise ValueError(
                    "refined prompt embeddings must have hidden width "
                    f"{self.hidden_size}, got {int(text_embed.shape[-1])}"
                )
        else:
            text_embed = self.refine_prompt_embeds(
                text_embeddings_selected,
                refiner_cu_seqlens,
                device=device,
            )

        local_seq_len = row_stop - row_start
        trusted_layout = local_embedding_layout is not None
        if trusted_layout:
            used_len = text_len + int(img_pos.numel()) + int(audio_pos.numel())
            local_live_rows = min(max(used_len - row_start, 0), local_seq_len)
            embeddings = torch.empty(
                (local_seq_len, self.hidden_size), device=device, dtype=_BF16_DTYPE
            )

View on GitHub (pinned to 0132848349)

Solutions

  1. Project the external embeddings to hidden_size before passing them (or use the model's internal refine_prompt_embeds by omitting the length so the else-branch runs)
  2. Check the config's hidden_size against the embedding producer's output dim
  3. Re-derive embeddings with the matching refiner checkpoint

Example fix

// before
emb = text_encoder(x)            # width != model.hidden_size
model.forward(..., refined_prompt_embeds=emb, ...)
// after
emb = projector(text_encoder(x))  # width == model.hidden_size
model.forward(..., refined_prompt_embeds=emb, ...)
Defensive patterns

Strategy: validation

Validate before calling

if refined_prompt_embeds is not None:
    assert refined_prompt_embeds.shape[-1] == model.hidden_size, refined_prompt_embeds.shape

Prevention

When it happens

Trigger: Passing refined_prompt_embeds (via packed sequence params) whose feature dimension differs from the model's configured hidden_size, e.g. raw encoder output width instead of projected embeddings.

Common situations: Swapping in a different text encoder or refiner checkpoint whose output width differs; passing unprojected CLIP/T5 outputs directly instead of the refine_prompt_embeds projection output.

Related errors


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