Lightning-AI/pytorch-lightning · error · ValueError

The metric `{value}` does not contain a single element, thus

Error message

The metric `{value}` does not contain a single element, thus it cannot be converted to a scalar.

What it means

The utility _to_/to_item conversion walks a metrics collection and calls .item() on every tensor; tensors with more than one element (numel() != 1) cannot be meaningfully converted to a Python scalar, so a ValueError is raised. This typically surfaces when logging a metric that is a vector/tensor of shape [N] instead of a scalar loss.

Source

Thrown at src/lightning/fabric/utilities/apply_func.py:131

def convert_to_tensors(data: Any, device: _DEVICE) -> Any:
    # convert non-tensors
    for src_dtype, conversion_func in CONVERSION_DTYPES:
        data = apply_to_collection(data, src_dtype, conversion_func, device=device)
    return move_data_to_device(data, device)


def convert_tensors_to_scalars(data: Any) -> Any:
    """Recursively walk through a collection and convert single-item tensors to scalar values.

    Raises:
        ValueError:
            If tensors inside ``metrics`` contains multiple elements, hence preventing conversion to a scalar.

    """

    def to_item(value: Tensor) -> Union[int, float, bool]:
        if value.numel() != 1:
            raise ValueError(
                f"The metric `{value}` does not contain a single element, thus it cannot be converted to a scalar."
            )
        return value.item()

    return apply_to_collection(data, Tensor, to_item)

View on GitHub (pinned to 9fed5c27d2)

Solutions

  1. Reduce the tensor to a scalar before logging: .mean(), .sum(), .max() or index a single element
  2. If you intentionally need the full tensor, log it via a logger that supports tensors (e.g. TensorBoard add_histogram / Neptune artifacts) rather than scalar metric conversion
  3. Check value.numel() == 1 in your metric computation before passing it on

Example fix

# before
self.log('val_recall', per_class_recall)  # shape [num_classes]

# after
self.log('val_recall', per_class_recall.mean())
Defensive patterns

Strategy: validation

Validate before calling

def scalar_or_fail(t):
    assert t.numel() == 1, f'metric must be scalar, got shape {tuple(t.shape)}'
    return t

Type guard

import torch

def is_scalar_tensor(t: torch.Tensor) -> bool:
    return t.numel() == 1

Prevention

When it happens

Trigger: Passing a multi-element tensor as a logged metric — e.g. self.log('preds', outputs) where outputs has shape [batch, ...], or fabric.log('metric', per_class_recall_vector) — anywhere Lightning converts collections via to_item (e.g. checkpoint/progress/metric conversion paths).

Common situations: Logging raw logits, per-class metric vectors, or confusion matrices; forgetting .mean()/.item() on a loss; refactors changing a metric from scalar to vector (per-class, per-token).

Related errors


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