5

Tôi đang làm việc với bộ dữ liệu lớn ~ 8GB và tôi cũng đang sử dụng tính năng tìm hiểu để đào tạo các mô hình ML khác nhau trên đó. Tập dữ liệu về cơ bản là một danh sách các vectơ 1D của các int.Bộ nhớ đọc chia sẻ Python

Làm cách nào để làm cho tập dữ liệu có sẵn cho nhiều quy trình python hoặc làm cách nào tôi có thể mã hóa tập dữ liệu để tôi có thể sử dụng các lớp học của multiprocessing? Tôi đã đọc trên ctypes và tôi cũng đã đọc vào tài liệu của multiprocessing nhưng tôi rất bối rối. Tôi chỉ cần làm cho dữ liệu có thể đọc được cho mọi quy trình để tôi có thể đào tạo các mô hình với nó.

Tôi có cần phải chia sẻ các biến số multiprocessing được chia sẻ làm ctypes không?

Tôi làm cách nào để đại diện cho tập dữ liệu là ctypes?

Trả lời

3

Tôi giả định rằng bạn có thể tải toàn bộ tập dữ liệu vào RAM trong một mảng có nhiều mảng và rằng bạn đang làm việc trên Linux hoặc Mac. (Nếu bạn đang sử dụng Windows hoặc bạn không thể lắp mảng vào RAM, thì có lẽ bạn nên sao chép mảng đó vào một tệp trên đĩa và sử dụng numpy.memmap để truy cập vào nó. Máy tính của bạn sẽ lưu dữ liệu từ đĩa vào RAM cũng như nó có thể, và những kho lưu trữ đó sẽ được chia sẻ giữa các quá trình, vì vậy nó không phải là một giải pháp khủng khiếp.)

Theo các giả định ở trên, nếu bạn cần truy cập chỉ đọc vào tập dữ liệu trong các quy trình khác được tạo qua multiprocessing, bạn có thể chỉ cần tạo và sau đó khởi chạy các quy trình khác. Họ sẽ có quyền truy cập chỉ đọc vào dữ liệu từ vùng tên ban đầu. Chúng có thể thay đổi dữ liệu từ vùng tên ban đầu, nhưng những thay đổi đó sẽ không hiển thị với các tiến trình khác (trình quản lý bộ nhớ sẽ sao chép từng phân đoạn bộ nhớ mà chúng thay đổi vào bản đồ bộ nhớ cục bộ).

Nếu quá trình khác của bạn cần phải thay đổi các dữ liệu ban đầu và thực hiện những thay đổi đó có thể nhìn thấy quá trình cha mẹ hoặc các quá trình khác, bạn có thể sử dụng một cái gì đó như thế này:

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

Có thể là bản sao của Share Large, Read-Only Numpy Array Between Multiprocessing Processes

Bạn có thể chuyển đổi dữ liệu của bạn từ đại diện hiện tại để đối tượng NumPy memmap mới, và sử dụng nó từ mọi quá trình. Nhưng nó sẽ không được nhanh chóng anyway, nó chỉ cung cấp cho một số trừu tượng làm việc với mảng từ ram, trong thực tế nó sẽ được tập tin từ HDD, một phần lưu trữ trong RAM. Vì vậy, bạn nên sử dụng thuật toán scikit-tìm hiểu với phương pháp partial_fit, và sử dụng chúng.

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

Trên thực tế joblib (được sử dụng trong scikit-học cho parallelizing) tự động chuyển đổi dữ liệu của bạn để memmap đại diện để sử dụng nó từ các quá trình khác nhau (Nếu đó là đủ lớn, tất nhiên).

Các vấn đề liên quan