与非多处理情况相比,使用多处理和 AllenNLP 解码速度较慢

Using multiprocessing with AllenNLP decoding is sluggish compared to non-multiprocessing case

我正在使用 AllenNLP(2.6 版)语义角色标记模型来处理一大堆句子。我的 Python 版本是 3.7.9。我在 MacOS 11.6.1 上。我的目标是使用 multiprocessing.Pool 来并行化工作,但是通过池进行的调用所花费的时间比在父进程中所花费的时间要长,有时实际上是这样。

在父进程中,我已将模型显式放置在共享内存中,如下所示:

from allennlp.predictors import Predictor            
from allennlp.models.archival import load_archive
import allennlp_models.structured_prediction.predictors.srl
PREDICTOR_PATH = "...<srl model path>..."

archive = load_archive(PREDICTOR_PATH)
archive.model.share_memory()
PREDICTOR = Predictor.from_archive(archive)

我知道模型只在父进程中加载​​一次。无论是否要使用池,我都会将模型放在共享内存中。正如许多人所推荐的,我正在使用 torch.multiprocessing,并且我正在使用 spawn 启动方法。

我正在使用 Pool.apply_async 调用池中的预测器,我正在为子进程中的调用计时。我知道池正在使用可用的 CPU(我有六个内核),而且我还远远没有 运行 物理内存不足,因此没有理由将子进程交换到磁盘。

这是一批 395 个句子的结果:

进程越多,AllenNLP 的总处理时间就越差——即使模型明确地在共享内存中,并且在调用期间唯一跨越进程边界的是输入文本和输出 JSON.

我做了一些分析,我首先想到的是函数 torch._C._nn.linear 在多处理情况下花费的时间明显更长。此函数将两个张量作为参数——但没有张量跨进程边界传递,而且我正在解码,而不是训练,因此该模型应该是完全只读的。看起来这一定是共享模型资源的锁定或竞争问题,但我完全不明白为什么会这样。而且我不是 torch 程序员,所以我对正在发生的事情的理解是有限的。

如有任何指点或建议,我们将不胜感激。

原来我没有比较正确的东西。这个线程:https://github.com/allenai/allennlp/discussions/5471 进入所有细节。简而言之,因为 pytorch 可以在幕后使用额外的资源,所以当 运行 并行运行两个实例时,我没有多处理的基线测试不会对我的计算机造成足够的负担;我必须 运行 4 个实例才能看到惩罚,在那种情况下,总处理时间对于 4 个并行非多处理调用或一个具有 4 个子进程的多处理情况基本相同。