sgl-project/sglang · error · ValueError
num_inference_steps must be positive, got {steps}
Error message
num_inference_steps must be positive, got {steps} What it means
LTX-2's prepare_sigmas builds the sigma schedule [1 - i/steps] when no explicit sigmas are passed; a non-positive num_inference_steps (0 or negative) would produce an empty/invalid schedule, so it is rejected up front.
Source
Thrown at python/sglang/multimodal_gen/configs/pipeline_configs/ltx_2.py:262
# two logical encoders sharing the same underlying `text_encoder` module.
text_encoder_configs: tuple[EncoderConfig, ...] = field(
default_factory=lambda: (Gemma3Config(),)
)
text_encoder_precisions: tuple[str, ...] = field(default_factory=lambda: ("bf16",))
text_encoder_extra_args: list[dict] = field(default_factory=lambda: [{}])
preprocess_text_funcs: tuple[Callable[[str], str] | None, ...] = field(
default_factory=lambda: (None,)
)
postprocess_text_funcs: tuple[
Callable[[BaseEncoderOutput, dict], torch.Tensor], ...
] = field(default_factory=lambda: (_gemma_postprocess_func,))
def prepare_sigmas(self, sigmas, num_inference_steps):
if sigmas is None:
steps = int(num_inference_steps)
if steps <= 0:
raise ValueError(f"num_inference_steps must be positive, got {steps}")
return [1.0 - i / steps for i in range(steps)]
return sigmas
def tokenize_prompt(self, prompt: list[str], tokenizer, tok_kwargs) -> dict:
# Adapted from diffusers_pipeline.py _get_gemma_prompt_embeds
# But we only need tokenization here, the embedding happens in TextEncodingStage
# Official LTX Gemma tokenizer trims surrounding whitespace before
# tokenization.
prompt = [text.strip() for text in prompt]
# Gemma expects left padding for chat-style prompts
tokenizer.padding_side = "left"
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
max_sequence_length = tok_kwargs.get(
"max_length", 1024
) # Default from diffusers pipelineView on GitHub (pinned to 0132848349)
Solutions
- Set num_inference_steps to a positive integer (typically 20-50 for LTX-2)
- If computing steps from strength, clamp: max(1, int(strength * total_steps))
- Pass an explicit sigmas list if you want to bypass step-count schedule generation
- Validate request params before submission
Example fix
# before steps = int(strength * num_inference_steps) # 0 when strength small out = pipe(prompt, num_inference_steps=steps) # after steps = max(1, int(strength * num_inference_steps)) out = pipe(prompt, num_inference_steps=steps)
Defensive patterns
Strategy: validation
Validate before calling
num_inference_steps = max(1, int(num_inference_steps)) assert num_inference_steps > 0
Try / catch
except ValueError as e:
if "num_inference_steps must be positive" in str(e):
pipe(prompt, num_inference_steps=30) # sane default retry Prevention
- Clamp strength-derived step counts with max(1, ...)
- Validate request schema client-side
- Default num_inference_steps in config, never 0
When it happens
Trigger: Calling generation with sigmas=None and num_inference_steps <= 0 — e.g. 0, -1, or a value that int() truncates to 0 (like 0.5).
Common situations: num_inference_steps read from a config/CLI where the default was never set (0), computed as steps = strength * total and rounding to 0 at low strength, or a typo/negative value in request parameters.
Related errors
- padding_side must be 'left' or 'right', got {padding_side}
- Unsupported content type ${header.content_type}
- Unknown serve backend {name!r}. Available values: {available
- k_cache can only be None when only_qv=True
- q can only be None when only_qv=True
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/214fdd98201c400c.
Report an issue: GitHub.