PyTorch Dataloader当使用LMDB数据时num_worker>0引发TypeError: can‘t pickle Environment objects问题的解决

PyTorch Dataloader当使用LMDB数据时num_worker>0引发TypeError: can't pickle Environment objects问题的解决

防忘记,原issue:https://github.com/pytorch/vision/issues/689#issuecomment-787215916

解决方法:

  1. 不要在__init__方法中调用lmdb.open方法;
  2. 在第一次加载数据时打开lmdb。

代码如下

class DataLoader(torch.utils.data.Dataset):
    def __init__(self):
        """do not open lmdb here!!"""

    def open_lmdb(self):
         self.env = lmdb.open(self.lmdb_dir, readonly=True, create=False)
         self.txn = self.env.begin(buffers=True)

    def __getitem__(self, item: int):
        if not hasattr(self, 'txn'):
            self.open_lmdb()
        """
        Then do anything you want with env/txn here.
        """

解释(照搬原文,懒得翻译了):
The multi-processing actually happens when you create the data iterator (e.g., when calling for datum in dataloader:):
https://github.com/pytorch/pytorch/blob/461014d54b3981c8fa6617f90ff7b7df51ab1e85/torch/utils/data/dataloader.py#L712-L720
In short, it would create multiple processes which “copy” the state of the current process. This copy involves a pickle of the LMDB’s Env thus causes an issue. In our solution, we open it at the first data iteration and the opened lmdb file object would be dedicated to each subprocess.

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在Windows上使用PyTorchDataLoadernum_workers参数用于指定在数据加载过程中使用的子进程数量。它的作用是并行地从磁盘读取数据,以加速数据的加载和预处理过程。 然而,在Windows操作系统上,由于不支持"fork"机制,因此不能像在Linux或Mac上那样使用多个子进程。在Windows中,PyTorchDataLoadernum_workers参数设置为非零值,会将数据加载和预处理的任务放在主进程中执行,而不会使用额外的子进程。 因此,在Windows上使用PyTorch,无论将num_workers参数设置为多少,都只有一个主进程用于数据加载和预处理。这导致在Windows上的数据加载速度可能会较慢,特别是当数据集比较大。为了加快数据加载过程,可以考虑使用较小的batch_size或者使用更快的硬盘存储设备。 总之,在Windows上使用PyTorch,虽然可以设置num_workers参数,但其实际效果与设置为0相同,即数据加载是在主进程中完成的,无法利用多进程来加速数据加载过程。 ### 回答2: Windows上使用PyTorchdataloader,可以设置num_worker参数来指定数据加载的多线程工作数。num_worker参数的作用是控制加载数据的并发数,即同加载多少个样本。 在Windows操作系统上,通常建议将num_worker参数设置为0或1。这是因为Windows的多进程实现与Unix系统上的多进程实现有所不同,其中涉及到一些技术方面的限制和差异。 将num_worker设置为0意味着仅使用主进程加载数据,并且不会启动任何额外的工作线程。这是一种简单且可行的方式,当数据集规模较小,可以减少进程间的冲突问题,并提高代码的可移植性。 将num_worker设置为1意味着在主进程之外使用一个额外的工作线程来加载数据。这样可以在加载数据的同进行一些前处理操作,但同样不会引入进程间的冲突问题。 需要注意的是,Windows上的多线程工作数设置对于每个人的具体情况可能会有所不同。因此,根据实际需求和硬件配置,可以进行一些尝试和调整来选择最佳的num_worker值,以达到性能的最大化和代码的稳定运行。同,在使用多线程加载数据,还需要确保代码的正确性和线程安全性,以避免潜在的错误和异常情况的发生。 ### 回答3: 在使用PyTorch,可以使用Dataloader类来加载和预处理数据。在Dataloader中有一个参数叫做`num_workers`,它用于指定加载数据使用的线程数。 `num_workers`参数的作用是并行加载数据,它决定了有多少个子进程用于数据的预处理。使用多个子进程可以加快数据加载的速度,特别是当数据的预处理操作比较耗使用多个子进程可以提高数据加载的效率。 在Windows系统中,由于GIL(全局解释器锁)的存在,多线程并不会真正发挥出并行加载数据的效果,因此在Windows上使用`num_workers`参数设置多个线程的方法并不能有效提高数据加载的速度。相反,设置的`num_workers`越大,对于Windows系统来说,反而可能导致数据加载的速度变慢。 解决这个问题的一个方法是使用`torch.multiprocessing`模块中的`set_start_method`函数将后端设置为`'spawn'`,这样可以阻止使用fork进程来生成子进程,从而在Windows上实现真正的并行加载数据。 总而言之,在Windows系统上,使用`num_workers`参数设置多个线程的方法可能不会真正提高数据加载的速度。为了充分利用多核处理器的计算能力,可以考虑使用`torch.multiprocessing`模块中的函数来设置后端并行加载数据
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值