facebookresearch/detectron2 · error · ValueError

total_batch_size and single_gpu_batch_size are mutually inco

Error message

total_batch_size and single_gpu_batch_size are mutually incompatible.
                Please specify only one. 

What it means

build_batch_data_loader takes either total_batch_size (split across all GPUs) or single_gpu_batch_size (per-GPU), never both. Supplying non-zero values for both raises this ValueError immediately.

Source

Thrown at detectron2/data/build.py:333

    Args:
        dataset (torch.utils.data.Dataset): a pytorch map-style or iterable dataset.
        sampler (torch.utils.data.sampler.Sampler or None): a sampler that produces indices.
            Must be provided iff. ``dataset`` is a map-style dataset.
        total_batch_size, aspect_ratio_grouping, num_workers, collate_fn: see
            :func:`build_detection_train_loader`.
        single_gpu_batch_size: You can specify either `single_gpu_batch_size` or `total_batch_size`.
            `single_gpu_batch_size` specifies the batch size that will be used for each gpu/process.
            `total_batch_size` allows you to specify the total aggregate batch size across gpus.
            It is an error to supply a value for both.
        drop_last (bool): if ``True``, the dataloader will drop incomplete batches.

    Returns:
        iterable[list]. Length of each list is the batch size of the current
            GPU. Each element in the list comes from the dataset.
    """
    if single_gpu_batch_size:
        if total_batch_size:
            raise ValueError(
                """total_batch_size and single_gpu_batch_size are mutually incompatible.
                Please specify only one. """
            )
        batch_size = single_gpu_batch_size
    else:
        world_size = get_world_size()
        assert (
            total_batch_size > 0 and total_batch_size % world_size == 0
        ), "Total batch size ({}) must be divisible by the number of gpus ({}).".format(
            total_batch_size, world_size
        )
        batch_size = total_batch_size // world_size
    logger = logging.getLogger(__name__)
    logger.info("Making batched data loader with batch_size=%d", batch_size)

    if isinstance(dataset, torchdata.IterableDataset):
        assert sampler is None, "sampler must be None if dataset is IterableDataset"
    else:

View on GitHub (pinned to a2f4a8771a)

Solutions

  1. Keep only one argument: pass total_batch_size=cfg.SOLVER.IMS_PER_BATCH (default path) and drop single_gpu_batch_size
  2. Or set single_gpu_batch_size only and clear total_batch_size
  3. Audit custom build_detection_train_loader overrides after upgrading detectron2

Example fix

# before
build_batch_data_loader(ds, mapper, sampler, total_batch_size=16, single_gpu_batch_size=4)
# after
build_batch_data_loader(ds, mapper, sampler, total_batch_size=16)
Defensive patterns

Strategy: validation

Validate before calling

assert not (total_batch_size and single_gpu_batch_size), "specify only one batch size arg"

Type guard

def batch_args_valid(total=None, per_gpu=None) -> bool:
    return not (total and per_gpu)

Prevention

When it happens

Trigger: Calling build_batch_data_loader(dataset, sampler, batch_sampler/mapper, total_batch_size=16, single_gpu_batch_size=4); or a custom config that sets both dataloader values and reaches build_detection_train_loader's from_config.

Common situations: Upgrading detectron2 versions where new per-GPU batch size knobs were introduced alongside the old IMS_PER_BATCH; custom trainers setting cfg.DATALOADER fields plus passing explicit sizes.

Related errors


AI-assisted analysis of facebookresearch/detectron2@a2f4a8771a (2026-08-27). Data as JSON: /api/errors/5504b08df9bccc7b. Report an issue: GitHub.