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 configView on GitHub (pinned to 28dc5e14f1)
Solutions
- Edit hparams.tts_schedule so every session's batch_size is a multiple of n_gpus
- Or pin to one GPU with CUDA_VISIBLE_DEVICES=0
- 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
- Validate the whole tts_schedule up front
- Pin single GPU for small-batch training schedules
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.