sgl-project/sglang · error · ValueError

Unsupported scale {scale}. Choose from {list(mapping.keys())

Error message

Unsupported scale {scale}. Choose from {list(mapping.keys())}

What it means

The latent upsampler only supports a fixed set of rational spatial scale factors, mapped internally to integer fractions (0.75→3/4, 1.5→3/2, 2.0→2/1, 4.0→4/1). Constructing SpatialRationalResampler with any other scale value raises this error because no rational upsampling path exists for it.

Source

Thrown at python/sglang/multimodal_gen/runtime/models/upsampler/latent_upsampler.py:128

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        residual = x
        x = self.conv1(x)
        # Fused GroupNorm + SiLU on the first norm of the block. The second
        # norm (line below) is followed by `silu(norm + residual)`, which the
        # current `apply_group_norm_silu` helper does not cover -- left on
        # the eager path until a `group_norm_add_silu` helper exists.
        x = apply_group_norm_silu(x, self.norm1, self.activation)
        x = self.conv2(x)
        x = self.norm2(x)
        x = self.activation(x + residual)
        return x


def _rational_for_scale(scale: float) -> Tuple[int, int]:
    mapping = {0.75: (3, 4), 1.5: (3, 2), 2.0: (2, 1), 4.0: (4, 1)}
    if float(scale) not in mapping:
        raise ValueError(
            f"Unsupported scale {scale}. Choose from {list(mapping.keys())}"
        )
    return mapping[float(scale)]


class SpatialRationalResampler(torch.nn.Module):
    """Fully-learned rational spatial scaling via PixelShuffle + anti-aliased downsample."""

    def __init__(self, mid_channels: int, scale: float):
        super().__init__()
        self.scale = float(scale)
        self.num, self.den = _rational_for_scale(self.scale)
        self.conv = torch.nn.Conv2d(
            mid_channels, (self.num**2) * mid_channels, kernel_size=3, padding=1
        )
        self.pixel_shuffle = PixelShuffleND(2, upscale_factors=(self.num, self.num))
        self.blur_down = BlurDownsample(dims=2, stride=self.den)

View on GitHub (pinned to 0132848349)

Solutions

  1. Set scale to one of the supported values: 0.75, 1.5, 2.0, or 4.0
  2. If scale is computed, round it to the nearest supported value before passing it in
  3. If you need an unsupported ratio, use a different upsampler module that supports arbitrary scales

Example fix

# before
resampler = SpatialRationalResampler(scale=3.0)
# after
resampler = SpatialRationalResampler(scale=4.0)
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_SCALES = {0.75, 1.5, 2.0, 4.0}
if not any(abs(scale - s) < 1e-9 for s in SUPPORTED_SCALES):
    scale = min(SUPPORTED_SCALES, key=lambda s: abs(scale - s))
    # or raise your own descriptive error before constructing

Type guard

def is_supported_scale(scale: float) -> bool:
    return float(scale) in {0.75, 1.5, 2.0, 4.0}

Prevention

When it happens

Trigger: Instantiating SpatialRationalResampler (or a wrapper that passes scale) with e.g. scale=3.0, scale=1.0, or a float that isn't exactly one of 0.75/1.5/2.0/4.0. The check is float(scale) not in mapping, so near-misses like 2.0000001 also fail.

Common situations: Copying a config from another model variant with different resolution requirements; passing a scale computed from a ratio (e.g. target_res/base_res) that doesn't land on a supported value; floating point drift when scale is derived arithmetically.

Related errors


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