Pytorch数据集和共享内存?

Pytorch数据集和共享内存?,pytorch,python-multiprocessing,Pytorch,Python Multiprocessing,我想在torch.utils.data.Dataset中缓存数据。简单的解决方案是只在数据集的一个成员中保留某些张量。但是,由于torch.utils.data.DataLoader类生成了多个进程,因此缓存将只在每个实例的本地进行,并且可能会导致缓存相同张量的多个副本。有没有办法使用Python的多处理库在不同的加载程序进程之间共享数据?答案取决于您的操作系统和设置。如果您使用的是带有默认进程启动方法的Linux,则不必担心重复或进程通信,因为工作进程共享内存!这是通过共享内存(更多细节)作为

我想在
torch.utils.data.Dataset
中缓存数据。简单的解决方案是只在数据集的一个成员中保留某些张量。但是,由于
torch.utils.data.DataLoader
类生成了多个进程,因此缓存将只在每个实例的本地进行,并且可能会导致缓存相同张量的多个副本。有没有办法使用Python的多处理库在不同的加载程序进程之间共享数据?

答案取决于您的操作系统和设置。如果您使用的是带有默认进程启动方法的Linux,则不必担心重复或进程通信,因为工作进程共享内存!这是通过共享内存(更多细节)作为进程间通信(IPC)有效实现的。 对于Windows来说,事情更加复杂。从:

由于worker依赖于Python多处理,因此worker启动行为 在Windows上与Unix上不同

在Unix上,fork()是默认的多处理启动方法。使用 fork(),子工作人员通常可以访问数据集和Python 参数直接通过克隆的地址空间运行

在Windows上,spawn()是默认的多处理启动方法。使用 spawn(),启动另一个运行主脚本的解释器, 然后是接收数据集的内部辅助函数, 通过pickle序列化整理_fn和其他参数

这意味着动态缓存的
数据集
成员将在Linux上的所有进程之间自动共享。太好了!但是,在Windows上,进程将不会收到它们的副本(它们只在生成时收到
数据集
),因此您应该使用进程通信方案,例如通过
多处理
管道
队列
管理器
(最好是广播到多个进程,但必须将张量转换为列表)。这不是很有效,而且实现起来相当麻烦


尽管如此,还有另一种方法:内存映射(memmaping)。这意味着您的对象将被写入虚拟内存,并且所有进程都可以访问虚拟内存,而这些对象的相应“卷影副本”将在某个时间刷新并存在于您的硬盘驱动器上(可以放在
/tmp
目录中)。您可以在
mmap
模块中使用memmaping,在这种情况下,您的对象必须序列化为二进制文件,或者您可以使用
numpy.memmap
。您可以找到更多详细信息。

我想我以前已经成功地完成了这项工作,但不记得是如何实现的……我也对这个问题感兴趣,我也想知道