Spacy训练多线程CPU使用率

Tho*_*hoc 3 python multithreading nlp spacy

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

环境:
- 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

syl*_*sm_ 6

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

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

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

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

我通常禁用多线程并在单核上进行训练,因为这是最有效的(从工作成本的意义上来说)——然后我将更多模型作为单独的进程进行训练(通常在单独的 GCE VM 上)。

在编写 spaCy 时,我并没有假设目标是使用大量内核。目标是效率。使用整个机器来执行可以在单个内核上完成的相同工作并不是一种美德。很多论文在这方面都具有很大的误导性。例如,跨云启动 12 个训练流程并使用异步 SGD 策略(例如 Hogwild!)进行优化可能会让人感到满意。这是一种消耗大量能量的有效方法,但不一定能更快地训练模型:使用 Adam 和较小的批量大小,训练更加稳定,并且通常可以在更少的迭代中达到相同的精度。同样,我们可以扩大网络,以便机器得到锻炼……但为什么呢?目标是训练模型。一堆矩阵相乘是一种手段,而不是目的。

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

如果您怀疑 BLAS 不好,可以尝试的一个简单方法是尝试使用 conda 安装 numpy。这将为您提供一个链接到英特尔 MKL 库的副本。