我有一个 python 脚本,它正在生成数据,还有一个脚本正在使用该数据使用 tensorflow 和 keras 训练神经网络。两者都需要神经网络的实例。
由于我没有设置“允许增长”标志,每个进程都会占用完整的 GPU 内存。因此,我只是为每个进程提供了自己的 GPU。 (对于只有一个 GPU 的人来说也许不是一个好的解决方案......又是一个 Unresolved 问题)
实际问题如下:两个实例都需要访问网络权重文件。我最近发生了一系列崩溃,因为两个进程都试图访问权重。当另一个进程正在访问时,标志或类似的东西应该阻止每个进程访问它。希望这不会造成瓶颈。 我试图想出一个像 C 中的信号量这样的解决方案,但今天我发现了这个 post在堆栈交换中。
重命名的想法对我来说似乎非常简单且有效。对于我来说,这是一个好的做法吗?我将用我自己的函数创建权重文件
self.model.save_weights(filepath='weights.h5$$$')
在学习过程中,保存后重命名为
os.rename('weights.h5$$$', 'weights.h5')
并使用函数将它们加载到我的数据生成过程中
self.model.load_weights(filepath='weights.h5')
?
此重命名会覆盖旧文件吗?如果其他进程当前正在加载,会发生什么情况?我希望了解如何多线程/多处理我的脚本的其他想法。刚刚意识到,在顺序脚本中生成数据、学习、生成数据……并不是真正高效。
编辑1:忘记提及权重通过keras的保存功能存储在.h5文件中
最佳答案
多处理
模块有一个RLock
可用于调节对分片资源的访问的类。 如果您记得在读写之前获取锁并在之后释放它,这也适用于文件。使用锁意味着有时某个进程无法读取或写入文件。这个问题的严重程度取决于两个进程必须访问该文件的程度。
请注意,要实现这一点,其中一个脚本必须在创建锁之后将另一个脚本作为进程
启动。
如果权重是 Python 数据结构,您可以将其置于 multiprocessing.Manager
的控制之下。 。这将为您管理对其控制下的对象的访问。 请注意,Manager
不适用于文件,而仅用于内存中的对象。
此外,在类 UNIX 操作系统上,Python 有 os.lockf
锁定文件(部分)。请注意,这只是一个咨询锁。也就是说,如果另一个进程调用lockf
,则返回值表明该文件已经被锁定。它实际上并不会阻止您读取该文件。
注意: 文件可以被读取和写入。 仅当两个进程读取同一个文件(读/读)时,此功能才能正常工作。所有其他组合(读/写、写/读、写/写)都可能并最终会导致未定义的行为和数据损坏。
注2:
另一种可能的解决方案涉及进程间通信。
进程 1 写入一个新的 h5 文件(具有随机文件名),关闭它,然后向进程 2 发送一条消息(使用Pipe
或队列
“我已经编写了一个新的参数文件\路径\到\文件”。
然后进程 2 读取该文件并将其删除。这可以双向工作,但要求两个进程经常检查和处理消息。这可以防止文件损坏,因为写入进程仅在完成文件后才通知读取进程。
关于python - python 中并行任务的良好实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54003532/