del*_*del 5 python-multiprocessing pytorch
我想将数据缓存在torch.utils.data.Dataset. 简单的解决方案是将某些张量保留在数据集的成员中。但是,由于该类torch.utils.data.DataLoader生成多个进程,因此缓存仅位于每个实例的本地,并且可能导致我缓存相同张量的多个副本。有没有办法使用Python的多处理库在不同的加载进程之间共享数据?
答案取决于您的操作系统和设置。如果您使用默认进程启动方法的Linux,则不必担心重复或进程通信,因为工作进程共享内存!这是通过共享内存有效地实现为进程间通信 (IPC)(更多详细信息请参见此处)。对于Windows,事情就更复杂了。从文档中:
由于工作程序依赖于 Python 多处理,因此与 Unix 相比,Windows 上的工作程序启动行为有所不同。
在 Unix 上,fork() 是默认的多处理启动方法。使用 fork(),子进程通常可以通过克隆的地址空间直接访问数据集和 Python 参数函数。
在 Windows 上,spawn() 是默认的多处理启动方法。使用spawn(),启动另一个解释器来运行主脚本,然后是内部工作函数,该函数通过pickle序列化接收数据集、collate_fn和其他参数。
这意味着动态缓存的Dataset成员将在 Linux 上的所有进程之间自动共享。那太棒了!但是,在 Windows 上,进程不会收到它们的副本(它们仅在生成Dataset时收到),因此您应该使用进程通信方案,例如通过multiprocessing Pipe,Queue或Manager(首选广播到多个进程,但您必须将张量转换为到列表)。这不是很有效,而且实施起来也很麻烦。
尽管如此,还有另一种方法:内存映射(memmaping)。这意味着您的对象将被写入虚拟内存,并且所有进程都将有权访问它,而这些对象的相应“卷影副本”将在某个时刻被刷新并存在于您的硬盘驱动器上(可以放置在/tmp目录)。您可以将 memmaping 与mmap模块一起使用,在这种情况下,您的对象必须序列化为二进制文件,或者您可以使用numpy.memmap. 您可以在这里找到更多详细信息。
| 归档时间: |
|
| 查看次数: |
4544 次 |
| 最近记录: |