当模型被训练在GPU上时,我正在研究从CPU中预取数据到GPU中。与GPU模型训练重叠的CPU到GPU数据传输似乎需要两者同时进行。
data = data.cuda(non_blocking=True)
向GPU传输数据train_loader = DataLoader(..., pin_memory=True)
将数据引脚到CPU内存但是,我无法理解如何在这个官方PyTorch示例中执行非阻塞传输,特别是这个代码块:
for i, (images, target) in enumerate(train_loader):
# measure data loading time
data_time.update(time.time() - end)
if args.gpu is not None:
images = images.cuda(args.gpu, non_blocking=True)
if torch.cuda.is_available():
target = target.cuda(args.gpu, non_blocking=True)
# compute output
output = model(images)
loss = criterion(output, target)
images.cuda(non_blocking=True)
和target.cuda(non_blocking=True)
不需要在执行output = model(images)
之前完成。由于这是一个同步点,images
必须首先完全传输到CUDA设备上,因此数据传输步骤不再是有效的无阻塞的。
由于output = model(images)
是阻塞的,在下一个for
循环的i
迭代中,在计算模型输出之前不会发生for
和target.cuda()
,这意味着在下一个循环迭代中没有预取。
如果这是正确的,那么执行数据预取到GPU的正确方法是什么?
发布于 2021-11-09 17:15:07
我认为output = model(images)
是一个同步点。似乎计算是由GPU的另一个部分处理的。来自官方PyTorch文档的报价
此外,一旦您固定一个张量或存储,您可以使用异步GPU副本。只需将附加的
non_blocking=True
参数传递给to()
或cuda()
调用即可。--这可用于将数据传输与计算重叠。
发布于 2020-10-18 23:35:22
要在PyTorch上正确地实现GPU预取,必须将for-循环转换为while-循环.
应该使用DataLoader函数将iter
转换为迭代器,例如iterator = iter(loader)
。
在while循环中的每一步都使用next(iterator)
来获得下一个小批处理。
可以通过从迭代器捕获DataLoader的StopIteration
来检测StopIteration
的结束。
在引发StopIteration
时,使用标志结束while循环。
https://stackoverflow.com/questions/63460538
复制相似问题