精华内容
下载资源
问答
  • 今天小编就为大家分享一篇解决pytorch DataLoader num_workers出现的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • windows num_workers

    2021-09-06 20:29:56
    就是num_workers的设置问题,设置为1,cpu那个线程压力太大,所以设置为大点!! 还有一个问题 RuntimeError: CUDA error: an illegal memory access was encountered 这个错误解决 这样来。用了torch....

    分配了这个电脑,跑了10个程序9个因为cpu利用率太高,声音太大导致跑不了,让我一度以为是电脑散热坏了还有cpu不行,其实不是的

    就是num_workers的设置问题,设置为1,cpu那个线程压力太大,所以设置为大点!!

    可以设置为2,4这种,一般设置为4就行,设置太大,Gpu显存不够的话也处理不过来!

    windows下设置num_workers会出现很多问题,一般的处理方式有两种,一种是将num_workers=0

    另一种是将代码放在main()函数中

    然后在最下面来一个就好

    if __name__ == '__main__':
        main()

    还有一个问题

    RuntimeError: CUDA error: an illegal memory access was encountered

    这个错误解决

     这样来。用了torch.cuda.set_device(0)后

    把那些.to(device)都改成.cuda()就可以!!!

    展开全文
  • 前段时间,我在调整yolo系列代码的时候,运行代码后,会提示 win页面太小问题,这种问题的解决办法之一就是通过调整 DataLoader的num_workers值的大小来解决,为了进一步了解num_workers到底起了什么作用,这里我查...

    前段时间,我在调整yolo系列代码的时候,运行代码后,会提示 win页面太小问题,这种问题的解决办法之一就是通过调整 DataLoader的num_workers值的大小来解决,为了进一步了解num_workers到底起了什么作用,这里我查了一些相关的资料。

    这里我们将探讨如何利用PyTorch DataLoader类的多进程功能来加快神经网络训练过程 

    一、训练进程提速

    为了加快训练过程,我们将利用DataLoader类的num_workers可选属性。

    num_workers属性告诉DataLoader实例要使用多少个子进程进行数据加载。默认情况下,num_workers值被设置为0,0值代表告诉加载器在主进程内部加载数据。

    0:这意味着训练进程将在主进程内部依次工作。在训练过程中使用一批批处理之后,我们从磁盘上读取另一批批处理数据。

    现在,如果我们有一个工作进程,我们可以利用我们的机器有多个内核这一事实。这意味着,在主进程准备好另一个批处理的时候,下一个批处理已经可以加载并准备好了。这就是速度提升的原因。批处理使用附加的辅助进程加载,并在内存中排队。

    二、num_works到底取何值

    在给Dataloader设置worker数量(num_worker)时,到底设置多少合适?这个worker到底怎么工作的?如果将num_worker设为0(也是默认值),就没有worker了吗?

    dataloader = loader(dataset,
                        batch_size=batch_size,
                        num_workers=nw,
                        sampler=sampler,
                        pin_memory=True,
                        collate_fn=LoadImagesAndLabels.collate_fn4 if quad else LoadImagesAndLabels.collate_fn)

    1、每每轮到dataloader加载数据时:dataloader一次性创建num_worker个worker,(也可以说dataloader一次性创建num_worker个工作进程,worker也是普通的工作进程),并用batch_sampler将指定batch分配给指定worker,worker将它负责的batch加载进RAM。然后,dataloader从RAM中找本轮迭代要用的batch,如果找到了,就使用。如果没找到,就要num_worker个worker继续加载batch到内存,直到dataloader在RAM中找到目标batch。一般情况下都是能找到的,因为batch_sampler指定batch时当然优先指定本轮要用的batch。

    2、num_worker设置得大,好处是寻找batch速度快,因为下一轮迭代的batch很可能在上一轮/上上一轮...迭代时已经加载好了。坏处是内存开销大,也加重了CPU负担(worker加载数据到RAM的进程是CPU复制的嘛)。num_workers的经验设置值是自己电脑/服务器的CPU核心数,如果CPU很强、RAM也很充足,就可以设置得更大些。

    3、如果num_worker设为0,意味着每一轮迭代时,dataloader不再有自主加载数据到RAM这一步骤(因为没有worker了),而是在RAM中找batch,找不到时再加载相应的batch。缺点当然是速度更慢。

    展开全文
  • Pytorch 初学 ———num_workers问题 运行环境 配置一 cpu:AMD 5600x 内存:32G 硬盘:pm981a pytorch:1.8 CPU版本 系统:windows 10 配置二 cpu:i7 10700k 内存:32G 硬盘:固态(型号未知) pytorch:1.8 GPU版本...

    Pytorch 初学 ———num_workers问题

    运行环境

    配置一

    cpu:AMD 5600x 内存:32G 硬盘:pm981a pytorch:1.8 CPU版本 系统:windows 10

    配置二

    cpu:i7 10700k 内存:32G 硬盘:固态(型号未知) pytorch:1.8 GPU版本 系统:ubuntu

    运行代码

    import torch, torchvision
    import numpy as np
    from torch.utils.data import Dataset, DataLoader
    import time
     
      class MnistModel(torch.nn.Module):
        def __init__(self, nodes):
            super(MnistModel, self).__init__()
            self.linear1 = torch.nn.Linear(784, nodes)
            self.linear2 = torch.nn.Linear(nodes, 10)
            self.sigmoid = torch.nn.Sigmoid()
    
        def forward(self, x):
            x = self.sigmoid(self.linear1(x))
            x = self.linear2(x)
    
            return x
    
    
    class MnistDataset(Dataset):
        def __init__(self, path):
            data = np.loadtxt(path, delimiter=',', dtype='float32')
            self.len = data.shape[0]
            self.x_data = torch.tensor(data[:, 1:])
            self.y_data = torch.LongTensor(data[:, 0])
    
        def __getitem__(self, index):
            return self.x_data[index], self.y_data[index]
    
        def __len__(self):
            return self.len
    
    
    
    MnistData = MnistDataset('datasets/MNIST/mnist_train_100.csv')
    #使用num_workers 
    #trainLoader = DataLoader(dataset=MnistData, batch_size=50, shuffle=True,num_wprkers = 2)
    #去掉 num_workers
    trainLoader = DataLoader(dataset=MnistData, batch_size=50, shuffle=True)
    
    model = MnistModel(100)
    criterion = torch.nn.CrossEntropyLoss()
    optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
    start_time = time.time()
    if __name__ == "__main__":
        for epoch in range(100):
            for i, (inputs, labels) in enumerate(trainLoader, 0):
            
                y_pred = model(inputs)
    
                loss = criterion(y_pred, labels)
                print("epoch:", epoch, loss.item())
    
                optimizer.zero_grad()
                loss.backward()
    
                optimizer.step()
    end_time = time.time()
    
    print("训练耗费时间:",(end_time - start_time))
    

    上述代码主要是实现手写数字的识别,属于多分类问题,因此使用的为交叉熵损失函数CrossEntroyLoss( ),所用数据集为自己下载的MNIST数据集的一部分,并不是torchvision中提供的数据集,因此需要自己进行数据的处理。
    忽略数据处理时间,只对训练时间进行统计;windows 10系统下在num_workers = 2 的时候,100个epoch所耗费的时间为100s左右,而去掉该参数 100个epoch花费的时间为0.2s左右;ubuntu系统下 即使num_workers = 2,100个epoch花费的时间也在4秒左右。可见,多进程的情况下时间差距是很大的。
    在B站up主刘二大人的pytorch教程中,老师提到由于Linux和Windows的多进程实现方式是不同的(Linux 使用fork( ),而Windows 则使用spawn( ) ),所以在训练的时候直接进行上述代码中的for循环会导致
    在这里插入图片描述
    解决方法就是在for循环之前加上一个if语句,但是并没有提及多进程在Windows 系统下会导致运行缓慢的情况。

    猜测

    由于本人也刚刚开始学pytorch,因此以下的结论只是猜测:5600x 和i7 10700K 的性能差距并不是很大,其他的配置也是类似的,虽然显卡差距很大,但都采用cpu进行运算。总的来说,两台电脑的配置差距可以忽略,加之多进程在Linux和Windows系统下实现方式不同,因此我猜测 造成pytorch代码运行缓慢的原因就是系统差异。当然,根据控制变量法,最好是在同一台电脑上装双系统然后进行测试。目前我的电脑还没有装Linux,后续有需要的话我会装上该系统再次进行测试的。

    结语

    由于在网上并没有找到导致该现象出现的具体原因,上述观点只是本人的猜测。如有错误还请纠正,当然如果您能找到具体原因或者验证上述观点存在正确部分也希望能够不吝赐教。补充一句:删除该参数之后,意味着不再使用多进程,因此在运行的时候也就可以将if语句去掉了,不过既然是在Windows系统下,还是使用if语句为好吧。

    此外附上 pytorch github 提交的相关issue 地址:issue

    展开全文
  • 参考 torch Dataloader中的num_workers - 云+社区 - 腾讯云 考虑这么一个场景,有海量txt文件,一个个batch读进来,测试一下torch DataLoader的效率如何。 基本信息: 本机配置:8核32G内存,工作站内置一块2T的机械...

    参考 torch Dataloader中的num_workers - 云+社区 - 腾讯云

    考虑这么一个场景,有海量txt文件,一个个batch读进来,测试一下torch DataLoader的效率如何。

    基本信息:

    • 本机配置:8核32G内存,工作站内置一块2T的机械硬盘,数据均放在该硬盘上
    • 操作系统:ubuntu 16.04 LTS
    • pytorch:1.0
    • python:3.6

    1、首先生成很多随机文本txt

    def gen_test_txt():
        population = list(string.ascii_letters) + ['\n']
        for i in range(1000):
            with open(f'./test_txt/{i}.txt', 'w') as f:
                f.write(
                    ''.join(random.choices(population, k=1000000))
                )

    2、然后顺序读取作为benchmark

    def test_torch_reader():
        class Dst(Dataset):
            def __init__(self, paths):
                self.paths = paths
    
            def __len__(self):
                return len(self.paths)
    
            def __getitem__(self, i):
                open(self.paths[i], 'r').read()
                return 1
    
        dst = Dst([f'./test_txt/{i}.txt' for i in range(1000)])
        loader = DataLoader(dst, 128, num_workers=0)
    
        ts = time()
        time_cost = []
        for i, ele in enumerate(loader, 1):
            dur = time() - ts
            time_cost.append(dur)
            print(i, dur)
            ts = time()
    
        print(f"{sum(time_cost):.3f}, "
              f"{np.mean(time_cost):.3f}, "
              f"{np.std(time_cost):.3f}, "
              f"{max(time_cost):.3f}, "
              f"{min(time_cost):.3f}")
    
        plt.plot(time_cost)
        plt.grid()
        plt.show()

    每个batch耗时的基本统计信息如下,

    基本维持在0.9 sec / batch

    total, mean, std, max, min

    7.148, 0.893, 0.074, 1.009, 0.726

    可见,一共是1000个文件,batch size 128,也就是8个batch,总共耗时7.1s,接下来清除cache,

    3、设置num_workers为4

    每隔4个batch,要准备4个batch,且是串行的,因此时间增大4倍,接下来3个batch几乎不占用时间

    total, mean, std, max, min

    7.667, 0.958, 1.652, 3.983, 0.000

    接下来实验在SSD上进行,同样num_workers先0后4,如下

    total, mean, std, max, min

    3.251, 0.406, 0.026, 0.423, 0.338

    SSD上,对比机械硬盘更加稳定

    然后是num_workers = 4,

    total, mean, std, max, min

    1.934, 0.242, 0.421, 1.088, 0.000

    观察到同样的现象,但尖峰应该是0.4*4=1.6,这里反而epoch 4 (0-index)降为一半为0.8

    基本结论:可以看到,不管是在SSD,还是机械硬盘上,总的耗时基本不变(SSD小一些,但原因也可能是实验不充分),并没有因为numworkers增大而减小,令我很费解!我一贯的理解是:比如num_workers为4,那么每个worker计算一个batch,因为本机多核且大于4,讲道理4个worker并行处理,因此时间为num_workers=0的1/4才合理,那原因是为何呢?(这个实验本来是为了load audio数据,其实在audio上作类似实验也是一致的现象)

    补充了一个实验,尝试用ray读取,代码如下,

    def test_ray():
        ray.init()
    
        @ray.remote
        def read(paths):
            for path in paths:
                open(path, 'r').read()
            return 1
    
        def ray_read(paths, n_cpu=4):
            chunk_size = len(paths) // n_cpu
            object_ids = []
            for i in range(n_cpu):
                x = read.remote(paths[i * chunk_size: (i + 1) * chunk_size])
                object_ids.append(x)
    
            return ray.get(object_ids)
    
        def batch(l, bs):
            out = []
            i = 0
            while i < len(l):
                out.append(l[i: i + bs])
                i += bs
            return out
    
        paths = [os.path.expanduser(f'~/test_txt/{i}.txt') for i in range(1000)]
        paths = batch(paths, 128)
    
        time_cost = []
        ts = time()
        for i, ele in enumerate(paths, 1):
            # read(paths[i - 1])
            ray_read(paths[i - 1], 8)
            dur = time() - ts
            time_cost.append(dur)
            print(i, dur)
            ts = time()
    
        print(f"{sum(time_cost):.3f}, "
              f"{np.mean(time_cost):.3f}, "
              f"{np.std(time_cost):.3f}, "
              f"{max(time_cost):.3f}, "
              f"{min(time_cost):.3f}")
    
        plt.plot(time_cost)
        plt.grid()
        plt.show()

    流程是这样的:将输入paths分成n_cpu个chunk,chunk之间通过ray异步执行,结果是:同样是在SSD上,理论上每个batch耗时是之前的1/4,也就是0.1s左右,但实测是0.2s,也就是说,n_cpu最大有效值就是2。

    展开全文
  • pytorch中DataLoader的num_workers参数详解与设置大小建议

    千次阅读 多人点赞 2021-04-04 11:50:26
    Q:在给Dataloader设置worker数量(num_worker)时,到底设置多少合适?这个worker到底怎么工作的? train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True,
  • Pytorch中num_workers详解

    万次阅读 多人点赞 2020-07-21 10:53:06
    一直很迷,在给Dataloader设置worker数量(num_worker)时,到底设置多少合适?这个worker到底怎么工作的?如果将num_worker设为0(也是默认值),就没有worker了吗? worker的使用场景: from torch.utils.data ...
  • pytorch中num_workers详解

    万次阅读 多人点赞 2020-01-15 17:06:02
    一直很迷,在给Dataloader设置worker数量(num_worker)时,到底设置多少合适?这个worker到底怎么工作的?如果将num_worker设为0(也是默认值),就没有worker了吗? worker的使用场景: fro...
  • 但是在训练的时候遇到了一个问题:每隔num_workers个iteration数据加载都很慢,通过查找资料和代码搞清了这个问题。 背景   设计了一个网络做目标检测,骨干网络是自己diy的因此没有pretrain的模型。而目标检测的...
  • PyTorch - 33 - PyTorch DataLoader Num_workers - 深度学习速度限制增加 Speeding Up The Training Process Optimal Value For The num_workers Attribute Testing Values For The num_workers Attribute Different...
  • PyTorch DataLoader num_workers Test - 加快速度 欢迎来到本期神经网络编程系列。在本集中,我们将看到如何利用PyTorch DataLoader类的多进程功能来加快神经网络训练过程。 加快训练进程 为了加快训练过程,我们将...
  • 对于num_workers大于0是报错 Error1: DataLoader worker (pid(s) 15464, 8000) exited unexpectedly or Error2: BrokenPipeError: [Errno 32] Broken pipe 解决方法: 在运行的部分放进__main__()函数里 ...
  • num_workers的理解

    2020-05-17 22:24:42
    指用来加载数据的子进程。默认值是0,意味只用主进程加载数据。在我实验过程中似乎 1与2 作用一样。越大意味着寻找batch速度越快。
  • pytorch DataLoader num_workers 出现的问题

    万次阅读 多人点赞 2018-07-03 10:17:18
    最近在学pytorch,在使用数据分批训练时在导入数据是使用了 DataLoader 在参数num_workers的设置上使程序出现运行没有任何响应的结果 ,看看代码 import torch #导入模块 import torch.utils.data as Data BATCH_...
  • 电脑有10核20线程应该怎么设置torch.utils.data.DataLoader 中 num_workers使得我数据加载最快? 首先来搞定定义:概念核心数与线程数 核心数与线程数 核心:一个CPU具有的物理核心数(物理概念) 线程:是CPU调度和...
  • 问题描述: 最近在用RFBnet (源码是pytorch的)训练RSNA的比赛数据,除了要修改一点代码支持RSNA的数据...如果设置num_workers为其他任何一个大于0的整数,也就是使用子进程读取数据时,训练程序会卡住,卡在训练之前
  • 未将主运行程序放在if __name__ == '__main__':之下导致调用出错 而dataloader本质上是使用多进程来进行程序的加速,而python在调用多进程程序时如果不将主程序加入if __name__ == '__main__':下,子线程就会无限...
  • PyTorch——num_workers参数的设置

    万次阅读 2019-12-03 13:33:24
    在使用DataLoader载入数据时,我们需要对num_workers这个参数进行设置,那么设置成多少比较好呢; 2 DataLoader中num_workers参数的设置 我个人觉得按照CPU的线程数来设置比较好,因为感觉数据载入是一个跟IO读取...
  • 1.问题分析 torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True, num_workers=NUM_WORKERS, pin_memory=True) 在Pytorch中
  • pytorch中Dataloader()中的num_workers设置问题: 如果num_workers的值大于0,要在运行的部分放进__main__()函数里,才不会有错: import numpy as np import torch from torch.autograd import Variable import ...
  • 深度学习训练中的num_workers

    千次阅读 2020-05-09 18:27:15
    num_workers是加载数据(batch)的线程数目 当加载batch的时间 < 数据训练的时间  GPU每次训练完都可以直接从CPU中取到next batch的数据  无需额外的等待,因此也不需要多余的worker,即使增加worker也不会...
  • 在Windows系统中,num_workers参数建议设为0,在Linux系统则不需担心。 1 问题描述 在之前的任务超大图上的节点表征学习中,使用PyG库用于数据加载的DataLoader,ClusterLoader等类时,会涉及到参数num_workers。在...
  • pytorch中的num_workers和pin_memory

    千次阅读 2019-10-14 16:10:28
    1.dataset:加载的数据集(Dataset对象) ...5.num_workers:使用多进程加载的进程数,0代表不使用多进程 6.collate_fn: 如何将多个样本数据拼接成一个batch,一般使用默认的拼接方式即可 7.pin_...
  • pytorch data.DataLoader 中num_workers的问题

    千次阅读 2020-02-15 12:57:50
    我遇见的问题是: 是num_worker的问题,将 ** num_workers改为0就可以了** 不知道是不是版本的问题,我的是win10+3.7
  • 测试程序时发现,当DataLoader函数中加载数据时线程数设定大于0时,程序会卡住,但当设定线程数为1(num_workers=0即将用主进程加载数据)时,程序能正常运行,但由于仅单线程的加载致使神经网络在训练时会花将近...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,539
精华内容 8,615
关键字:

num_workers