Skip to content

Commit 334673b

Browse files
committed
fix: track actual accumulated samples for accurate effective batch size
Replace static _eff_bs = batch_size * accum_steps with actual sample counting across micro-batches. Each micro-batch's actual sample count (latents/images/captions shape[0]) is summed, then multiplied by num_processes for DDP. Handles: - Incomplete last batch of epoch (fewer samples) - Partial gradient accumulation (training ends mid-window) - Uneven micro-batches within a single accumulation window
1 parent 8b73454 commit 334673b

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

train_network.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,6 +2268,7 @@ def remove_model(old_ckpt_name):
22682268
current_global_step_wnoise = 0.0 if self.weight_noise_enabled else None
22692269
avr_loss = 0.0
22702270
accumulation_counter = 0
2271+
accumulated_samples = 0 # Tracks actual samples across micro-batches for dynamic sigma
22712272

22722273
# Detect step_func optimizer (e.g. AdamWScheduleFreePlus with Polyak step size).
22732274
# step_func(function_value) replaces step() and requires the current loss value.
@@ -2381,6 +2382,18 @@ def remove_model(old_ckpt_name):
23812382

23822383
accumulation_counter += 1
23832384

2385+
# Track actual micro-batch size for accurate effective batch size
2386+
_actual_bs = None
2387+
if "latents" in batch and batch["latents"] is not None:
2388+
_actual_bs = batch["latents"].shape[0]
2389+
elif "images" in batch and batch["images"] is not None:
2390+
_actual_bs = batch["images"].shape[0]
2391+
elif "captions" in batch:
2392+
_actual_bs = len(batch["captions"])
2393+
if _actual_bs is None:
2394+
_actual_bs = args.train_batch_size
2395+
accumulated_samples += _actual_bs
2396+
23842397
# preprocess batch for each model
23852398
self.on_step_start(args, accelerator, network, text_encoders, unet, batch, weight_dtype, is_train=True)
23862399

@@ -2487,9 +2500,9 @@ def remove_model(old_ckpt_name):
24872500
unwrapped_network = accelerator.unwrap_model(network)
24882501
if hasattr(unwrapped_network, "inject_weight_noise"):
24892502
# Compute effective batch size and fallback LR for dynamic scaling.
2490-
# Pass the optimizer so the network can resolve per-param LR
2491-
# from optimizer.param_groups for accurate dynamic scaling.
2492-
_eff_bs = args.train_batch_size * args.gradient_accumulation_steps
2503+
# Use actual accumulated samples (handles incomplete batches
2504+
# and partial gradient accumulation) × num_processes for DDP.
2505+
_eff_bs = accumulated_samples * accelerator.num_processes
24932506
_fallback_lr = lr_scheduler.get_last_lr()[0]
24942507
_raw_opt = getattr(optimizer, 'optimizer', optimizer)
24952508
noise_norm = unwrapped_network.inject_weight_noise(
@@ -2681,6 +2694,7 @@ def remove_model(old_ckpt_name):
26812694
if self.weight_noise_enabled:
26822695
current_global_step_wnoise = 0.0
26832696
accumulation_counter = 0
2697+
accumulated_samples = 0
26842698

26852699
if global_step >= args.max_train_steps:
26862700
break

0 commit comments

Comments
 (0)