Skip to content

Commit 2ebcb4c

Browse files
committed
Add --sync_every_iter to turn on synchronization at the end of each iteration
1 parent 37f9830 commit 2ebcb4c

2 files changed

Lines changed: 88 additions & 33 deletions

File tree

PyTorch/Classification/ConvNets/image_classification/training.py

Lines changed: 79 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ def __init__(
149149
grad_acc_steps: int,
150150
ema: Optional[float] = None,
151151
ltc: bool = False,
152+
gpu_id: int = None,
153+
sync_every_iter: bool = False,
152154
):
153155
self.executor = executor
154156
self.optimizer = optimizer
@@ -159,6 +161,8 @@ def __init__(
159161
self.ema = EMA(ema, self.ema_executor.model)
160162
self.use_ema = True
161163
self.ltc = ltc
164+
self.gpu_id = gpu_id
165+
self.sync_every_iter = sync_every_iter
162166

163167
self.optimizer.zero_grad(set_to_none=True)
164168
self.steps_since_update = 0
@@ -187,6 +191,14 @@ def train_step(self, input, target, step=None):
187191
self.optimizer.zero_grad()
188192
self.steps_since_update = 0
189193

194+
if self.ltc:
195+
ltm.mark_step(torch.device("lazy", self.gpu_id))
196+
197+
if self.sync_every_iter:
198+
if self.ltc:
199+
ltm.wait_device_ops()
200+
torch.cuda.synchronize()
201+
190202
if self.use_ema:
191203
self.ema(self.executor.model, step=step)
192204

@@ -219,52 +231,84 @@ def train(
219231
step=0,
220232
ltc=False,
221233
gpu_id=None,
234+
sync_every_iter=False,
222235
):
223236
interrupted = False
224-
bs = 0
225-
237+
end = time.time()
226238
data_iter = enumerate(train_loader)
227239

228-
start = time.time()
240+
if sync_every_iter:
241+
for i, (input, target) in data_iter:
242+
if ltc:
243+
input = input.to(torch.device("lazy", gpu_id))
244+
target = target.to(torch.device("lazy", gpu_id))
229245

230-
for i, (input, target) in data_iter:
231-
if ltc:
232-
input = input.to(torch.device("lazy", gpu_id))
233-
target = target.to(torch.device("lazy", gpu_id))
246+
bs = input.size(0)
247+
lr = lr_scheduler(i)
248+
data_time = time.time() - end
249+
loss = train_step(input, target, step=step + i)
250+
it_time = time.time() - end
234251

235-
bs += input.size(0)
236-
lr = lr_scheduler(i)
252+
with torch.no_grad():
253+
if torch.distributed.is_initialized():
254+
reduced_loss = utils.reduce_tensor(loss.detach())
255+
else:
256+
reduced_loss = loss.detach()
237257

238-
loss = train_step(input, target, step=step + i)
258+
log_fn(
259+
compute_ips=utils.calc_ips(bs, it_time - data_time),
260+
total_ips=utils.calc_ips(bs, it_time),
261+
data_time=data_time,
262+
compute_time=it_time - data_time,
263+
lr=lr,
264+
loss=reduced_loss.item(),
265+
)
266+
end = time.time()
267+
268+
if prof > 0 and (i + 1 >= prof):
269+
time.sleep(5)
270+
break
239271

240-
if ltc:
241-
ltm.mark_step(torch.device("lazy", gpu_id))
272+
if ((i + 1) % 20 == 0) and timeout_handler.interrupted:
273+
time.sleep(5)
274+
interrupted = True
275+
break
242276

243-
with torch.no_grad():
244-
if torch.distributed.is_initialized():
245-
reduced_loss = utils.reduce_tensor(loss.detach())
246-
else:
247-
reduced_loss = loss.detach()
277+
else: # not sync_every_iter
278+
reduced_loss = None
279+
bs = 0
280+
for i, (input, target) in data_iter:
281+
if ltc:
282+
input = input.to(torch.device("lazy", gpu_id))
283+
target = target.to(torch.device("lazy", gpu_id))
248284

249-
if prof > 0 and (i + 1 >= prof):
250-
time.sleep(5)
251-
break
252-
if ((i + 1) % 20 == 0) and timeout_handler.interrupted:
253-
time.sleep(5)
254-
interrupted = True
255-
break
285+
bs += input.size(0)
286+
lr = lr_scheduler(i)
287+
loss = train_step(input, target, step=step + i)
256288

257-
if ltc:
258-
ltm.wait_device_ops()
259-
torch.cuda.synchronize()
289+
with torch.no_grad():
290+
if torch.distributed.is_initialized():
291+
reduced_loss = utils.reduce_tensor(loss.detach())
292+
else:
293+
reduced_loss = loss.detach()
260294

261-
end = time.time()
295+
if prof > 0 and (i + 1 >= prof):
296+
break
262297

263-
log_fn(
264-
total_ips=utils.calc_ips(bs, end - start),
265-
lr=lr,
266-
loss=reduced_loss.item(),
267-
)
298+
if ((i + 1) % 20 == 0) and timeout_handler.interrupted:
299+
interrupted = True
300+
break
301+
302+
if ltc:
303+
ltm.wait_device_ops()
304+
torch.cuda.synchronize()
305+
306+
total_time = time.time() - end
307+
log_fn(
308+
total_ips=utils.calc_ips(bs, total_time),
309+
lr=lr,
310+
loss=reduced_loss.item(),
311+
)
268312

269313
return interrupted
270314

@@ -360,6 +404,7 @@ def train_loop(
360404
checkpoint_filename="checkpoint.pth.tar",
361405
ltc=False,
362406
ltc_summary=False,
407+
sync_every_iter=False,
363408
):
364409
train_metrics = TrainingMetrics(logger)
365410
val_metrics = {
@@ -402,6 +447,7 @@ def train_loop(
402447
step=epoch * train_loader_len,
403448
ltc=ltc,
404449
gpu_id=trainer.executor.gpu_id,
450+
sync_every_iter=sync_every_iter,
405451
)
406452

407453
if not skip_validation:

PyTorch/Classification/ConvNets/main.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,12 @@ def add_parser_arguments(parser, skip_arch=False):
368368
help="Dump LTC summary report",
369369
)
370370

371+
parser.add_argument(
372+
"--sync_every_iter",
373+
action="store_true",
374+
help="Synchronize after each iteration",
375+
)
376+
371377
def prepare_for_training(args, model_args, model_arch):
372378
args.distributed = False
373379
if "WORLD_SIZE" in os.environ:
@@ -612,6 +618,8 @@ def _worker_init_fn(id):
612618
grad_acc_steps=batch_size_multiplier,
613619
ema=args.use_ema,
614620
ltc=args.ltc,
621+
gpu_id=args.gpu,
622+
sync_every_iter=args.sync_every_iter,
615623
)
616624

617625
if (args.use_ema is not None) and (model_state_ema is not None):
@@ -665,6 +673,7 @@ def main(args, model_args, model_arch):
665673
checkpoint_filename=args.checkpoint_filename,
666674
ltc=args.ltc,
667675
ltc_summary=args.ltc_summary,
676+
sync_every_iter=args.sync_every_iter,
668677
)
669678
exp_duration = time.time() - exp_start_time
670679
if not torch.distributed.is_initialized() or torch.distributed.get_rank() == 0:

0 commit comments

Comments
 (0)