首页 > 解决方案 > python中并行任务的好习惯

问题描述

我有一个生成数据的 python 脚本和一个使用 tensorflow 和 keras 对这些数据训练神经网络的脚本。两者都需要神经网络的实例。

由于我没有设置“允许增长”标志,因此每个进程都会占用完整的 GPU 内存。因此,我只是给每个进程自己的 GPU。(对于只有一个 GPU 的人来说,这可能不是一个好的解决方案……还有一个未解决的问题)

实际问题如下:两个实例都需要访问网络权重文件。我最近遇到了一堆崩溃,因为两个进程都试图访问权重。一个标志或类似的东西应该阻止每个进程访问它,而另一个进程正在访问。希望这不会造成瓶颈。我试图想出一个像 C 中的信号量这样的解决方案,但今天我在堆栈交换中找到了这篇文章。

重命名的想法对我来说似乎非常简单和有效。就我而言,这是一种好习惯吗?我将使用我自己的函数创建权重文件

self.model.save_weights(filepath='weights.h5$$$')

在学习过程中,保存后重命名为

os.rename('weights.h5$$$', 'weights.h5')

并使用函数将它们加载到我的数据生成过程中

self.model.load_weights(filepath='weights.h5')

?

这次重命名会覆盖旧文件吗?如果另一个进程当前正在加载,会发生什么?我会很感激其他想法如何多线程/多处理我的脚本。刚刚意识到在顺序脚本中生成数据、学习、生成数据……并不是真正的高性能。

编辑 1:忘了提到权重通过 keras 的保存功能存储在 .h5 文件中

标签: pythonmultithreadingmultiprocessing

解决方案


multiprocessing模块有一个RLock类,您可以使用它来规范对分片资源的访问。如果您记得在读取和写入之前获取锁并在之后释放它,这也适用于文件。使用锁意味着某些时候某个进程无法读取或写入文件。这有多少问题取决于两个进程必须访问文件的程度。

请注意,要使其正常工作,其中一个脚本必须在创建锁Process 后启动另一个脚本。

如果权重是 Python 数据结构,您可以将其置于multiprocessing.Manager. 这将为您管理对其控制下的对象的访问。请注意, aManager不适用于文件,仅用于内存对象

此外,在类 UNIX 操作系统上,Python 必须os.lockf锁定(部分)文件。请注意,这只是一个建议锁。也就是说,如果另一个进程调用lockf,返回值表明文件已经被锁定。它实际上并不会阻止您读取文件。

注意: 文件可以读写。只有当两个进程正在读取同一个文件(读取/读取)时才能正常工作。任何其他组合(读/写、写/读、写/写)都可能并最终会导致未定义的行为和数据损坏。

注意2: 另一种可能的解决方案涉及进程间通信。进程 1 写入一个新的 h5 文件(具有随机文件名),关闭它,然后发送一条消息(使用PipeorQueue到进程 2“我已经编写了一个新的参数文件 \path\to\file”。进程 2 然后读取文件并将其删除。这可以双向工作,但需要两个进程每隔一段时间检查和处理消息。这可以防止文件损坏,因为写入进程仅在完成文件后才通知读取进程


推荐阅读