{"record":{"id":"571e65aba431698e","repo":"invoke-ai/InvokeAI","slug":"generation-devices-requested-device-str-but-m","errorCode":null,"errorMessage":"generation_devices requested '{device_str}', but MPS is not available.","messagePattern":"generation_devices requested '(.+?)', but MPS is not available\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/util/devices.py","lineNumber":312,"sourceCode":"            # valid indices, so this just validates explicitly-configured devices.)\n            if device.type == \"cuda\":\n                if not torch.cuda.is_available():\n                    raise ValueError(f\"generation_devices requested '{device_str}', but no CUDA device is available.\")\n                if device.index is not None and device.index >= torch.cuda.device_count():\n                    raise ValueError(\n                        f\"generation_devices requested '{device_str}', but only {torch.cuda.device_count()} \"\n                        f\"CUDA device(s) are available (valid indices 0-{torch.cuda.device_count() - 1}).\"\n                    )\n            elif device.type == \"xpu\":\n                if not _xpu_is_available():\n                    raise ValueError(f\"generation_devices requested '{device_str}', but no XPU device is available.\")\n                if device.index is not None and device.index >= torch.xpu.device_count():\n                    raise ValueError(\n                        f\"generation_devices requested '{device_str}', but only {torch.xpu.device_count()} \"\n                        f\"XPU device(s) are available (valid indices 0-{torch.xpu.device_count() - 1}).\"\n                    )\n            elif device.type == \"mps\" and not torch.backends.mps.is_available():\n                raise ValueError(f\"generation_devices requested '{device_str}', but MPS is not available.\")\n            if str(device) not in seen:\n                seen.add(str(device))\n                devices.append(device)\n        return devices\n\n    @classmethod\n    def normalize(cls, device: Union[str, torch.device]) -> torch.device:\n        \"\"\"Add the device index to CUDA and XPU devices.\"\"\"\n        device = torch.device(device)\n        if device.index is None and device.type == \"cuda\" and torch.cuda.is_available():\n            device = torch.device(device.type, torch.cuda.current_device())\n        elif device.index is None and device.type == \"xpu\" and _xpu_is_available():\n            device = torch.device(device.type, torch.xpu.current_device())\n        return device\n\n    @classmethod\n    def empty_cache(cls) -> None:\n        \"\"\"Clear the GPU device cache.\"\"\"","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/util/devices.py#L294-L330","documentation":"get_generation_devices() in invokeai/backend/util/devices.py validates every device string from the `generation_devices` config (or the legacy `device:` setting) and raises this ValueError when a requested torch.device has type 'mps' but torch.backends.mps.is_available() is False. MPS (Metal Performance Shaders) is Apple-GPU acceleration, only present on macOS builds of PyTorch with an Apple Silicon GPU. The check fails fast at config load/startup instead of letting a worker crash later at the first tensor allocation.","triggerScenarios":"Calling get_generation_devices with a config where generation_devices (or the legacy device: field) is 'mps' or 'mps:N' while running on a non-macOS machine, on macOS with an Intel CPU (no Apple Silicon GPU), on a PyTorch build without MPS support, or when MPS is disabled (e.g. via PYTORCH_ENABLE_MPS_FALLBACK absent isn't relevant here, but torch.backends.mps.is_available() returns False when the framework is missing).","commonSituations":"Sharing one invokeai.yaml across Linux/CUDA servers and a Mac; a stale pinned `device: mps` left in the config after moving the install; running in a Linux Docker container with a copied macOS config; an old torch wheel compiled without MPS.","solutions":["Set generation_devices/device to 'auto' (or 'cpu') in invokeai.yaml so the resolver picks an actually available device.","If you expect Apple GPU acceleration, run on macOS on Apple Silicon with a PyTorch build that includes MPS (torch >= 1.12, native arm64 wheel).","If CUDA/XPU hardware exists, change the config to 'cuda' or 'xpu' instead of 'mps'.","Verify availability before launch with: python -c \"import torch; print(torch.backends.mps.is_available())\"."],"exampleFix":"// before (invokeai.yaml)\ngeneration_devices:\n  - mps\n// after\n generation_devices:\n  - auto   # or 'cpu' on machines without Apple Silicon MPS","handlingStrategy":"validation","validationCode":"import torch\ndef mps_requested_and_unavailable(generation_devices):\n    if generation_devices == 'auto':\n        return False\n    for d in (generation_devices or []):\n        if str(d).startswith('mps') and not torch.backends.mps.is_available():\n            return True\n    return False\n\nif mps_requested_and_unavailable(cfg.generation_devices):\n    cfg.generation_devices = ['auto']  # or ['cpu']","typeGuard":"def mps_available() -> bool:\n    import torch\n    return torch.backends.mps.is_available()","tryCatchPattern":"try:\n    devices = TorchDevice.get_generation_devices(cfg.generation_devices)\nexcept ValueError as e:\n    if 'MPS is not available' in str(e):\n        logger.warning('MPS requested but unavailable; falling back to auto')\n        devices = TorchDevice.get_generation_devices('auto')\n    else:\n        raise","preventionTips":["Use generation_devices: 'auto' instead of hardcoding mps in shared configs.","Check torch.backends.mps.is_available() in a startup smoke test before launching workers.","Keep per-machine config overrides (env-specific yaml) rather than one global device pin.","Run invokeai on native arm64 PyTorch wheels on Apple Silicon if MPS is the intent."],"tags":["pytorch","device-configuration","mps","macos"],"backgroundTag":"device-not-available","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}