Spacy 训练多线程 CPU 用法

Spacy training multithread CPU usage

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

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

唯一 multi-threaded 是矩阵乘法,在 v2.0.8 中是通过 numpy 完成的,它将它们委托给 BLAS 库。其他都是 single-threaded.

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

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

最后,并行的效率很大程度上取决于batch-size。在小批量上,矩阵很小,per-update 例程(例如 Adam 优化器)花费更多时间。

我通常禁用 multi-threading 并在单个核心上进行训练,因为这是最有效的(在 dollars-for-work 的意义上)---然后我将更多模型训练为单独的过程(通常在单独的 GCE VM 上)。

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

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

如果您怀疑您的 BLAS 有问题,可以尝试使用 conda 安装 numpy。这将为您提供一份链接到英特尔 MKL 库的副本。