{"record":{"id":"bea913c0e4877d5b","repo":"unslothai/unsloth","slug":"invalid-gpu-ids-requested-ids-duplicate-gpu-ids","errorCode":null,"errorMessage":"Invalid gpu_ids {requested_ids}: duplicate GPU IDs are not allowed.","messagePattern":"Invalid gpu_ids (.+?): duplicate GPU IDs are not allowed\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/utils/hardware/hardware.py","lineNumber":2762,"sourceCode":") -> list[int]:\n    parent_visible_spec = _get_parent_visible_gpu_spec()\n    parent_visible_ids = get_parent_visible_gpu_ids()\n    physical_gpu_count = get_physical_gpu_count()\n\n    if gpu_ids is None:\n        return [] if is_vulkan else parent_visible_ids\n\n    requested_ids = list(gpu_ids)\n    if len(requested_ids) == 0:\n        return [] if is_vulkan else parent_visible_ids\n\n    if is_vulkan:\n        # A Vulkan build selects by ggml Vulkan ordinal (--device VulkanN), a separate\n        # index space from CUDA/ROCm ids that may be empty under CPU-only torch. The\n        # CUDA parent-visible / physical-count checks below do not apply; only reject\n        # malformed ordinals (issue #7239).\n        if len(set(requested_ids)) != len(requested_ids):\n            raise ValueError(f\"Invalid gpu_ids {requested_ids}: duplicate GPU IDs are not allowed.\")\n        negative_ids = [gpu_id for gpu_id in requested_ids if gpu_id < 0]\n        if negative_ids:\n            raise ValueError(\n                f\"Invalid gpu_ids {requested_ids}: GPU IDs must be non-negative. \"\n                f\"Rejected IDs: {negative_ids}.\"\n            )\n        return requested_ids\n\n    if not parent_visible_spec[\"supports_explicit_gpu_ids\"]:\n        env_var_name = (\n            \"ZE_AFFINITY_MASK\" if get_device() == DeviceType.XPU else \"CUDA_VISIBLE_DEVICES\"\n        )\n        raise ValueError(\n            f\"Invalid gpu_ids {requested_ids}: explicit physical GPU IDs are \"\n            f\"unsupported when {env_var_name} uses non-numeric or subdevice \"\n            f\"entries ({parent_visible_spec['raw']!r}). Omit gpu_ids to use \"\n            \"the parent-visible devices.\"\n        )","sourceCodeStart":2744,"sourceCodeEnd":2780,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/hardware/hardware.py#L2744-L2780","documentation":"Raised during GPU ID validation on the Vulkan path (llama.cpp Vulkan builds) when the requested gpu_ids list contains the same Vulkan ordinal twice. Vulkan selects devices by ggml ordinal (--device VulkanN), a separate index space from CUDA/ROCm ids, so only basic well-formedness checks (duplicates, negatives) apply — there is no parent-visible or physical-count cross-check on this path.","triggerScenarios":"Calling resolve_requested_gpu_ids([0, 0]) or any gpu_ids list with a repeated element while the active device backend is Vulkan.","commonSituations":"Config files where a default id list got concatenated with a user-specified one (e.g. [0] + [0, 1]); UI multi-select allowing duplicate submissions; hand-edited YAML/JSON with copy-paste duplication.","solutions":["Deduplicate the gpu_ids list before passing it: sorted(set(gpu_ids)).","Fix the config/UI layer that produced the duplicated ids.","Use distinct Vulkan ordinals, one per device you want to use (e.g. [0, 1])."],"exampleFix":"# before\napply_gpu_ids([0, 0])  # ValueError: duplicate GPU IDs are not allowed\n\n# after\napply_gpu_ids(sorted(set([0, 0])))  # -> [0]","handlingStrategy":"validation","validationCode":"def normalize_gpu_ids(ids):\n    \"\"\"Dedup while preserving order.\"\"\"\n    return list(dict.fromkeys(ids))\n\n# guard: resolve_requested_gpu_ids(normalize_gpu_ids(gpu_ids))","typeGuard":"def are_unique_non_negative_ints(ids) -> bool:\n    return (\n        isinstance(ids, (list, tuple))\n        and all(isinstance(i, int) for i in ids)\n        and len(set(ids)) == len(ids)\n        and all(i >= 0 for i in ids)\n    )","tryCatchPattern":null,"preventionTips":["Deduplicate gpu id lists before any hardware API call.","Use set operations when merging default and user GPU selections.","Reject duplicate selections in UI multi-selects.","Remember Vulkan uses its own ordinal space — do not reuse CUDA id logic blindly."],"tags":["gpu","vulkan","hardware","validation","config"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}