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
- 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())".
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
- 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.
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
- Tokenizer returned unexpected types.
- configure_torch_cuda_allocator() must be called before impor
- Attempted to configure the PyTorch CUDA memory allocator, bu
- Failed to configure the PyTorch CUDA memory allocator. Expec
- Unexpected cond image shape: {tuple(rgb_bchw_01.shape)} (exp
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/571e65aba431698e.
Report an issue: GitHub.