[英]Python shared read memory
我正在使用大约8GB的数据集,并且还在使用scikit-learn在其上训练各种ML模型。 数据集基本上是一维int向量的列表。
如何使数据集可用于多个python进程或如何对数据集进行编码,以便可以使用multiprocessing
的类? 我一直在阅读ctypes
,也一直在阅读multiprocessing
的文档,但是我很困惑。 我只需要使数据对每个过程都可读,就可以使用它来训练模型。
我是否需要将共享的multiprocessing
变量作为ctypes?
如何将数据集表示为ctypes
?
我假设您可以将整个数据集以numpy数组的形式加载到RAM中,并且您正在Linux或Mac上工作。 (如果您使用的是Windows,或者无法将阵列放入RAM中,则应该将阵列复制到磁盘上的文件中,并使用numpy.memmap进行访问。您的计算机也会将磁盘中的数据缓存到RAM中尽可能,并且这些缓存将在进程之间共享,所以这不是一个糟糕的解决方案。)
在上述假设下,如果您需要对通过multiprocessing
创建的其他进程中的数据集进行只读访问,则只需创建数据集,然后启动其他进程即可。 他们将具有对原始名称空间中数据的只读访问权限。 它们可以更改原始名称空间中的数据,但是其他进程将看不到这些更改(内存管理器会将其更改的每个内存段都复制到本地内存映射中)。
如果您的其他流程需要更改原始数据集,并使这些更改对父流程或其他流程可见,则可以使用以下方法:
import multiprocessing
import numpy as np
# create your big dataset
big_data = np.zeros((3, 3))
# create a shared-memory wrapper for big_data's underlying data
# (it doesn't matter what datatype we use, and 'c' is easiest)
# I think if lock=True, you get a serialized object, which you don't want.
# Note: you will need to setup your own method to synchronize access to big_data.
buf = multiprocessing.Array('c', big_data.data, lock=False)
# at this point, buf and big_data.data point to the same block of memory,
# (try looking at id(buf[0]) and id(big_data.data[0])) but for some reason
# changes aren't propagated between them unless you do the following:
big_data.data = buf
# now you can update big_data from any process:
def add_one_direct():
big_data[:] = big_data + 1
def add_one(a):
# People say this won't work, since Process() will pickle the argument.
# But in my experience Process() seems to pass the argument via shared
# memory, so it works OK.
a[:] = a+1
print "starting value:"
print big_data
p = multiprocessing.Process(target=add_one_direct)
p.start()
p.join()
print "after add_one_direct():"
print big_data
p = multiprocessing.Process(target=add_one, args=(big_data,))
p.start()
p.join()
print "after add_one():"
print big_data
您可以将数据集从当前表示形式转换为新的numpy memmap对象,并在每个过程中使用它。 但是无论如何它不会很快,它只是提供了一些与ram一起使用数组的方法,实际上,它将是来自HDD的文件,部分缓存在RAM中。 因此,您应该更喜欢使用带有part_fit方法的scikit学习算法,并使用它们。
https://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html
实际上,joblib(在scikit-learn中用于并行化)会自动将您的数据集转换为memmap表示形式,以便在不同进程中使用它(当然,如果足够大的话)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.