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

  1. Remove negative ids; use [] or None for 'auto/all' selection instead of -1.
  2. Fix the caller computing ids so it clamps to >= 0.
  3. 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

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


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/23a889640465e153. Report an issue: GitHub.