unslothai/unsloth · error · ValueError
tensor_split must have a positive total
Error message
tensor_split must have a positive total
What it means
Raised by the same tensor_split validator after the per-entry check passes: the sum of all entries must be strictly positive. An all-zero (or all entries summing to 0) list is degenerate — it would be silently dropped at launch yet keep triggering reload-dedupe comparisons, so it is rejected as a 422.
Source
Thrown at studio/backend/models/inference.py:262
# folding into the int core schema, and they leak into OpenAPI as ge/le.
if isinstance(value, bool):
raise ValueError("Expected a number, got a boolean.")
return value
@field_validator("tensor_split")
@classmethod
def _reject_degenerate_tensor_split(cls, value: Optional[List[float]]) -> Optional[List[float]]:
# A negative / non-finite / all-zero split is silently dropped at launch
# (stored as None) yet still compared raw in the reload dedupe, so an
# identical Apply reloads forever. Reject it up front; [] = no split.
if not value:
return value
import math
if any((not math.isfinite(v)) or v < 0 for v in value):
raise ValueError("tensor_split entries must be finite and non-negative")
if sum(value) <= 0:
raise ValueError("tensor_split must have a positive total")
return value
llama_extra_args: Optional[List[str]] = Field(
None,
description = (
"Extra arguments forwarded verbatim to llama-server for GGUF models. "
"One token per list entry, e.g. ['--top-k', '20', '--seed', '42']. "
"Unsloth-managed flags (model identity, port, context length, GPU placement, "
"auth, UI/server mode) are rejected. Ignored for non-GGUF models."
),
)
force_cancel_active: bool = Field(
False,
description = (
"Stop chats still generating instead of refusing with 409. A load "
"replaces the llama-server every open conversation decodes on."
),
)View on GitHub (pinned to 203007d190)
Solutions
- If you meant 'no tensor split', send [] or omit tensor_split entirely.
- If you meant to disable a GPU, weight the others positively, e.g. [0, 1, 1].
- Fix the client's GPU-probing fallback to emit an empty list when no GPUs are detected.
Example fix
# before
payload = {"tensor_split": [0, 0]}
# after
payload = {"tensor_split": []} # or omit the key entirely Defensive patterns
Strategy: validation
Validate before calling
def sanitize_split(split: list[float] | None) -> list[float] | None:
if not split or sum(split) <= 0:
return None # normalize degenerate splits to 'no split'
return split Prevention
- Treat all-zero GPU splits as 'no GPUs detected' and omit the field
- Disable a GPU with weight 0 only alongside at least one positive entry
- Unit-test split builders against the empty-GPU case
When it happens
Trigger: Sending tensor_split: [0, 0] or [0.0, 0.0] (entries pass the finite/non-negative check but total 0). A single positive entry avoids it; [] means 'no split' and is allowed.
Common situations: Auto-probing code that builds a split from detected GPUs and finds none, yielding a list of zeros instead of an empty list; placeholder configs shipped with zeros; users trying to 'disable' one GPU with 0 while the other is also 0.
Related errors
- tensor_split entries must be finite and non-negative
- Expected a number, got a boolean.
- too many extra llama-server args (limit {MAX_EXTRA_ARG_TOKEN
- extra llama-server args cannot contain unpaired surrogate ch
- extra llama-server args are too large (limit {limit} bytes)
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/9bb0ec1784b64dc1.
Report an issue: GitHub.