Spacy培训多线程CPU使用率

时间:2018-03-26 12:57:13

标签: python multithreading nlp spacy

我用自己的NER管训练一些模型。我需要在lxc容器中运行spacy,这样我就可以运行python3.6(允许多线程训练)。
但是..在我的7核上被授权在我的容器上运行只有1次运行在100%其他运行在40-60%(实际上他们从100%开始但在几分钟后减少)。我真的想提高这个%核心使用率。有什么想法去哪儿看?这可能是生产者/消费者的问题吗?

ENV:
- spaCy版本2.0.8
- 位置/root/.env/lib/python3.6/site-packages/spacy
- 平台Linux-3.14.32-xxxx-grs-ipv6-64-x86_64-with-debian-buster-sid
- Python版本3.6.4

1 个答案:

答案 0 :(得分:2)

唯一的多线程是矩阵乘法,在v2.0.8中通过numpy完成,它将它们委托给BLAS库。其他一切都是单线程的。

您应该检查您的numpy链接到哪个BLAS库,并确保已为您的计算机正确编译了库。在我的机器上,我通过pip安装的numpy带有一个OpenBLAS副本,认为我的机器有一个Prescott CPU。这可以防止它使用AVX指令。因此,如果我在我的机器上从pip安装默认numpy,它运行速度比应该慢2-3倍。

另一个问题是OpenBLAS可能会启动比应该更多的线程。这似乎在容器中特别常见。

最后,并行性的效率在很大程度上取决于批量大小。在小批量中,矩阵很小,并且每个更新例程(例如Adam优化器)占用的时间更多。

我通常禁用多线程并在单个核心上进行训练,因为这是最有效的(在工作资金的意义上) - 然后我将更多模型训练为单独的进程(通常在单独的GCE上)虚拟机)。

在撰写spaCy时,我并未假设目标是使用大量核心。目标是效率。使用整个机器执行可在单个核心上完成的相同工作并不是一种美德。许多论文在这方面都非常误导。例如,在云中启动12个培训流程并使用Hogwild等异步SGD策略进行优化可能会令人满意。这是一种燃烧大量能量的有效方法,但不一定能更快地训练你的模型:使用亚当和更小的批量大小,训练更稳定,并且通常在更少的迭代中达到相同的准确度。同样,我们可以扩大网络,让机器得到锻炼...但为什么呢?目标是训练模型。将一堆矩阵相乘是一种手段,而不是目的。

我最关心的问题是可怕的BLAS联动情况。这将在v2.1中得到很大改进,因为我们将带来我们自己的OpenBLAS内核。默认情况下,内核将是单线程的。

如果您怀疑BLAS是坏的,那么尝试一个简单的事情就是尝试使用conda安装numpy。这将为您提供与英特尔MKL库相关联的副本。