sgl-project/sglang · error · ValueError

In-place vision RoPE requires complex64 frequencies, got {fr

Error message

In-place vision RoPE requires complex64 frequencies, got {freqs_cis.dtype}/{freqs_cis.device}

What it means

prepare_fused_qk_complex_rope_inplace prepares a cache by concatenating freqs_cis.real and freqs_cis.imag along the last dim; that split only exists for complex tensors, so freqs_cis must be torch.complex64. Any other dtype (float32 stored as interleaved real/imag, complex128) is rejected before the split.

Source

Thrown at python/sglang/kernels/ops/attention/vision_rope.py:165

        k_flat.stride(0),
        k_flat.stride(1),
        k_flat.stride(2),
        freqs.stride(0),
        freqs.stride(1),
        freqs.stride(2),
        BLOCK=block,
        num_warps=4,
    )
    return q_out.view(original_shape), k_out.view(original_shape)


def prepare_fused_qk_complex_rope_inplace(
    freqs_cis: torch.Tensor,
) -> PreparedInplaceComplexRoPE:
    """Prepare the cache and positions used by the contiguous in-place kernel."""

    if freqs_cis.dtype != torch.complex64:
        raise ValueError(
            "In-place vision RoPE requires complex64 frequencies, got "
            f"{freqs_cis.dtype}/{freqs_cis.device}"
        )
    return (
        torch.cat((freqs_cis.real, freqs_cis.imag), dim=-1),
        torch.arange(
            freqs_cis.size(0),
            dtype=torch.long,
            device=freqs_cis.device,
        ),
    )


def apply_fused_qk_complex_rope_inplace(
    q: torch.Tensor,
    k: torch.Tensor,
    prepared_rope: PreparedInplaceComplexRoPE,
) -> Tuple[torch.Tensor, torch.Tensor]:

View on GitHub (pinned to 0132848349)

Solutions

  1. Convert: freqs = torch.view_as_complex(freqs_float.reshape(*freqs_float.shape[:-1], -1, 2).contiguous()) when the data is interleaved real/imag
  2. Or build the table with torch.polar(abs, angle) which produces complex64 directly

Example fix

// before
prepared = prepare_fused_qk_complex_rope_inplace(freqs_float32)  # (T, D/2, 2)
// after
freqs_cis = torch.view_as_complex(freqs_float32.contiguous())
prepared = prepare_fused_qk_complex_rope_inplace(freqs_cis)
Defensive patterns

Strategy: validation

Validate before calling

assert freqs_cis.dtype == torch.complex64, 'freqs must be complex64'

Type guard

def is_c64(t: torch.Tensor) -> bool:
    return t.dtype == torch.complex64

Prevention

When it happens

Trigger: Passing a float32 tensor of shape (..., 2*half) that packs real and imag channels (a common memory layout after slicing a projection) instead of an actual complex64 tensor.

Common situations: Vision towers whose RoPE tables are materialized as real tensors for convolution-friendly layouts, then fed to the in-place fused path which expects torch.view_as_complex-style complex64 input.

Related errors


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