Lightning-AI/pytorch-lightning · error · TypeError

Device IDs (GPU/TPU) must be an int, a string, a sequence of

Error message

Device IDs (GPU/TPU) must be an int, a string, a sequence of ints, but you passed a sequence of {type(id_).__name__}.

What it means

When devices is a sequence, Lightning requires every element to be a real int (checked with type(id_) is int, so bools and numpy integers fail too). If any element is another type, TypeError is raised naming the offending element's type. This guards the parser from ambiguous inputs like ['0','1'], [True, False], or numpy arrays.

Source

Thrown at src/lightning/fabric/utilities/device_parser.py:204

def _check_data_type(device_ids: object) -> None:
    """Checks that the device_ids argument is one of the following: int, string, or sequence of integers.

    Args:
        device_ids: gpus/tpu_cores parameter as passed to the Trainer

    Raises:
        TypeError:
            If ``device_ids`` of GPU/TPUs aren't ``int``, ``str`` or sequence of ``int```

    """
    msg = "Device IDs (GPU/TPU) must be an int, a string, a sequence of ints, but you passed"
    if device_ids is None:
        raise TypeError(f"{msg} None")
    if isinstance(device_ids, (MutableSequence, tuple)):
        for id_ in device_ids:
            id_type = type(id_)  # because `isinstance(False, int)` -> True
            if id_type is not int:
                raise TypeError(f"{msg} a sequence of {type(id_).__name__}.")
    elif type(device_ids) not in (int, str):
        raise TypeError(f"{msg} {device_ids!r}.")


def _select_auto_accelerator() -> str:
    """Choose the accelerator type (str) based on availability."""
    from lightning.fabric.accelerators.cuda import CUDAAccelerator
    from lightning.fabric.accelerators.mps import MPSAccelerator
    from lightning.fabric.accelerators.xla import XLAAccelerator

    if XLAAccelerator.is_available():
        return "tpu"
    if MPSAccelerator.is_available():
        return "mps"
    if CUDAAccelerator.is_available():
        return "cuda"
    return "cpu"

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Convert elements to int: devices=[int(d) for d in devices] or list(map(int, devices))
  2. For string specs use the string form devices='0,1' instead of a list of strings
  3. Cast numpy arrays: devices=device_array.tolist()

Example fix

# before
Fabric(accelerator="gpu", devices=np.array([0, 1]))  # np.int64 elements

# after
Fabric(accelerator="gpu", devices=[int(d) for d in np.array([0, 1])])
Defensive patterns

Strategy: validation

Validate before calling

devices = [int(d) for d in devices] if isinstance(devices, (list, tuple)) else devices
assert all(type(d) is int and not isinstance(d, bool) for d in devices)

Type guard

def is_int_sequence(d) -> bool:
    return isinstance(d, (list, tuple)) and all(type(x) is int for x in d)

Prevention

When it happens

Trigger: devices=['0', '1'] (strings inside a list); devices=[True, False]; devices=np.array([0, 1]) (elements are np.int64, not int); devices=[0.0, 1.0] floats.

Common situations: Parsing device ids from CLI/config as strings and not converting to int; passing numpy arrays or numpy ints from scientific pipelines; JSON configs where ids become strings.

Related errors


AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28). Data as JSON: /api/errors/14d229d74f97897b. Report an issue: GitHub.