unslothai/unsloth · error · ValueError
Invalid gpu_ids {requested_ids}: GPU IDs must be non-negativ
Error message
Invalid gpu_ids {requested_ids}: GPU IDs must be non-negative. Rejected IDs: {negative_ids}. What it means
Raised on the Vulkan validation path when any requested GPU ordinal is negative. The error lists every rejected negative id. Like the duplicate check, this is a pure well-formedness guard because Vulkan ordinals have no parent-visible set to validate against (issue #7239 regression guard).
Source
Thrown at studio/backend/utils/hardware/hardware.py:2765
physical_gpu_count = get_physical_gpu_count()
if gpu_ids is None:
return [] if is_vulkan else parent_visible_ids
requested_ids = list(gpu_ids)
if len(requested_ids) == 0:
return [] if is_vulkan else parent_visible_ids
if is_vulkan:
# A Vulkan build selects by ggml Vulkan ordinal (--device VulkanN), a separate
# index space from CUDA/ROCm ids that may be empty under CPU-only torch. The
# CUDA parent-visible / physical-count checks below do not apply; only reject
# malformed ordinals (issue #7239).
if len(set(requested_ids)) != len(requested_ids):
raise ValueError(f"Invalid gpu_ids {requested_ids}: duplicate GPU IDs are not allowed.")
negative_ids = [gpu_id for gpu_id in requested_ids if gpu_id < 0]
if negative_ids:
raise ValueError(
f"Invalid gpu_ids {requested_ids}: GPU IDs must be non-negative. "
f"Rejected IDs: {negative_ids}."
)
return requested_ids
if not parent_visible_spec["supports_explicit_gpu_ids"]:
env_var_name = (
"ZE_AFFINITY_MASK" if get_device() == DeviceType.XPU else "CUDA_VISIBLE_DEVICES"
)
raise ValueError(
f"Invalid gpu_ids {requested_ids}: explicit physical GPU IDs are "
f"unsupported when {env_var_name} uses non-numeric or subdevice "
f"entries ({parent_visible_spec['raw']!r}). Omit gpu_ids to use "
"the parent-visible devices."
)
if len(set(requested_ids)) != len(requested_ids):
raise ValueError(View on GitHub (pinned to 203007d190)
Solutions
- Remove negative ids; use [] or None for 'auto/all' selection instead of -1.
- Fix the caller computing ids so it clamps to >= 0.
- Check the config file for a -1 placeholder and replace it with an empty list.
Example fix
# before gpu_ids = [-1] # CUDA-style 'all' convention -> ValueError on Vulkan # after gpu_ids = [] # auto-select on Vulkan
Defensive patterns
Strategy: validation
Validate before calling
def valid_vulkan_ids(ids):
return all(isinstance(i, int) and i >= 0 for i in ids) and len(set(ids)) == len(ids) Type guard
def are_valid_vulkan_ordinals(ids) -> bool:
return (
isinstance(ids, (list, tuple))
and len(ids) > 0
and all(isinstance(i, int) and i >= 0 for i in ids)
and len(set(ids)) == len(ids)
) Prevention
- Never use -1 to mean 'all GPUs' on Vulkan — use auto-select (None/[]).
- Clamp computed GPU indices to >= 0.
- Treat unset config values as empty lists, not -1 sentinels.
When it happens
Trigger: Calling resolve_requested_gpu_ids([-1]) or any list containing a negative id under the Vulkan backend, e.g. someone using CUDA-style '-1 means all' semantics.
Common situations: Porting CUDA conventions (-1 = all GPUs) to a Vulkan build; off-by-one index math producing -1; parsing a config where an unset value defaulted to -1.
Related errors
- Invalid gpu_ids {requested_ids}: duplicate GPU IDs are not a
- Invalid gpu_ids {requested_ids}: duplicate GPU IDs are not a
- Invalid gpu_ids {requested_ids}: GPU IDs must be non-negativ
- This trainer requires a bfloat16-capable GPU (Ampere or newe
- tensor_split entries must be finite and non-negative
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/23a889640465e153.
Report an issue: GitHub.