给pytorch dataloader读取数据加速

平时的代码:

train_loader = torch.utils.data.DataLoader(
								Vlog.VlogSet(params, is_train=True,frame_gap=args.frame_gap),
								batch_size=params['batchSize'],
								shuffle=True,
								num_workers=args.workers, 
								pin_memory=True)
for batch_idx, (imgs, img, patch2, theta, meta) in enumerate(train_loader):
         #训练代码

改过的代码:

class data_prefetcher():
    def __init__(self, loader):
        self.loader = iter(loader)
        self.stream = torch.cuda.Stream()
        self.preload()

    def preload(self):
        try:
            self.imgs, self.img, self.patch2, self.theta, self.meta = next(self.loader)

        except StopIteration:
            self.next_input = None

            return
        with torch.cuda.stream(self.stream):
            self.imgs = self.imgs.cuda(non_blocking=True)
            self.img = self.img.cuda(non_blocking=True)
            self.patch2 = self.patch2.cuda(non_blocking=True)
            self.theta = self.theta.cuda(non_blocking=True)

    def next(self):
        torch.cuda.current_stream().wait_stream(self.stream)
        imgs = self.imgs
        img = self.img
        patch2 = self.patch2
        theta = self.theta
        meta = self.meta

        self.preload()
        return imgs, img, patch2, theta, meta
    prefetcher = data_prefetcher(train_loader)
    (imgs, img, patch2, theta, meta) = prefetcher.next()

    batch_idx = 0
    while data is not None:
        batch_idx += 1
        #训练代码
        (imgs, img, patch2, theta, meta) = prefetcher.next()

大功告成,gpu利用率蹭蹭上来,当然最好还是把机械硬盘换成ssd

参考:这个情况nVidia给出了解决方案
https://github.com/NVIDIA/apex/blob/f5cd5ae937f168c763985f627bbf850648ea5f3f/examples/imagenet/main_amp.py#L256

在调整num_workers的过程中,发现训练速度并没有变化,原因在于:

num_workers是加载数据(batch)的线程数目

当加载batch的时间 < 数据训练的时间

  GPU每次训练完都可以直接从CPU中取到next batch的数据

  无需额外的等待,因此也不需要多余的worker,即使增加worker也不会影响训练速度

当加载batch的时间 > 数据训练的时间

  GPU每次训练完都需要等待CPU完成数据的载入

  若增加worker,即使worker_1还未就绪,GPU也可以取worker_2的数据来训练

仅限单线程训练情况

写在结尾:对于dataloader特别大的情况好像并无luan用,开了100个线程喂进去100个batch,接下来又是漫长的等待。

DataLoader num_workers与torch.set_num_threads的区别:
num_workers设置DataLoader在实现数据预处理的并行化的进程数,并没有设置线程。
set_num_threads()设置Pytorch进行CPU多线程并行计算时所占用的线程数。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值