Python共享读取内存

时间:2016-08-07 19:49:21

标签: python python-2.7 scikit-learn ctypes python-multiprocessing

我正在处理大约8GB的数据集,而且我还使用scikit-learn来训练各种ML模型。数据集基本上是一维的1D向量列表。

如何使数据集可用于多个python进程,或者如何编码数据集以便我可以使用multiprocessing的类?我一直在ctypes上阅读,而且我也在阅读multiprocessing的文档,但我很困惑。我只需要让数据对每个进程都可读,这样我就可以用它来训练模型。

我是否需要将共享的multiprocessing变量作为ctypes?

如何将数据集表示为ctypes

2 个答案:

答案 0 :(得分:3)

我假设您能够将整个数据集加载到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

答案 1 :(得分:1)

可能与Share Large, Read-Only Numpy Array Between Multiprocessing Processes

重复

您可以将数据集从当前表示转换为新的numpy memmap对象,并在每个进程中使用它。但它无论如何都不会很快,它只是提供了一些从ram处理数组的抽象,实际上它将是来自HDD的文件,部分缓存在RAM中。所以你应该更喜欢scikit-learn algos和partial_fit方法,并使用它们。

https://docs.scipy.org/doc/numpy/reference/generated/numpy.memmap.html

实际上,joblib(用于scikit-learn for parallelizing)会自动将数据集转换为memmap表示,以便在不同的进程中使用它(如果它足够大,当然)。