加速Spacy命名实体识别

18

我正在使用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. 有没有办法在这个阶段移除像标记器这样的管道,ER是否可以分离开来而仍然保持准确性?删除其他管道会影响模型本身还是只是暂时的事情?

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


更新:

我成功大幅缩短了处理时间:

  1. 使用自定义分词器(使用文档中的分词器)

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

  3. 不再将每个网页的整个正文传递给spacy,而是只发送最多5000个字符

我的更新代码来加载模型:

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

然而,它依然太慢了(比我需要的慢20倍)

问题:

  1. 有什么其他的改进方法可以加速实体识别吗? Spacy中是否可以减少一些负担?

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

1个回答

11
请参阅此处以获取有关速度故障排除的详细信息:https://github.com/explosion/spaCy/issues/1508 最重要的事情:
1)检查numpy链接的BLAS库,并确保其为您的计算机编译。使用conda很有帮助,因为这样您就可以获得Intel的mkl
2)
引用: c4.8xlarge实例在AWS上,当spacy评估数据时所有36个内核都���断地达到最大值。
那可能是不好的。我们目前只能并行化矩阵乘法,因为我们正在使用numpy --- 所以没有办法线程大块内容。这意味着BLAS库可能启动了太多线程。通常而言,每个进程只能有效地使用3-4个内核。尝试设置BLAS库的环境变量以限制线程数。
3) 使用nlp.pipe(),处理数据批次。这使矩阵乘法更大,使处理更高效。
4)你的“通过我的处理管道馈送数据”的外部循环可能是令人尴尬的并行。所以并行。使用Python的多进程,或类似joblib的东西,或类似Spark的东西,或只是并行启动10个bash脚本。但尽可能地将最外层,最高���别的工作拆分成尽可能独立的部分运行。
实际上,通常最好运行多个较小的VM,而不是一个大的VM。这在操作上很麻烦,但意味着资源共享更少。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接