web-dev-qa-db-fra.com

Accélérez la reconnaissance des entités nommées Spacy

J'utilise spacy pour reconnaître les adresses sur les pages Web. 

Mon modèle est initialisé à l'aide du nouveau code de type d'entité de spacy que l'on trouve ici: https://github.com/explosion/spaCy/blob/master/examples/training/train_new_entity_type.py

Mes données d'entraînement sont constituées de pages Web en texte brut avec leurs entités d'adresse postale et leurs positions respectives.

J'ai été capable de construire rapidement un modèle rapide pour commencer à faire des prédictions, mais j'ai trouvé sa vitesse de prédiction très lente.

Mon code fonctionne en effectuant une itération sur plusieurs pages HTML brutes, puis en insérant la version en texte brut de chaque page dans spacy au fur et à mesure de son itération. Pour des raisons que je ne peux pas entrer, je dois faire des prédictions avec Spacy page par page, à l'intérieur de la boucle d'itération.

Une fois le modèle chargé, j'utilise la méthode standard de prévision, à laquelle je fais référence en tant que phase de prévision/évaluation:

  doc = nlp(plain_text_webpage)

  if len(doc.ents) > 0:

         print ("found entity")

Des questions:

  1. Comment puis-je accélérer la phase de prédiction/reconnaissance d'entité? J'utilise une instance c4.8xlarge sur AWS et les 36 cœurs sont constamment saturés lorsque spacy évalue les données. Spacy convertit quelques millions de pages Web d'un travail d'une minute à un travail d'une heure ou plus.

  2. La vitesse de reconnaissance des entités augmentera-t-elle à mesure que mon modèle devient plus précis?

  3. Existe-t-il un moyen de supprimer les pipelines tels que le tagueur pendant cette phase, est-il possible de découpler ER et de rester précis? La suppression d’autres pipelines aura-t-elle une incidence sur le modèle lui-même ou s’agit-il d’une mesure temporaire?

  4. J'ai vu que vous pouvez utiliser le GPU pendant la phase de formation aux urgences. Peut-il également être utilisé dans cette phase d'évaluation dans mon code pour des prévisions plus rapides?


Mise à jour:

J'ai réussi à réduire considérablement le temps de traitement en:

  1. Utilisation d'un tokenizer personnalisé (utilisé celui de la documentation)

  2. Désactivation d'autres pipelines qui ne sont pas destinés à la reconnaissance d'entités nommées

  3. Au lieu d'alimenter spacy tout le corps de texte de chaque page Web, j'envoie seulement un maximum de 5 000 caractères.

Mon code mis à jour pour charger le modèle:

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

Cependant, il estencoretrop lent (20X plus lent que j'en ai besoin)

Questions:

  1. Puis-je apporter d'autres améliorations pour accélérer la reconnaissance des entités nommées? Tout le gras que je peux couper de spacy?

  2. Je cherche toujours à voir si une solution basée sur un GPU pourrait aider - j'ai vu que l'utilisation du GPU était prise en charge pendant la phase de formation à la reconnaissance d'entités nommées, peut-elle également être utilisée dans cette phase d'évaluation dans mon code pour des prédictions plus rapides?

5
podcastguy

Veuillez voir ici pour plus de détails sur le dépannage de la vitesse: https://github.com/explosion/spaCy/issues/1508

Les choses les plus importantes:

1) Vérifiez à quelle librairie BLAS est liée Numpy et assurez-vous qu’il est bien compilé pour votre machine. L'utilisation de conda est utile car vous obtenez alors le mkl d'Intel

2)

l'instance c4.8xlarge sur AWS et les 36 cœurs sont constamment saturés lorsque spacy évalue les données.

C'est probablement mauvais. Pour le moment, nous ne pouvons vraiment que paralléliser les multiplications de la matrice, car nous utilisons numpy ---, il n’ya donc aucun moyen d’enfiler des gros morceaux. Cela signifie que la bibliothèque BLAS lance probablement trop de threads. En règle générale, vous ne pouvez utiliser que 3-4 cœurs par processus. Essayez de définir les variables d’environnement de votre bibliothèque BLAS pour limiter le nombre de threads.

3) Utilisez nlp.pipe() pour traiter des lots de données. Cela augmente la multiplication de la matrice et rend le traitement plus efficace.

4) Votre boucle externe de "données d'alimentation par le biais de mon pipeline de traitement" est probablement parallèlement embarrassante. Alors, parallélisez-le. Utilisez soit le multitraitement de Python, soit quelque chose comme joblib, ou quelque chose comme Spark, ou lancez simplement 10 scripts bash en parallèle. Mais prenez le bloc de travail le plus externe et le plus élevé possible et exécutez-le de la manière la plus autonome possible.

En fait, il est généralement préférable d’exécuter plusieurs petites machines virtuelles au lieu d’une seule. C'est ennuyeux du point de vue opérationnel, mais cela signifie moins de partage des ressources.

1
syllogism_