invoke-ai/InvokeAI · error · ValueError

generation_devices requested '{device_str}', but MPS is not

Error message

generation_devices requested '{device_str}', but MPS is not available.

What it means

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.

Source

Thrown at invokeai/backend/util/devices.py:312

            # valid indices, so this just validates explicitly-configured devices.)
            if device.type == "cuda":
                if not torch.cuda.is_available():
                    raise ValueError(f"generation_devices requested '{device_str}', but no CUDA device is available.")
                if device.index is not None and device.index >= torch.cuda.device_count():
                    raise ValueError(
                        f"generation_devices requested '{device_str}', but only {torch.cuda.device_count()} "
                        f"CUDA device(s) are available (valid indices 0-{torch.cuda.device_count() - 1})."
                    )
            elif device.type == "xpu":
                if not _xpu_is_available():
                    raise ValueError(f"generation_devices requested '{device_str}', but no XPU device is available.")
                if device.index is not None and device.index >= torch.xpu.device_count():
                    raise ValueError(
                        f"generation_devices requested '{device_str}', but only {torch.xpu.device_count()} "
                        f"XPU device(s) are available (valid indices 0-{torch.xpu.device_count() - 1})."
                    )
            elif device.type == "mps" and not torch.backends.mps.is_available():
                raise ValueError(f"generation_devices requested '{device_str}', but MPS is not available.")
            if str(device) not in seen:
                seen.add(str(device))
                devices.append(device)
        return devices

    @classmethod
    def normalize(cls, device: Union[str, torch.device]) -> torch.device:
        """Add the device index to CUDA and XPU devices."""
        device = torch.device(device)
        if device.index is None and device.type == "cuda" and torch.cuda.is_available():
            device = torch.device(device.type, torch.cuda.current_device())
        elif device.index is None and device.type == "xpu" and _xpu_is_available():
            device = torch.device(device.type, torch.xpu.current_device())
        return device

    @classmethod
    def empty_cache(cls) -> None:
        """Clear the GPU device cache."""

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Set generation_devices/device to 'auto' (or 'cpu') in invokeai.yaml so the resolver picks an actually available device.
  2. 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).
  3. If CUDA/XPU hardware exists, change the config to 'cuda' or 'xpu' instead of 'mps'.
  4. Verify availability before launch with: python -c "import torch; print(torch.backends.mps.is_available())".

Example fix

// before (invokeai.yaml)
generation_devices:
  - mps
// after
 generation_devices:
  - auto   # or 'cpu' on machines without Apple Silicon MPS
Defensive patterns

Strategy: validation

Validate before calling

import torch
def mps_requested_and_unavailable(generation_devices):
    if generation_devices == 'auto':
        return False
    for d in (generation_devices or []):
        if str(d).startswith('mps') and not torch.backends.mps.is_available():
            return True
    return False

if mps_requested_and_unavailable(cfg.generation_devices):
    cfg.generation_devices = ['auto']  # or ['cpu']

Type guard

def mps_available() -> bool:
    import torch
    return torch.backends.mps.is_available()

Try / catch

try:
    devices = TorchDevice.get_generation_devices(cfg.generation_devices)
except ValueError as e:
    if 'MPS is not available' in str(e):
        logger.warning('MPS requested but unavailable; falling back to auto')
        devices = TorchDevice.get_generation_devices('auto')
    else:
        raise

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/571e65aba431698e. Report an issue: GitHub.