【问题标题】:Using multiprocessing with AllenNLP decoding is sluggish compared to non-multiprocessing case与非多处理情况相比,使用 AllenNLP 解码的多处理是缓慢的
【发布时间】:2021-12-28 16:19:35
【问题描述】:

我正在使用 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 个句子,情况如下:

  • 没有多重处理:638 总处理秒数(以及经过的时间)。
  • 使用 4 进程池:经过时间 293 秒,总处理时间为 915 秒。
  • 使用 12 个进程池:经过时间 263 秒,总处理时间为 2024 秒。

进程越多,AllenNLP 的总处理时间越差 - 即使模型显式位于共享内存中,并且在调用期间跨越进程边界的唯一内容是输入文本和输出 JSON。

我已经进行了一些分析,首先让我感到震惊的是函数torch._C._nn.linear 在多处理情况下花费的时间要长得多。这个函数接受两个张量作为参数——但是没有张量通过进程边界,我正在解码,而不是训练,所以模型应该是完全只读的。似乎它必须是共享模型资源的锁定或竞争问题,但我完全不明白为什么会这样。而且我不是torch 程序员,所以我对正在发生的事情的理解有限。

任何指针或建议将不胜感激。

【问题讨论】:

  • 我还尝试使用copy.deepcopy 将预测器中的模型复制为池元素的初始化代码的一部分,但这只会增加创建池元素的时间,并且没有显着减少 AllenNLP 处理时间。

标签: pytorch multiprocessing allennlp


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    相关资源
    最近更新 更多