加速Spacy命名实体识别

时间:2018-04-06 23:44:54

标签: 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")

问题:

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

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

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

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

  5. 更新

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

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

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

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

    4. 我加载模型的更新代码:

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

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

      问题:

      1. 我是否可以加快指定实体识别的其他改进?我可以从spacy中减少任何脂肪吗?

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

1 个答案:

答案 0 :(得分:1)

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

最重要的事情:

1)检查哪个BLAS库numpy被链接,并确保它为您的机器编译好。使用conda很有帮助,因为你得到了英特尔的mkl

2)

  AWS上的c4.8xlarge实例和所有36个核心不断被最大化   当spacy正在评估数据时。

那可能很糟糕。我们现在只能真正地对矩阵乘法进行并行化,因为我们正在使用numpy ---所以没有办法对更大的块进行线程化。这意味着BLAS库可能会启动太多线程。通常,每个进程只能使用3-4个核心。尝试为BLAS库设置环境变量以限制线程数。

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

4)你的外部循环'#34;通过我的处理管道提供数据"可能是令人尴尬的平行。所以,将它并行化。要么使用Python的多处理,要么使用像joblib这样的东西,比如Spark,或者只是并行启动10个bash脚本。但是,尽可能独立地进行最外层,最高级别的工作。

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