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
- 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).
- Or pin the run to one GPU: CUDA_VISIBLE_DEVICES=0 python synthesizer_train.py <root>.
- 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
- Validate every phase of tts_schedule against the target machine's GPU count before submitting a training job.
- Keep per-machine hparams overrides rather than editing the shared defaults.
- Prefer powers-of-two batch sizes across the whole schedule.
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
- `hparams.synthesis_batch_size` must be evenly divisible by n
- Unknown cleaner: %s
- Can't create RandomCycler from an empty collection
- No speakers found. Make sure you are pointing to the directo
- No visdom server detected. Run the command \"visdom\" in you
AI-assisted analysis of CorentinJ/Real-Time-Voice-Cloning@890f3a0318 (2026-08-15).
Data as JSON: /api/errors/6bdf6ac8eb96c946.
Report an issue: GitHub.