Spark NLP : le traitement du langage naturel distribué, de la tokenisation aux LLM
State of the Art Natural Language Processing
En bref
- De quoi s’agit-il ?
- Spark NLP étend Apache Spark avec des annotateurs natifs pour le NLP et l'inférence de grands modèles. La bibliothèque vise les équipes qui ont déjà des données massives dans Spark et qui refusent de sortir du cluster pour traiter du texte.
- À qui s’adresse-t-il ?
- Adoptez Spark NLP si vos textes vivent déjà dans Spark et que le coût de sortie du cluster dépasse le coût d'apprentissage de la bibliothèque. Ne l'adoptez pas si vous traitez quelques milliers de documents par jour sur un seul serveur : spaCy ou un pipeline Hugging Face en Python simple demandera moins de configuration.
- Puis-je l’utiliser commercialement ?
- Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 3 jours.
- En quel langage est-il écrit ?
- Principalement Scala, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème : traiter du texte là où il est déjà stocké
La plupart des bibliothèques NLP supposent que le texte tient sur une machine. Vous chargez un corpus en mémoire, vous construisez un pipeline d'annotateurs, vous écrivez les résultats. Cela fonctionne jusqu'à ce que le corpus dépasse quelques gigaoctets, ou jusqu'à ce que les données soient déjà dans un lac de données distribué et qu'il faille les déplacer pour les analyser. Spark NLP prend le problème par l'autre bout : les annotateurs sont des Transformers Spark, ils s'exécutent sur les partitions existantes et le texte ne quitte pas le cluster. Le public visé est donc précis : des équipes qui ont déjà une infrastructure Spark, qui traitent des volumes que le monoligne ne digère pas, et qui veulent enchaîner tokenisation, plongements, reconnaissance d'entités nommées et classification dans le même graphe d'exécution que leurs autres traitements. Le README annonce plus de 100 000 pipelines et modèles pré-entraînés couvrant plus de 200 langues, ce qui donne la mesure de l'ambition : couvrir l'essentiel des tâches NLP classiques sans que l'utilisateur ait à entraîner quoi que ce soit.
Annotateurs, pipelines et sessions Spark : le mécanisme réel
Spark NLP ne remplace pas Spark, il l'étend. Une session se crée via sparknlp.start(), qui accepte des paramètres documentés dans le README : gpu=True pour le support GPU, apple_silicon=True pour macOS M1 et M2, memory="16G" pour la mémoire du driver. Une fois la session ouverte, deux objets structurent le travail. Les annotateurs (tokenizer, embeddings, NER, classificateur) transforment un DataFrame colonne par colonne. Les pipelines assemblent ces annotateurs en une séquence réutilisable, ou chargent une séquence déjà entraînée via PretrainedPipeline. L'exemple du README charge 'explain_document_dl' en anglais, appelle pipeline.annotate(text) et récupère un dictionnaire dont les clés sont 'entities', 'stem', 'checked', 'lemma', 'document', 'pos', 'token', 'ner', 'embeddings' et 'sentence'. La valeur de 'entities' pour le texte sur La Joconde est ['Mona Lisa', 'Leonardo', 'Louvre', 'Paris']. Ce qui compte ici n'est pas la sortie en elle-même mais le fait que chaque clé corresponde à un étage du pipeline : le document est découpé en phrases, les phrases en tokens, les tokens reçoivent une étiquette POS et un lemme, puis les entités sont extraites. Vous pouvez reconstruire cette chaîne annotateur par annotateur au lieu d'utiliser un pipeline figé, ce qui est le vrai intérêt du modèle : la granularité du contrôle reste dans vos mains, à condition d'accepter la verbosité de l'API.
Ce que la bibliothèque importe, et pourquoi cela change le calcul
Le README liste quatre formats d'import de modèles : TensorFlow, ONNX, OpenVINO et Llama.cpp (GGUF). Ce n'est pas un détail cosmétique. Cela signifie qu'un modèle entraîné ailleurs peut être exécuté dans un job Spark sans réécriture, et que le choix du moteur d'inférence devient une décision d'exploitation. ONNX et OpenVINO visent le CPU avec des optimisations de graphe. GGUF via Llama.cpp vise les modèles de génération quantifiés, ce qui ouvre la porte à des LLM qui tiennent sur des nœuds sans GPU dédié. Le README cite parmi les architectures supportées BERT, RoBERTa, DeBERTa, XLM-RoBERTa, Longformer, ELECTRA, ALBERT, DistilBERT, XLNet, ELMO, Universal Sentence Encoder, T5, BART, MarianMT, M2M100, GPT2, Whisper, Llama-2, Llama, Mistral, Phi, Qwen2, E5 et Instructor. La conséquence pratique est double. D'un côté, vous n'êtes pas enfermé dans un format de poids propriétaire. De l'autre, chaque format apporte ses propres contraintes de conversion et de performance, et rien dans le README ne permet de savoir lequel sera le plus rapide sur votre matériel. C'est à vous de mesurer, sur vos données, avec vos nœuds.
Mise en route : commandes et clés de configuration
Le README donne une séquence d'installation explicite. Il faut Java 8 ou 11, Oracle ou OpenJDK, puis un environnement conda : conda create -n sparknlp python=3.7 -y, conda activate sparknlp, puis pip install spark-nlp==6.4.2 pyspark==3.3.1. La version de pyspark n'est pas anodine : le README précise que spark-nlp est par défaut basé sur pyspark 3.x, et le tableau des paquets fait correspondre Apache Spark 3.0 à 3.5 au paquet Maven spark-nlp pour le CPU, spark-nlp-gpu pour le GPU, spark-nlp-aarch64 pour Linux AArch64 et spark-nlp-silicon pour Apple Silicon. Les fonctions de démarrage suivent la même logique : sparknlp.start(), sparknlp.start(gpu=True), sparknlp.start(aarch64=True), sparknlp.start(apple_silicon=True). Deux réserves figurent noir sur blanc : M1/M2 et AArch64 sont en support expérimental. Si vous déployez sur ces architectures, vous ne déployez pas sur une cible de production stabilisée. Le reste de la configuration passe par les paramètres des annotateurs et par le choix du pipeline pré-entraîné, dont le nom et la langue sont les deux arguments de PretrainedPipeline.
La version de Spark est un contrat, pas une suggestion
La contrainte la plus concrète de Spark NLP n'est pas algorithmique, elle est matricielle. Le tableau des paquets associe chaque version majeure de Spark à un artefact Maven distinct. Un cluster en Spark 3.2 avec le paquet destiné à Spark 3.5 ne fonctionnera pas, et l'erreur ne sera pas nécessairement explicite. Cela impose une coordination entre l'équipe qui gère le cluster et celle qui écrit les pipelines. Dans une organisation où la plateforme Spark monte en version tous les dix-huit mois, cela signifie une fenêtre de migration à chaque fois : reconstruire l'environnement, retester les pipelines, vérifier que les modèles pré-entraînés restent chargeables. Le README ne décrit pas de mécanisme de compatibilité croisée. Il faut donc traiter la version de Spark comme une dépendance dure du projet, au même titre qu'une version de bibliothèque native. Ce n'est pas un défaut de conception, c'est le prix de l'intégration native à Spark, et ce prix doit être budgété.
Quand Spark NLP est le mauvais outil
Le cas défavorable est simple à énoncer. Si vous traitez quelques milliers de documents par jour sur une seule machine, démarrer une SparkSession pour cela ajoute une couche de sérialisation, de planification et de gestion mémoire qui ne vous rapporte rien. Vous payez la distribution sans en avoir besoin. Le deuxième cas défavorable concerne les environnements où Java 8 ou 11 n'est pas disponible ou ne peut pas l'être, par exemple une image de conteneur verrouillée sur une version plus récente du JRE : la bibliothèque ne s'installera pas dans les conditions décrites. Le troisième cas est celui du prototypage exploratoire. Charger un pipeline pré-entraîné pour jeter un œil à des entités est rapide, mais dès que vous voulez modifier un étage, vous manipulez l'API des annotateurs Spark, plus lourde que l'équivalent Python d'un pipeline Hugging Face. Enfin, le support expérimental d'Apple Silicon et d'AArch64 rend ces plateformes inadaptées à une charge de production non surveillée. Le README ne donne aucune garantie de stabilité pour ces cibles, et il faut le prendre au mot.
Face à spaCy et aux pipelines Hugging Face
La comparaison utile n'est pas celle des architectures de modèles, c'est celle du modèle d'exécution. spaCy et les pipelines Hugging Face en Python s'exécutent dans un processus, sur une machine, avec une boucle d'inférence que vous contrôlez entièrement. Ils excellent quand le corpus tient en mémoire et que le débit se règle par le nombre de workers. Spark NLP déplace la boucle dans le planificateur Spark : la parallélisation, la tolérance aux pannes et la reprise sur échec sont héritées du moteur, pas écrites par vous. La différence se voit au moment du passage à l'échelle. Ajouter des nœuds à un cluster Spark est une opération d'infrastructure. Réécrire un script spaCy pour qu'il tienne sur dix machines est un projet. En contrepartie, Spark NLP vous demande d'accepter les contraintes de Spark : versions figées, sérialisation, temps de démarrage de session, et une courbe d'apprentissage sur les DataFrames. Le choix se résume donc à une question de volume et d'emplacement des données, pas à une question de qualité de modèles.
Licence, modèles et coût de maintenance
Le code de Spark NLP est publié sous Apache-2.0, une licence permissive qui autorise l'usage commercial, la modification et la redistribution, avec les obligations habituelles de conservation des mentions et de l'état des modifications. Cette licence couvre le dépôt. Elle ne couvre pas automatiquement les modèles pré-entraînés téléchargés depuis le site du projet, dont les conditions peuvent différer selon l'origine des poids et les données d'entraînement. Le README ne détaille pas ce point, et c'est une zone à vérifier au cas par cas avant une mise en production, en particulier pour les modèles dérivés de Llama ou de Mistral. Sur la maintenance, les versions récentes listées sont 6.4.0, 6.4.1 et 6.4.2, avec une cadence de publication d'environ un mois entre chacune, et un dernier push en septembre 2026. Cette cadence implique de suivre les versions si vous voulez les correctifs, mais chaque montée de version doit être testée contre vos pipelines et votre version de Spark. Le coût réel n'est pas la licence, il est le temps passé à maintenir l'alignement entre trois éléments : la version de Spark du cluster, la version de spark-nlp et les modèles que vous avez épinglés.
Conclusion éditoriale
Adoptez Spark NLP si vos textes vivent déjà dans Spark et que le coût de sortie du cluster dépasse le coût d'apprentissage de la bibliothèque. Ne l'adoptez pas si vous traitez quelques milliers de documents par jour sur un seul serveur : spaCy ou un pipeline Hugging Face en Python simple demandera moins de configuration. Avant de vous engager, vérifiez trois choses : la compatibilité entre votre version de Spark et le paquet Maven choisi dans le tableau du README, la disponibilité de la langue et de la tâche visées dans les modèles pré-entraînés, et les conditions de la licence Apache-2.0 pour les modèles que vous téléchargez, car le code et les poids ne relèvent pas nécessairement du même régime.
Notes de la communauté