{"record":{"id":"5affc98bac599e7e","repo":"unslothai/unsloth","slug":"invalid-gpu-ids-requested-ids-duplicate-gpu-ids-5affc9","errorCode":null,"errorMessage":"Invalid gpu_ids {requested_ids}: duplicate GPU IDs are not allowed. Parent-visible GPUs: {parent_visible_ids}","messagePattern":"Invalid gpu_ids (.+?): duplicate GPU IDs are not allowed\\. Parent-visible GPUs: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/utils/hardware/hardware.py","lineNumber":2783,"sourceCode":"            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        )\n\n    if len(set(requested_ids)) != len(requested_ids):\n        raise ValueError(\n            f\"Invalid gpu_ids {requested_ids}: duplicate GPU IDs are not allowed. \"\n            f\"Parent-visible GPUs: {parent_visible_ids}\"\n        )\n\n    # Reject negative IDs.\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}. Parent-visible GPUs: {parent_visible_ids}\"\n        )\n\n    # Only enforce the physical upper bound when the count is reliable (nvidia-smi).\n    # A torch count reflects only visible devices, so it could falsely reject valid\n    # physical indices. The parent-visible check below is always authoritative.\n    if physical_gpu_count > 0 and parent_visible_ids:\n        max_parent_id = max(parent_visible_ids)\n        if physical_gpu_count > max_parent_id:","sourceCodeStart":2765,"sourceCodeEnd":2801,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/hardware/hardware.py#L2765-L2801","documentation":"Raised on the CUDA/ROCm/XPU path (after the env-var mask was confirmed numeric) when requested gpu_ids contain duplicates. The message also lists the parent-visible GPU ids so the user can see the valid id space. Distinct from the Vulkan duplicate error: this one can cross-check against the parent-visible set.","triggerScenarios":"Calling resolve_requested_gpu_ids([0, 0]) or any list with repeats while CUDA_VISIBLE_DEVICES (or ZE_AFFINITY_MASK) is numeric or unset.","commonSituations":"Merging a default gpu list with a user-provided one ([0] + [0,1]); multi-select UI bugs re-submitting an id; hand-edited JSON/YAML configs; scripts appending ids in a loop without dedup.","solutions":["Deduplicate before calling: sorted(set(gpu_ids)) (order preserved with dict.fromkeys if order matters).","Fix the config merge that introduced the duplicate.","Use each physical GPU id exactly once."],"exampleFix":"# before\nresolve_requested_gpu_ids([0, 0, 1])  # ValueError\n\n# after\nresolve_requested_gpu_ids(list(dict.fromkeys([0, 0, 1])))  # [0, 1]","handlingStrategy":"validation","validationCode":"def dedup_ids(ids):\n    return list(dict.fromkeys(int(i) for i in ids))\n\n# resolve_requested_gpu_ids(dedup_ids(gpu_ids))","typeGuard":"def is_valid_gpu_id_list(ids) -> bool:\n    return (\n        isinstance(ids, (list, tuple))\n        and all(isinstance(i, int) and i >= 0 for i in ids)\n        and len(set(ids)) == len(ids)\n    )","tryCatchPattern":null,"preventionTips":["Deduplicate GPU id lists at config load time.","Avoid concatenating default + user id lists without a set merge.","Validate ids against the parent-visible set (shown in the error) before launching jobs."],"tags":["gpu","cuda","hardware","validation","config"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}