Lightning-AI/pytorch-lightning · error · TypeError
`devices` selected with `CPUAccelerator` should be an int >
Error message
`devices` selected with `CPUAccelerator` should be an int > 0.
What it means
When a logged metric has sync_dist=True (or is otherwise a torchmetrics Metric), Lightning calls the metric's .compute() and expects a single torch.Tensor back. This ValueError is thrown in _get_cache when the computed cache exists but is not a Tensor (e.g. a tuple, dict, list, or number).
Source
Thrown at src/lightning/fabric/accelerators/cpu.py:99
"""Parses the cpu_cores given in the format as accepted by the ``devices`` argument in the
:class:`~lightning.pytorch.trainer.trainer.Trainer`.
Args:
cpu_cores: An int > 0 or a string that can be converted to an int > 0.
Returns:
An int representing the number of processes
Raises:
MisconfigurationException:
If cpu_cores is not an int > 0
"""
if isinstance(cpu_cores, str) and cpu_cores.strip().isdigit():
cpu_cores = int(cpu_cores)
if not isinstance(cpu_cores, int) or cpu_cores <= 0:
raise TypeError("`devices` selected with `CPUAccelerator` should be an int > 0.")
return cpu_cores
View on GitHub (pinned to 9fed5c27d2)
Solutions
- Make the custom Metric.compute() return a single torch.Tensor (stack/cat or index into the collection)
- Split multi-output metrics into separate Metric instances, one per scalar, each logged with its own name
- Return a scalar tensor: e.g. return loss.item() -> return torch.tensor(loss) is wrong; return loss if loss is already a tensor
Example fix
# before
class MyMetric(Metric):
def compute(self):
return self.tp, self.fp # tuple -> raises
# after
class MyMetric(Metric):
def compute(self):
return torch.stack([self.tp.float(), self.fp.float()])
# or two separate metrics logged under distinct names Defensive patterns
Strategy: validation
Validate before calling
import torch
from torchmetrics import Metric
def compute_is_tensor(metric: Metric) -> bool:
out = metric.compute()
return isinstance(out, torch.Tensor) Type guard
from torch import Tensor
from torchmetrics import Metric
def metric_returns_tensor(m: Metric) -> bool:
try:
return isinstance(m.compute(), Tensor)
except Exception:
return False Try / catch
try:
value = trainer.callback_metrics["my_metric"]
except (ValueError, KeyError) as e:
# metric.compute() did not return a tensor
logger.warning("skipping metric: %s", e)
value = None Prevention
- Always return a single Tensor from custom Metric.compute()
- Keep one Metric per scalar value; never return tuples or dicts from compute()
- Add a unit test asserting isinstance(my_metric.compute(), torch.Tensor)
When it happens
Trigger: Logging a torchmetrics Metric whose compute() returns a tuple (like returning (loss, acc)) or a dict; logging a custom Metric subclass whose compute() returns a Python float or a collection; metrics with enable_graph/sync_dist paths that read result_metric._computed in _get_cache (used by metrics(), tests like test_metric_result_computed_check).
Common situations: Wrapping a model that returns multiple outputs into one Metric.compute(); using ClassificationTask-style metrics returning dicts; upgrading torchmetrics where compute() signatures changed; writing custom metrics without returning a tensor.
Related errors
- Blocking backward sync is only possible if the module passed
- Expected a precision plugin, got {plugin}
- Expected a method or a string, but got: {type(method).__name
- Could not find the `LightningModule` attribute for the `torc
- Could not find the `LightningModule` attribute for the `torc
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/f00cc76528e6aa6d.
Report an issue: GitHub.