Skip to main content
 首页 » 编程设计

python之使用 Python 多处理更新共享只读数据

2025年05月04日13birdshome

我正在尝试使用 Python 的多处理库来试验分布式神经网络。目前,我已将其设置为服务器进程创建神经网络并将输入分块以进行小批量梯度下降,并将批处理放入共享队列,由客户端进程处理,并将结果放入单独的共享队列。

到目前为止,一切正常,除了为了处理批处理并产生梯度,子进程需要网络权重的副本,我已经使用多处理数组共享了它。客户端进程只需要权重的只读副本,但服务器进程在每个训练时期后更新本地副本。

我的问题是如何更新共享内存以反射(reflect)更改后的权重,以便在下一个时期,客户端进程具有计算梯度的正确值。

请您参考如下方法:

自从阅读这篇文章以来,我一直在玩 multiprocessing 并发现更新 mp.Array 中的数据并不太难 - 让我兴奋的是使用循环迭代 Array 时,访问不是原子的。以下代码片段使用 mp.Process(使用 Pool 会更好,但这对我来说更快)设置了一个简单的 master-worker 集,其中 mp. Array 用于同步 master 经常更改的数据(尽可能快)

from multiprocessing import Process, RLock, Array 
from time import sleep 
 
def worker(n, array, arrayLock): 
    while True: 
        arrayLock.acquire() 
        print("Worker: %i -> %s" % (n, ",".join(str(i) for i in array))) 
        arrayLock.release() 
        sleep(n + 1) 
 
if __name__ == '__main__': 
    arrayLock = RLock() 
    array = Array('i', range(10), lock=arrayLock) 
 
    pd = {} 
    for i in range(3): 
        pd[i] = Process(target=worker, args=(i, array, arrayLock)) 
        pd[i].start() 
 
    try: 
        while True: 
            arrayLock.acquire() 
            for i in range(len(array)): 
                array[i] = -array[i] 
            arrayLock.release() 
    except KeyboardInterrupt: 
        pass 
 
    for p in pd.values(): 
        p.terminate() 

产生以下输出

~> python mp_shared.py 
Worker: 0 -> 0,1,2,3,4,5,6,7,8,9 
Worker: 1 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9 
Worker: 2 -> 0,1,2,3,4,5,6,7,8,9 
Worker: 0 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9 
Worker: 1 -> 0,-1,-2,-3,-4,-5,-6,-7,-8,-9 
Worker: 0 -> 0,1,2,3,4,5,6,7,8,9 

跨进程更新数据只是更改Array 中的值的问题。我遇到了一个问题,结果看起来像这样(注意数据的交替符号)

Worker: 0 -> 0,-1,2,-3,4,-5,6,-7,8,-9 
Worker: 1 -> 0,-1,2,-3,4,-5,6,-7,8,-9 
Worker: 2 -> 0,-1,2,-3,4,-5,6,-7,8,-9 

这是因为当我读取或写入数组时,为 Array 自动创建的 Lock 不会同步整个循环的访问!主进程将在 Array 中快速进出,在工作人员获取锁之间进行更改。

为了避免这种情况,我刚刚创建了自己的 RLock(需要是一个 RLock,因为触摸 Array 会使其获取,这将阻止如果您已经获得了 Lock) 用于 Array。我将 RLock 传递给所有工作人员,以便他们每个人都可以进行原子操作(在您的情况下,我相信读取和写入是原子的很重要,以防止梯度计算中的错误)。

编辑:

另一种选择似乎是 mmap,但我无法评论它的使用以及更改是否按预期工作。