CorentinJ/Real-Time-Voice-Cloning · 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

Raised by the training loop setup in synthesizer/train.py when CUDA is available and any batch_size entry in hparams.tts_schedule is not divisible by torch.cuda.device_count(). tts_schedule is a list of (lr, iters, clip, batch_size) annealing phases; every phase's batch must shard evenly across GPUs under DataParallel, so each entry is validated before training starts. Like error 6, the check only runs on CUDA machines.

Source

Thrown at synthesizer/train.py:60

    weights_fpath = model_dir / f"synthesizer.pt"
    metadata_fpath = syn_dir.joinpath("train.txt")

    print("Checkpoint path: {}".format(weights_fpath))
    print("Loading training data from: {}".format(metadata_fpath))
    print("Using model: Tacotron")

    # Bookkeeping
    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")
    model = Tacotron(embed_dims=hparams.tts_embed_dims,
                     num_chars=len(symbols),
                     encoder_dims=hparams.tts_encoder_dims,
                     decoder_dims=hparams.tts_decoder_dims,
                     n_mels=hparams.num_mels,
                     fft_bins=hparams.num_mels,
                     postnet_dims=hparams.tts_postnet_dims,
                     encoder_K=hparams.tts_encoder_K,
                     lstm_dims=hparams.tts_lstm_dims,
                     postnet_K=hparams.tts_postnet_K,
                     num_highways=hparams.tts_num_highways,
                     dropout=hparams.tts_dropout,

View on GitHub (pinned to 890f3a0318)

Solutions

  1. Edit the tts_schedule in the synthesizer hparams so every 4th tuple element is a multiple of the GPU count (e.g. 16, 32, 48 on 2/4/8 GPUs).
  2. Or pin the run to one GPU: CUDA_VISIBLE_DEVICES=0 python synthesizer_train.py <root>.
  3. Print torch.cuda.device_count() in the same environment to confirm how many GPUs the schedule must divide into before editing.

Example fix

# before: 2 GPUs
hparams.tts_schedule = [(1e-3, 100000, 1e-5, 11), (5e-4, 100000, 1e-5, 11)]  # 11 % 2 -> ValueError

# after
hparams.tts_schedule = [(1e-3, 100000, 1e-5, 12), (5e-4, 100000, 1e-5, 12)]  # divisible by 2 (and 3, 4, 6)
Defensive patterns

Strategy: validation

Validate before calling

import torch

def validate_schedule(schedule):
    n = torch.cuda.device_count() if torch.cuda.is_available() else 1
    for i, (_, _, _, bs) in enumerate(schedule):
        if n > 1 and bs % n != 0:
            raise ValueError(f"tts_schedule[{i}].batch_size={bs} not divisible by {n} GPUs")
    return schedule

Prevention

When it happens

Trigger: Running synthesizer_train.py on a multi-GPU machine with a tts_schedule containing at least one batch_size that is not a multiple of the visible GPU count (e.g. schedule [(1e-3, 100000, 1e-5, 11), ...] with 2 GPUs).

Common situations: Using a shared/rented multi-GPU box with a schedule authored for single GPU; changing CUDA_VISIBLE_DEVICES or moving to a different node with more GPUs; hand-editing the schedule and leaving one phase odd.

Related errors


AI-assisted analysis of CorentinJ/Real-Time-Voice-Cloning@890f3a0318 (2026-08-15). Data as JSON: /api/errors/6bdf6ac8eb96c946. Report an issue: GitHub.