sgl-project/sglang · critical · ValueError
MiniMax H3 Ulysses size must be positive.
Error message
MiniMax H3 Ulysses size must be positive.
What it means
The Ulysses sequence-parallel degree must be a positive integer. Ulysses shards the packed sequence among attention ranks, so a zero/negative degree breaks all local-shape arithmetic; validation runs in __init__ via _validate_sequence_parallel_config.
Source
Thrown at python/sglang/multimodal_gen/runtime/models/dits/minimax_h3.py:1839
("video_patch_output_dim", arch.latents_dim * math.prod(arch.patch_size)),
("audio_patch_output_dim", arch.audio_latents_dim),
):
if value % tp_size:
raise ValueError(
f"MiniMax H3 {name}={value} must be divisible by "
f"TP size {tp_size}."
)
@staticmethod
def _validate_sequence_parallel_config(
*,
arch: MiniMaxH3DiTArchConfig,
tp_size: int,
ulysses_size: int,
ring_size: int,
) -> None:
if ulysses_size <= 0:
raise ValueError("MiniMax H3 Ulysses size must be positive.")
if ring_size <= 0:
raise ValueError("MiniMax H3 ring size must be positive.")
local_heads = arch.num_attention_heads // tp_size
if local_heads % ulysses_size:
raise ValueError(
f"MiniMax H3 TP-local heads {local_heads} must be divisible by "
f"Ulysses size {ulysses_size} (total heads="
f"{arch.num_attention_heads}, TP={tp_size})."
)
# ring never shards heads (only rows), so it has no head-divisibility
# constraint; the packed sequence alignment constant must still
# divide the *combined* sequence-parallel size, since ring adds an
# outer row split on top of Ulysses's inner one (see forward()).
sp_size = ulysses_size * ring_size
if MINIMAX_H3_PACKED_SEQUENCE_ALIGNMENT % sp_size:
raise ValueError(
"MiniMax H3 packed sequence alignment "
f"{MINIMAX_H3_PACKED_SEQUENCE_ALIGNMENT} must be divisible by "View on GitHub (pinned to 0132848349)
Solutions
- Set ulysses_size to 1 (disabled) or a positive divisor of TP-local heads
- Audit the flag parsing: treat empty/None as 1, not 0
- Verify ulysses_size <= num_attention_heads // tp_size
Example fix
# before
ulysses_size=int(os.getenv("ULYSSES", "")) # 0
# after
ulysses_size=int(os.getenv("ULYSSES") or 1) Defensive patterns
Strategy: validation
Validate before calling
ulysses_size = int(os.getenv("ULYSSES") or 1)
assert ulysses_size > 0 and (arch.num_attention_heads // tp_size) % ulysses_size == 0 Type guard
def ulysses_ok(u: int) -> bool:
return isinstance(u, int) and u >= 1 Prevention
- Treat empty/missing SP flags as 1
- Compute ulysses only after tp_size is resolved
When it happens
Trigger: Passing ulysses_size=0 or negative to the model constructor — commonly from an unset CLI flag defaulting to 0, or deriving it as heads // something that evaluated to 0.
Common situations: --ulysses-size left unset and coerced to int('')/0; scripts computing ulysses = local_heads // heads_per_rank before distributed init.
Related errors
- MiniMax H3 ring size must be positive.
- Invalid threshold_type for topk: {threshold_type}. Choose 'q
- Invalid threshold_type: {threshold_type}. Choose 'query_head
- f"Unknown feature map: {feature_map}"
- f"Unsupported patch_size type: {type(patch_size)}"
AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28).
Data as JSON: /api/errors/3fd000f00f9a8e61.
Report an issue: GitHub.