Lightning-AI/pytorch-lightning · error · MisconfigurationException

device is expected to be a torch.device or a str. Found {dev

Error message

device is expected to be a torch.device or a str. Found {device}

What it means

The optional `device` argument of StochasticWeightAveraging (where the SWA-averaged model copy is kept) must be a torch.device or a str. Any other type (int, None is allowed) raises this MisconfigurationException at construction.

Source

Thrown at src/lightning/pytorch/callbacks/stochastic_weight_avg.py:116

        """

        err_msg = "swa_epoch_start should be a >0 integer or a float between 0 and 1."
        if isinstance(swa_epoch_start, int) and swa_epoch_start < 1:
            raise MisconfigurationException(err_msg)
        if isinstance(swa_epoch_start, float) and not (0 <= swa_epoch_start <= 1):
            raise MisconfigurationException(err_msg)

        wrong_type = not isinstance(swa_lrs, (float, list))
        wrong_float = isinstance(swa_lrs, float) and swa_lrs <= 0
        wrong_list = isinstance(swa_lrs, list) and not all(lr > 0 and isinstance(lr, float) for lr in swa_lrs)
        if wrong_type or wrong_float or wrong_list:
            raise MisconfigurationException("The `swa_lrs` should a positive float, or a list of positive floats")

        if avg_fn is not None and not callable(avg_fn):
            raise MisconfigurationException("The `avg_fn` should be callable.")

        if device is not None and not isinstance(device, (torch.device, str)):
            raise MisconfigurationException(f"device is expected to be a torch.device or a str. Found {device}")

        self.n_averaged: Optional[Tensor] = None
        self._swa_epoch_start = swa_epoch_start
        self._swa_lrs = swa_lrs
        self._annealing_epochs = annealing_epochs
        self._annealing_strategy = annealing_strategy
        self._avg_fn = avg_fn or self.avg_fn
        self._device = device
        self._model_contains_batch_norm: Optional[bool] = None
        self._average_model: Optional[pl.LightningModule] = None
        self._initialized = False
        self._swa_scheduler: Optional[LRScheduler] = None
        self._scheduler_state: Optional[dict] = None
        self._init_n_averaged = 0
        self._latest_update_epoch = -1
        self.momenta: dict[nn.modules.batchnorm._BatchNorm, Optional[float]] = {}
        self._max_epochs: int

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Use SWA(device='cuda') or SWA(device=torch.device('cuda'))
  2. For a specific GPU: SWA(device='cuda:0')
  3. Or omit device to keep the averaged model on CPU by default

Example fix

# before
swa = SWA(device=0)
# after
swa = SWA(device="cuda:0")  # or torch.device("cuda:0")
Defensive patterns

Strategy: validation

Validate before calling

import torch
device = None if cfg.device is None else str(cfg.device)  # coerce to str/torch.device
assert device is None or isinstance(device, (str, torch.device))
swa = SWA(device=device)

Type guard

def is_valid_device(d) -> bool:
    return d is None or isinstance(d, (str, torch.device))

Prevention

When it happens

Trigger: SWA(device=0) intending GPU index 0, or passing a torch.cuda device object of another library type.

Common situations: Migrating from an API that accepted a device index integer; passing device=0 copied from Trainer(accelerator='gpu', devices=[0]) style configs.

Related errors


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