我在Python中实现了一个机器学习的期望最大化算法,基本上是IBM Model1用于机器翻译的实现(如果你想查看代码,这里是我的GitHub),它确实能工作,但速度非常慢。现在我在学习并行计算课程,我想知道是否可以使用Python多进程来更快地达到收敛。谁能给我一些建议或提示?我甚至不知道从哪里开始。
编辑:我在阅读时发现了一篇关于使用EM和MapReduce进行并行化的论文——也许这是一个更好的主意?
回答:
你的问题主要在于Python本身速度很慢。请记住,你的代码是在解释器中执行的。当你执行像第82行那样的代码,一次处理一个元素进行数值计算时,你就有了那一个计算——以及Python解释器的所有开销。
你首先要做的是使用numpy来向量化你的代码。与你通常的Python代码不同,numpy调用的是预编译的高效二进制代码。你能在numpy中隐藏的工作越多,你在解释器中浪费的时间就越少。
一旦你向量化了你的代码,如果它仍然太慢,你就可以开始对其进行性能分析。你应该能够找到很多关于如何向量化Python以及一些替代选项的简单示例。
编辑:让我澄清一下,并行化本身就很慢的代码基本上是没有意义的。首先,并行化慢代码会给人一种你已经有所改进的假象。并行代码的“扩展”应该始终与最快的单线程版本的相同代码进行比较(在合理范围内,不需要在开始任何并行代码之前用汇编语言编写所有东西)。例如,考虑一个有争议的锁。争夺锁的线程越多,代码运行得就越慢,你将不会获得(或会得到负面的)性能提升。减少锁争用的一个方法是简单地减慢争用锁的代码的速度。这使得看起来好像没有锁争用的开销,而实际上——你没有改进,因为你代码的最快单线程版本将超过你的并行代码。
此外,Python并不是学习如何编写并行代码的好语言。Python有GIL,这基本上迫使Python中的所有多线程代码像只有一个CPU核心一样运行。这意味着必须进行一些奇怪的技巧(比如你链接的那个),这些技巧有它们自己的额外缺点和问题(有时候需要/使用这样的技巧,但它们不应该是在单台机器上运行代码的默认方法)。不要指望你编写任何并行Python代码所学到的东西能转移到其他语言或帮助你完成课程。