加速Spacy命名实体识别

pod*_*guy 7 python nlp spacy

我正在使用spacy来识别网页上的街道地址.

我的模型基本上使用spacy的新实体类型示例代码进行初始化:https : //github.com/explosion/spaCy/blob/master/examples/training/train_new_entity_type.py

我的培训数据包括纯文本网页及其相应的街道地址实体和角色位置.

我能够在spacy中快速构建模型以开始进行预测,但我发现它的预测速度非常慢.

我的代码通过遍历几个原始HTML页面然后将每个页面的纯文本版本提供给spacy来进行迭代.由于我无法进入的原因,我需要在迭代循环内逐页进行Spacy预测.

加载模型后,我使用标准的预测方法,我将其称为预测/评估阶段:

  doc = nlp(plain_text_webpage)

  if len(doc.ents) > 0:

         print ("found entity")
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 如何加快实体预测/识别阶段?我正在AWS上使用c4.8xlarge实例,当spacy正在评估数据时,所有36个核心都会不断超出.Spacy正在处理几百万个网页,从1分钟的工作到1个小时的工作.

  2. 随着我的模型变得更加准确,实体识别的速度会提高吗?

  3. 有没有办法在此阶段删除像tagger这样的管道,ER可以像这样解耦并仍然准确吗?删除其他管道会影响模型本身还是暂时的?

  4. 我看到你可以在ER训练阶段使用GPU,它是否也可以在我的代码的评估阶段用于更快的预测?


更新:

我设法通过以下方式显着缩短了处理时间:

  1. 使用自定义标记器(使用文档中的标记器)

  2. 禁用不适用于命名实体识别的其他管道

  3. 而不是将每个网页的整个文本都提供给spacy,我只发送最多5,000个字符

我加载模型的更新代码:

nlp = spacy.load('test_model/', disable=['parser', 'tagger', 'textcat'])
nlp.tokenizer = WhitespaceTokenizer(nlp.vocab)
doc = nlp(text)
Run Code Online (Sandbox Code Playgroud)

但是,它仍然太慢(比我需要的速度慢20倍)

问题:

  1. 我是否可以为加速命名实体识别做出任何其他改进?我可以从spacy切下什么脂肪?

  2. 我还在寻找基于GPU的解决方案是否会有所帮助 - 我看到在命名实体识别培训阶段支持使用GPU,它是否也可以在我的代码的评估阶段用于更快的预测?

syl*_*sm_ 8

有关速度故障排除的详细信息,请参阅此处:https : //github.com/explosion/spaCy/issues/1508

最重要的事情:

1) 检查哪个 BLAS 库 numpy 链接,并确保它为您的机器编译良好。使用 conda 很有帮助,因为您可以获得 Intel 的 mkl

2)

当 spacy 评估数据时,AWS 上的 c4.8xlarge 实例和所有 36 个内核不断地达到最大值。

那可能很糟糕。我们目前只能真正并行化矩阵乘法,因为我们使用的是 numpy --- 所以没有办法线程化更大的块。这意味着 BLAS 库可能启动了太多线程。一般来说,每个进程只能使用 3-4 个内核才能获利。尝试为 BLAS 库设置环境变量以限制线程数。

3) 使用nlp.pipe(), 处理批量数据。这使得矩阵乘法更大,使处理更有效。

4)您的“通过我的处理管道馈送数据”的外循环可能非常并行。所以,并行它。要么使用 Python 的多处理,或者类似 joblib 的东西,或者类似 Spark 的东西,或者只是并行触发 10 个 bash 脚本。但是,您可以选择最外层、最高级别的工作,并尽可能独立地运行它。

实际上,运行多个较小的 VM 而不是一个大型 VM 通常会更好。这在操作上很烦人,但这意味着更少的资源共享。