sgl-project/sglang · error · ValueError
Pi05 v1 expects one state vector per request
Error message
Pi05 v1 expects one state vector per request
What it means
The Pi05 v1 stage requires exactly one robot state vector per action request. After converting the state to a float32 tensor (and unsqueezing 1-D inputs to shape [1, D]), it rejects any tensor whose batch dimension is not exactly 1, matching the single-request design of the v1 API.
Source
Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/pi05_preprocess.py:185
is_present = value is not None and bool(image_masks_in.get(key, True))
if is_present:
tensor = _preprocess_image(value, self.config.image_size)
else:
channels = 3
height, width = self.config.image_size
tensor = torch.ones(channels, height, width, dtype=torch.float32) * -1.0
images[key] = tensor.unsqueeze(0)
image_masks[key] = torch.tensor([is_present], dtype=torch.bool)
state = raw_observation.get("state")
state_tensor = None
if state is not None:
state_tensor = torch.as_tensor(state, dtype=torch.float32)
if state_tensor.ndim == 1:
state_tensor = state_tensor.unsqueeze(0)
if state_tensor.shape[0] != 1:
raise ValueError("Pi05 v1 expects one state vector per request")
if state_tensor.shape[-1] > self.config.state_dim:
raise ValueError(
f"Pi05 state dim must be <= {self.config.state_dim}, "
f"got {state_tensor.shape[-1]}"
)
noise = raw_observation.get("noise")
noise_tensor = None
if noise is not None:
noise_tensor = torch.as_tensor(noise, dtype=torch.float32)
if noise_tensor.ndim == 2:
noise_tensor = noise_tensor.unsqueeze(0)
expected = (1, self.config.action_horizon, self.config.action_dim)
if tuple(noise_tensor.shape) != expected:
raise ValueError(
f"Pi05 noise must have shape {expected}, "
f"got {tuple(noise_tensor.shape)}"
)View on GitHub (pinned to 0132848349)
Solutions
- Slice your state array per timestep: state = states[t:t+1] (or states[t] which gets unsqueezed automatically).
- Verify state_tensor.ndim is 1 or 2 with shape[0]==1 before calling the stage.
- Batch by looping over requests rather than stacking states along dim 0.
Example fix
# before
state = episode_states # shape [T, D]
stage({"state": state, ...})
# after
for t in range(episode_states.shape[0]):
stage({"state": episode_states[t], ...}) Defensive patterns
Strategy: validation
Validate before calling
import torch
s = torch.as_tensor(state, dtype=torch.float32)
if s.ndim == 1:
s = s.unsqueeze(0)
assert s.shape[0] == 1, f"expected 1 state, got {s.shape[0]}" Type guard
def is_single_state(state) -> bool:
if state is None: return True
s = torch.as_tensor(state)
return s.ndim <= 2 and (s.ndim < 2 or s.shape[0] == 1) Prevention
- Index recorded trajectories per timestep before building the request.
- Log state tensor shape right before the call during integration.
When it happens
Trigger: Passing raw_observation state with shape [N, D] where N > 1 (a batched state matrix), or a nested list like [[s1...],[s2...]] containing multiple state vectors.
Common situations: Replaying recorded robot episodes where states are stored as [T, D] time-series arrays and the whole trajectory is passed at once instead of per-timestep; migrating from an ensemble/batched policy.
Related errors
- Pi05 v1 expects one prompt per action request
- Pi05 state dim must be <= {self.config.state_dim}, got {stat
- Pi05 noise must have shape {expected}, got {tuple(noise_tens
- Pi05Pipeline v1 supports same-process execution only. Use pr
- VLA action expert should not share the prefix TP layout. Use
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/d659fe9891e2ae68.
Report an issue: GitHub.