open-mmlab/mmdetection · error · NotImplementedError

device must be 'cpu' or 'gpu', but got {device}

Error message

device must be 'cpu' or 'gpu', but got {device}

What it means

collect_tracking_results only supports device 'cpu' or 'gpu' for gathering distributed video-metric results; any other string raises NotImplementedError with the received value.

Source

Thrown at mmdet/evaluation/metrics/base_video_metric.py:109

    """Collected results in distributed environments. different from the
    function mmengine.dist.collect_results, tracking compute metrics don't use
    paramenter size, which means length of the entire validation dataset.
    because it's equal to video num, but compute metrics need image num.

    Args:
        results (list): Result list containing result parts to be
            collected. Each item of ``result_part`` should be a picklable
            object.
        device (str): Device name. Optional values are 'cpu' and 'gpu'.
        tmpdir (str | None): Temporal directory for collected results to
            store. If set to None, it will create a temporal directory for it.
            ``tmpdir`` should be None when device is 'gpu'. Defaults to None.

    Returns:
        list or None: The collected results.
    """
    if device not in ['gpu', 'cpu']:
        raise NotImplementedError(
            f"device must be 'cpu' or 'gpu', but got {device}")

    if device == 'gpu':
        assert tmpdir is None, 'tmpdir should be None when device is "gpu"'
        raise NotImplementedError('GPU collecting has not been supported yet')
    else:
        return collect_tracking_results_cpu(results, tmpdir)


def collect_tracking_results_cpu(result_part: list,
                                 tmpdir: Optional[str] = None
                                 ) -> Optional[list]:
    """Collect results on cpu mode.

    Saves the results on different gpus to 'tmpdir' and collects them by the
    rank 0 worker.

    Args:

View on GitHub (pinned to cfd5d3a985)

Solutions

  1. Set collect_device='cpu' (the standard choice) in the metric config
  2. Pass a plain string, not a torch.device object

Example fix

# before
metric = MOTMetric(collect_device='cuda:0')
# after
metric = MOTMetric(collect_device='cpu')
Defensive patterns

Strategy: validation

Validate before calling

assert collect_device in ('cpu', 'gpu'), f'bad collect_device: {collect_device}'

Type guard

def is_valid_collect_device(d) -> bool:
    return isinstance(d, str) and d in ('cpu', 'gpu')

Prevention

When it happens

Trigger: Calling video metric evaluate() with collect_device set to something like 'cpu:gather' or a device object; misconfigured metric collect_device in configs.

Common situations: Custom configs overriding collect_device with an invalid string; passing torch.device instead of a plain 'cpu'/'gpu' string.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of open-mmlab/mmdetection@cfd5d3a985 (2026-08-27). Data as JSON: /api/errors/054eea412b4f166b. Report an issue: GitHub.