Lightning-AI/pytorch-lightning · error · ValueError
`self.log({name}, {value})` was called, but the tensor must
Error message
`self.log({name}, {value})` was called, but the tensor must have a single element. You can try doing `self.log({name}, {value}.mean())` What it means
__to_tensor requires every logged tensor to contain exactly one element (a scalar) so it can be aggregated. Tensors with more than one element (or zero) raise ValueError; the message suggests reducing via .mean().
Source
Thrown at src/lightning/pytorch/core/module.py:666
@staticmethod
def __check_not_nested(value: dict, name: str) -> None:
# self-imposed restriction. for simplicity
if any(isinstance(v, dict) for v in value.values()):
raise ValueError(f"`self.log({name}, {value})` was called, but nested dictionaries cannot be logged")
@staticmethod
def __check_allowed(v: Any, name: str, value: Any) -> None:
raise ValueError(f"`self.log({name}, {value})` was called, but `{type(v).__name__}` values cannot be logged")
def __to_tensor(self, value: Union[Tensor, numbers.Number], name: str) -> Tensor:
value = (
value.clone().detach()
if isinstance(value, Tensor)
else torch.tensor(value, device=self.device, dtype=_get_default_dtype())
)
if not torch.numel(value) == 1:
raise ValueError(
f"`self.log({name}, {value})` was called, but the tensor must have a single element."
f" You can try doing `self.log({name}, {value}.mean())`"
)
value = value.squeeze()
return value
def all_gather(
self, data: Union[Tensor, dict, list, tuple], group: Optional[Any] = None, sync_grads: bool = False
) -> Union[Tensor, dict, list, tuple]:
r"""Gather tensors or collections of tensors from multiple processes.
This method needs to be called on all processes and the tensors need to have the same shape across all
processes, otherwise your program will stall forever.
Args:
data: int, float, tensor of shape (batch, ...), or a (possibly nested) collection thereof.
group: the process group to gather results from. Defaults to all processes (world)
sync_grads: flag that allows users to synchronize gradients for the all_gather operationView on GitHub (pinned to 9fed5c27d2)
Solutions
- Reduce to a scalar: self.log('loss', loss.mean()) (or .sum()/.max() as appropriate)
- Ensure losses computed in training_step are already reduced to one value
- Log per-class values under separate scalar keys instead of one vector
Example fix
# before
self.log('loss', losses) # shape [B]
# after
self.log('loss', losses.mean()) Defensive patterns
Strategy: validation
Validate before calling
import torch
def scalarize(t):
return t.mean() if isinstance(t, torch.Tensor) and t.numel() != 1 else t
self.log(name, scalarize(value)) Type guard
def is_scalar_tensor(v) -> bool:
import torch
return not isinstance(v, torch.Tensor) or v.numel() == 1 Prevention
- Reduce losses with .mean() before self.log
- Assert one-element shape in debug builds for logged tensors
When it happens
Trigger: self.log('loss', per_sample_losses) where the tensor has shape [batch_size]; logging a vector, image tensor, or empty tensor.
Common situations: User logs unreduced loss over the batch, logs predictions array, or logs a tensor that got squeezed to empty.
Related errors
- Device should be CPU, got {device} instead.
- The metric `{value}` does not contain a single element, thus
- You are trying to `self.log()` but the loop's result collect
- You are trying to `self.log()` but it is not managed by the
- You called `self.log` with the key `{name}` but it should no
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/2b2a07e6deabd61e.
Report an issue: GitHub.