sgl-project/sglang · error · ValueError

height/width must be divisible by patch_size*ae_scale_factor

Error message

height/width must be divisible by patch_size*ae_scale_factor={patch}

What it means

The Ideogram stage requires height and width to be divisible by patch_size * ae_scale_factor (the latent-space compression granularity). Non-divisible dimensions would produce fractional latent grid sizes, so they are rejected up front.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/ideogram.py:149

            text, return_tensors="pt", add_special_tokens=False
        )
        token_ids = encoded["input_ids"][0]
        num_text_tokens = int(token_ids.shape[0])
        if num_text_tokens > max_text_tokens:
            raise ValueError(
                f"prompt has {num_text_tokens} tokens, exceeds max_text_tokens={max_text_tokens}"
            )
        return token_ids, num_text_tokens

    def _build_inputs(self, prompts: list[str], height: int, width: int, server_args):
        cfg = server_args.pipeline_config
        tokenized = [self._tokenize(p, cfg.max_text_tokens) for p in prompts]
        batch_size = len(prompts)
        patch = cfg.patch_size * cfg.ae_scale_factor
        if height < 256 or height > 2048 or width < 256 or width > 2048:
            raise ValueError("height/width must be between 256 and 2048")
        if height % patch != 0 or width % patch != 0:
            raise ValueError(
                f"height/width must be divisible by patch_size*ae_scale_factor={patch}"
            )
        grid_h = height // patch
        grid_w = width // patch
        num_image_tokens = grid_h * grid_w
        max_text_tokens = max(num_text for _, num_text in tokenized)
        total_seq_len = max_text_tokens + num_image_tokens
        device = get_local_torch_device()

        h_idx = torch.arange(grid_h).view(-1, 1).expand(grid_h, grid_w).reshape(-1)
        w_idx = torch.arange(grid_w).view(1, -1).expand(grid_h, grid_w).reshape(-1)
        t_idx = torch.zeros_like(h_idx)
        image_pos = torch.stack([t_idx, h_idx, w_idx], dim=1) + IMAGE_POSITION_OFFSET

        token_ids = torch.zeros(batch_size, total_seq_len, dtype=torch.long)
        text_position_ids = torch.zeros(batch_size, total_seq_len, 3, dtype=torch.long)
        position_ids = torch.zeros(batch_size, total_seq_len, 3, dtype=torch.long)
        segment_ids = torch.full(

View on GitHub (pinned to 0132848349)

Solutions

  1. Round height/width to the nearest multiple of cfg.patch_size * cfg.ae_scale_factor
  2. Use canonical sizes that are multiples of the granularity (e.g. 256-step sizes within [256,2048])

Example fix

# before
h, w = 1000, 768
# after
patch = cfg.patch_size * cfg.ae_scale_factor
h = round(h / patch) * patch
w = round(w / patch) * patch
Defensive patterns

Strategy: validation

Validate before calling

patch = cfg.patch_size * cfg.ae_scale_factor
height = round(height / patch) * patch
width = round(width / patch) * patch
assert height % patch == 0 and width % patch == 0

Prevention

When it happens

Trigger: Passing height/width divisible in-range values that are not multiples of cfg.patch_size * cfg.ae_scale_factor, e.g. 1000 when patch granularity is 16 (2 patch * 8 ae scale).

Common situations: Arbitrary user-supplied sizes like 333 or 700; changing patch_size or ae_scale_factor in config without re-rounding the client's dimensions; porting sizes from a model with a different VAE scale factor.

Related errors


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