sgl-project/sglang · error · TypeError
pairs must be a torch.Tensor
Error message
pairs must be a torch.Tensor
What it means
The 'dual_sigma_shift' postprocess fully validates its input before rebuilding both modality columns with the FlowMatchScheduler sigma transform. Its first check is a TypeError raised when pairs is not a torch.Tensor at all (list, tuple, numpy array, float, None).
Source
Thrown at python/sglang/multimodal_gen/runtime/models/schedulers/flow_match_pair.py:367
if name == "dual_sigma_shift":
visual_shift = float(kwargs.get("visual_shift", self.shift))
audio_shift = float(kwargs.get("audio_shift", self.shift))
visual_denoising_strength = float(
kwargs.get("visual_denoising_strength", 1.0)
)
audio_denoising_strength = float(
kwargs.get("audio_denoising_strength", 1.0)
)
visual_mu = kwargs.get(
"visual_exponential_shift_mu", self.exponential_shift_mu
)
audio_mu = kwargs.get(
"audio_exponential_shift_mu", self.exponential_shift_mu
)
def _dual_sigma_shift(pairs: torch.Tensor, *, source: str):
if not isinstance(pairs, torch.Tensor):
raise TypeError("pairs must be a torch.Tensor")
if pairs.ndim != 2 or pairs.shape[1] != 2:
raise ValueError("pairs must be a torch.Tensor of shape [N, 2]")
if pairs.shape[0] == 0:
raise ValueError("pairs length must be greater than 0")
if source not in ("timesteps", "sigmas"):
raise ValueError("source must be 'timesteps' or 'sigmas'")
num_steps = pairs.shape[0]
device = pairs.device
dtype = pairs.dtype
def _build_column(
shift_value: float, denoising_strength: float, mu_override
):
if shift_value <= 0:
raise ValueError("shift must be positive")
if denoising_strength <= 0:
raise ValueError("denoising_strength must be positive")View on GitHub (pinned to 0132848349)
Solutions
- Convert to a tensor before use: pairs = torch.as_tensor(pairs, dtype=torch.float32)
- Prefer scheduler-native set_timesteps so pairs are always torch.Tensor [N, 2]
- Add an isinstance assertion at the boundary of your custom loop
- Return early / skip the postprocess when pairs is None instead of passing it through
Example fix
# before post_pairs = np.linspace(1.0, 0.0, num_steps) # ndarray # after post_pairs = torch.as_tensor(np.linspace(1.0, 0.0, num_steps), dtype=torch.float32) post_pairs = torch.stack([post_pairs, post_pairs], dim=1)
Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(pairs, torch.Tensor):
pairs = torch.as_tensor(pairs, dtype=torch.float32) Type guard
def is_pairs_tensor(p) -> TypeGuard[torch.Tensor]:
return isinstance(p, torch.Tensor) and p.ndim == 2 and p.shape[1] == 2 Try / catch
try:
out = scheduler.step(...)
except TypeError as e:
if 'pairs must be a torch.Tensor' in str(e):
pairs = torch.as_tensor(pairs).reshape(-1, 2)
out = scheduler.step(...) # retry with normalized input
else:
raise Prevention
- Ban numpy arrays at your pipeline boundary; convert once at ingestion
- Deserialize schedules from config with torch.as_tensor immediately
When it happens
Trigger: set_pair_postprocess_by_name('dual_sigma_shift', ...) with a subsequent call where the pairs argument is a Python list, numpy.ndarray, or scalar — e.g. a schedule produced by numpy.linspace or deserialized from JSON/config.
Common situations: Config-driven pipelines that deserialize schedules from JSON/YAML into lists; numpy-based schedule generation not converted to torch; passing None when the scheduler cache is empty.
Understand the failure class
Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.
Related errors
- pairs length must be greater than 0
- pairs must be a torch.Tensor of shape [N, 2]
- `dt_bias` must have {HV * K} elements (got {dt_bias.numel()}
- The batch size is expected to be 1 rather than {q.shape[0]}
- The number of initial states is expected to be equal to the
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/c78ef43238621381.
Report an issue: GitHub.