babysor/MockingBird · error · ValueError

`batch_size` must be evenly divisible by n_gpus!

Error message

`batch_size` must be evenly divisible by n_gpus!

What it means

The Tacotron training loop checks every entry of hparams.tts_schedule and requires each session's batch_size to be divisible by the number of CUDA devices, since DataParallel splits the batch across GPUs.

Source

Thrown at models/synthesizer/train.py:64

    
    print("Checkpoint path: {}".format(weights_fpath))
    print("Loading training data from: {}".format(metadata_fpath))
    print("Using model: Tacotron")
    
    # Book keeping
    step = 0
    time_window = ValueWindow(100)
    loss_window = ValueWindow(100)
    
    
    # From WaveRNN/train_tacotron.py
    if torch.cuda.is_available():
        device = torch.device("cuda")

        for session in hparams.tts_schedule:
            _, _, _, batch_size = session
            if batch_size % torch.cuda.device_count() != 0:
                raise ValueError("`batch_size` must be evenly divisible by n_gpus!")
    else:
        device = torch.device("cpu")
    print("Using device:", device)

    # Instantiate Tacotron Model
    print("\nInitialising Tacotron Model...\n")
    num_chars = len(symbols)
    if weights_fpath.exists():
        # for compatibility purpose, change symbols accordingly:
        loaded_shape = torch.load(str(weights_fpath), map_location=device)["model_state"]["encoder.embedding.weight"].shape
        if num_chars != loaded_shape[0]:
            print("WARNING: you are using compatible mode due to wrong sympols length, please modify varible _characters in `utils\symbols.py`")
            num_chars != loaded_shape[0]
                # Try to scan config file
        model_config_fpaths = list(weights_fpath.parent.rglob("*.json"))
        if len(model_config_fpaths)>0 and model_config_fpaths[0].exists():
            hparams.loadJson(model_config_fpaths[0])
        else:  # save a config

View on GitHub (pinned to 28dc5e14f1)

Solutions

  1. Edit hparams.tts_schedule so every session's batch_size is a multiple of n_gpus
  2. Or pin to one GPU with CUDA_VISIBLE_DEVICES=0
  3. Multiply all scheduled batch sizes by device_count and scale LR accordingly if needed

Example fix

# before
tts_schedule: [[...], [0.0001, 1e-6, 10000, 3]]  # n_gpus=2 → 3 % 2 != 0

# after
tts_schedule: [[...], [0.0001, 1e-6, 10000, 4]]
Defensive patterns

Strategy: validation

Validate before calling

n = torch.cuda.device_count()
for session in hparams.tts_schedule:
    _, _, _, bs = session
    assert n == 0 or bs % n == 0, f'batch_size {bs} not divisible by {n} GPUs'

Prevention

When it happens

Trigger: Calling train() on a multi-GPU machine where any (learning_rate, ...) tuple in tts_schedule has a batch_size not divisible by torch.cuda.device_count().

Common situations: Using the default DeepVoice3/LJSpeech schedule (batch sizes like 1-16 ramps) on an 8-GPU box; changing GPU count without updating the schedule.

Related errors


AI-assisted analysis of babysor/MockingBird@28dc5e14f1 (2026-08-27). Data as JSON: /api/errors/1333408ad52c3ff0. Report an issue: GitHub.