Salut à toutes et tous ! Je suis Cyrile, Data Scientist au sein du groupe Crédit Mutuel Arkéa à Brest depuis 2017. Mon métier consiste à donner du sens à la donnée et la rendre exploitable aux métiers de la banque afin de faciliter leurs tâches et celle de nos clients au quotidien. Je vais vous présenter aujourd’hui une modélisation d’IA que nous avons réalisée au sein de notre équipe dans le but d’améliorer la reconnaissance du langage de manière automatique. Je vais vous expliquer comment ça marche, à quoi ça sert et comment on l’utilise dans le groupe Crédit Mutuel Arkéa.
C’est quoi l’IA ?
L’intelligence artificielle (IA) est un domaine vaste. La définition brute c’est : tout processus qui consiste à imiter le comportement humain. Ainsi, un programme qui vise à automatiser une tâche, aussi simple soit-elle, afin de faciliter le travail d’une personne ou de la remplacer sur cette même tâche, est de l’IA. De nos jours, celle-ci est assimilée à l’un de ses sous-domaines, très visible aux yeux du grand public, tant son évolution est rapide et impressionnante : le Machine Learning (ML).
Le ML est un pan de l’IA où l’on souhaite modéliser des problèmes. Mais au lieu que ce soit un humain qui fasse tout un tas de réglages pour adapter sa modélisation au problème, c’est la machine qui vient l’adapter de manière “autonome”. De ce fait, il est possible de modéliser des problèmes divers et très complexes. Aujourd’hui, c’est la modélisation du langage français qui va nous intéresser (rien que ça !).
Le Natural Language Processing
Modéliser le langage humain a toujours été un objectif pour le domaine du ML. En effet, cette tâche est très complexe, et y parvenir permettrait d’automatiser de nombreux processus sur des domaines où les humains règnent en maître. On peut remonter aux premières modélisations du texte aux années 1950 [1], avec les modélisations qu’on nomme “bag of word”, qui consistaient à modéliser des textes et extraire son information par la fréquence des mots utilisés. On peut sentir assez vite la limite de telles approches. En effet, si nous prenons en exemple les deux phrases : “Je pensais lire un livre nul, mais finalement je l’ai trouvé super !”, “Je pensais lire un livre super, mais finalement, je l’ai trouvé nul !” La fréquence des mots ne nous apprend rien, même pire ! Le sens des deux phrases est radicalement opposé. Ce qu’il manque, c’est la capacité à la modélisation de comprendre le sens des mots et leurs interactions dans une phrase. C’est là le but de tout un pan du ML. On a regroupé toutes ces tentatives sous une même bannière : le Natural Language Processing (NLP).
C’est d’un autre sous-domaine du ML qu’est venu le salut du NLP, à savoir le Deep Learning (DL). Ici les modélisations employées sont des réseaux de neurones multicouches pouvant être très profonds. L’avantage du DL est la capacité à s’adapter à des données très complexes. C’est en 2013 que la première modélisation du sens des mots a été développée : Word2Vec [2]. Avec Word2Vec, nous passons d’un mot à un vecteur dense, donc à une position dans un espace vectoriel. Le tour de force de cette application est que la structure algébrique de cet espace comporte le sens lexical commun des mots, par exemple si vous prenez la représentation vectorielle des mots : “roi”, “homme” et “femme” et que vous appliquez l’opération : “roi” – “homme” + “femme” vous tombez sur les coordonnées représentant le mot “reine”.
Cependant, on ne capte que le sens du mot en “absolu”, mais pas le sens relatif du mot dans la phrase. En effet, le sens de ce dernier est influencé par l’ensemble des mots du texte, et ces interactions qui influencent le mot peuvent être proches (par les voisins directs du mot) ou loin dans un texte. Et Word2Vec en est incapable, une fois le modèle entrainé le mot gardera toujours le même sens. Toute la suite de l’aventure du NLP vise à modéliser cette interaction par un procédé qu’on nomme “l’auto-attention”.
Il y eut beaucoup de tentatives pour créer cette interaction, mais c’est en juin 2017 que Google publie un article fondateur qui va changer l’approche et offrir des performances encore jamais atteintes sur le domaine. Google introduit alors une structure de réseau de neurones qui s’appelle “Transformer” se focalisant sur la tâche d’attention [3], puis en juin 2018 la première modélisation réalisée par OpenAI est publiée, GPT pour Generative Pre-trained Transformer [4], désormais très connue du grand public (aujourd’hui elle en est à sa quatrième génération [5]). Google arrive peu de temps après avec la modélisation BERT (Bidirectional Encoder Representations from Transformers) [6], qui, contrairement à GPT, n’est pas un générateur de texte, mais vient plutôt modéliser le langage afin d’extraire des informations issues de phrases. Finalement Meta (anciennement Facebook) sort sa modélisation RoBERTa (pour Robustly Optimized BERT pre training Approach) [7] qui vient améliorer BERT pour la modélisation de texte, tout ceci en anglais (que ce soit pour BERT ou RoBERTa)…
C’est en juillet 2020 que l’INRIA publie une modélisation inspirée de RoBERTa spécialisée pour le français qui se nomme CamemBERT [8].
Le camembert est <mask> 🙂
Le gros avantage de ces modélisations est d’offrir une approche “générique” qui va s’adapter à n’importe quelle tâche de NLP avec ou sans affinage (fine tuning). En effet, ces modèles sont gros (très gros même), par exemple CamemBERT possède 110 millions de paramètres, ce qui en fait encore à ce jour un très gros modèle. Les entraîner sont des tâches coûteuses et complexes, il serait donc intéressant de ne pas avoir à entraîner un nouveau modèle de zéro dès qu’on souhaite faire une nouvelle tâche. Et c’est là que la magie opère ! En effet, ces modèles sont entraînés sur une tâche générique et très simple consistant à lui faire compléter des textes à trous. Ce qui est bien avec cette tâche, c’est qu’à partir d’un corpus de textes. On peut lui générer un texte à trou de manière procédurale et comme nous connaissons le mot qu’on lui a masqué, nous avons la réalité terrain qui est souvent si coûteuse à avoir. C’est ce qu’on appelle, dans le milieu, de “l’apprentissage auto-supervisé”. Il est donc possible de lui faire avaler des tonnes de textes avec des milliards de mots masqués à estimer durant son apprentissage. Ainsi le modèle apprend le langage… Et de manière très efficace. Par exemple, pour CamemBERT, la balise pour lui masquer un mot est la balise “<mask>”, si bien que si on essaye les phrases :
“J’aime lire des <mask>.” le mot le plus probable est “livres”,
“J’aime lire le <mask>.” le mot le plus probable est “journal”,
“J’aime lire la <mask>.” le mot le plus probable est “Bible”.
On constate plusieurs choses. Tout d’abord, le mot estimé est très cohérent, mais surtout, c’est qu’il ne s’est pas trompé sur le genre et le nombre. Il a donc incorporé les notions de sens linguistique et de grammaire. Donc le modèle est performant pour modéliser le français et est du coup adaptable à de nombreuses autres tâches que juste prédire un mot manquant (qui, disons-le, est une tâche assez peu utile ;-)). Il peut par exemple comprendre le sens des deux phrases de la partie précédente, et lui faire évaluer le sentiment de chacune en symbolisant le sentiment par le nombre d’étoiles (une étoile correspondant à un sentiment très négatif et 5 étoiles à un sentiment très positif). Nous avons alors :
Autre exemple, si l’on souhaite détecter les entités nommées dans une phrase, qui est une tâche simple pour un humain, mais très vite ardue pour une machine. Par exemple la phrase suivante :
“Boulanger, habitant à Boulanger et travaillant dans le magasin Boulanger situé dans la ville de Boulanger. Boulanger a écrit le livre éponyme Boulanger, édité par la maison d’édition Boulanger.”
Il faut bien comprendre la sémantique de la phrase pour pouvoir la catégoriser correctement, et des modélisations ou des algorithmes standards en seraient incapables. Mais pour ce type de modèle, nous avons comme résultat :
De tels modèles sont implémentés aujourd’hui sur différents sujets. Ils permettent de traiter automatiquement des tâches sur des zones de texte de saisie libre sur de gros volumes, là précisément où il serait impossible qu’un opérateur traite toute la donnée. Les modèles nous permettent par exemple de vérifier certaines exigences issues de réglementations européennes dans les réponses des mails de nos conseillers. Ils permettent de détecter des controverses sur les entreprises pour les stratégies et charte éthique d’investissement du groupe sur des fils d’actualités en continu.
Cependant, un problème mentionné plus tôt demeure avec ces modélisations : leurs tailles… À titre d’exemple, sur une machine composée d’un seul CPU sur un texte de 400 mots, une inférence peut durer plus de huit secondes ! Il est extrêmement complexe de réaliser des inférences à échelle industrielle sur de très gros volumes de données, même pour des entreprises possédant un gros système d’information. C’est dans cette optique que nous avons entraîné et rendu en open-source via la plateforme HuggingFace-Hub une distillation du modèle CamemBERT, alias DistilCamemBERT.
DistilCamemBERT [9]
La taille de ce type de modèle influence énormément la capacité à modéliser le langage. Il est donc difficile d’entraîner une modélisation plus petite en partant de zéro et d’espérer atteindre des performances équivalentes. Cependant, il existe un domaine de ML spécialisé dans la réduction des modèles sans détériorer (ou limitant la détérioration) des performances. Il s’agit de la “distillation”. Le principe sur le papier est simple.
Nous avons un modèle de référence qu’on appelle dans ce domaine le modèle “professeur”, et une modélisation vierge, plus petite, qu’on nomme modèle “élève”. L’objectif de l’entraînement est de transférer le savoir acquis par le professeur à son élève, mais comme le modèle est plus petit, on va plutôt extraire un concentré pertinent du savoir du professeur, d’où le terme “distillation”.
Afin d’éviter tous biais d’apprentissage par rapport au professeur, le corpus de texte utilisé pour l’entraînement est identique à celui utilisé par le modèle d’origine CamemBERT. OSCAR [10], il s’agit d’un corpus créé pour ce type de modèle développé par l’INRIA où dans la version utilisée pour cet entraînement comportait 170 Go de texte.
La technique d’apprentissage en Deep Learning (DL) est la minimisation d’une fonction coût par descente du gradient. Il consiste à mettre à jour tous les poids de la modélisation en suivant l’opposé de la direction du vecteur gradient de la fonction coût. Il est donc important pour comprendre la modélisation de décrire la fonction coût pour comprendre ce qui est fait. Le schéma ci-dessous illustre notre procédure d’apprentissage.
On peut voir qu’elle est constituée de 3 fonctions coûts. En effet la procédure d’apprentissage du modèle est une combinaison linéaire de sous-tâches que nous allons décrire :
Solf Label Loss : cette fonction coût caractérise les méthodes de distillation sur les modèles de classification. Il s’agit d’exploiter la densité de probabilité sur l’ensemble des mots possibles connus par la modélisation professeur (qu’on appelle dictionnaire) et de rapprocher le comportement de l’élève. Le principal reproche de cette fonction coût est de focaliser l’apprentissage du modèle élève sur la tâche d’estimation des mots manquants. Elle ne témoigne pas de la qualité de création du vecteur dense représentant les mots dans la phrase ;
Cosine Loss : a contrario, la dernière couche cachée représentant la dernière représentation latente des mots est située en amont du classifieur. Une contrainte sur la colinéarité entre l’élève et le professeur est donc appliquée ;
MLM Loss : pour Masked Language Model. Il s’agit de la principale tâche d’entraînement du modèle professeur, comme nous l’avons vu il s’agit d’une tâche générique. Il s’agit également d’une partie de l’apprentissage en autonomie pour le modèle élève, car ne s’appuyant pas sur les résultats du modèle professeur.
Le temps d’entraînement est de 18 jours sur une machine équipée d’une carte NVidia TITAN RTX à 24 Go. Bon ! Le modèle est entraîné… Reste à évaluer les performances à présent.
Downstream task et performances
Il est possible d’évaluer la performance via l’évolution de la fonction coût le long des itérations des descentes de gradient. Mais pour ce type de modèle ce n’est pas très intéressant. Ce qui nous intéresse c’est la capacité du modèle à s’adapter à des tâches non vues durant l’apprentissage. C’est ce qu’on appelle dans le milieu les downstream task.
Nous en avons testé 4, correspondant chacun à une structure de modélisation particulière. Avec ces 4 downstreams tarks nous avons une vue plutôt globale des performances de modélisation.
Il est possible de visualiser ces tâches de manière générique de la manière suivante :
fig. X : les rectangles verts représentent un texte d’entrée, les rectangles bleus un deuxième texte juxtaposé au premier, les rectangles rouges les vecteurs de sortie de la modélisation et les ovales oranges la mécanique d’attention.
encodeur seq2vec : nous avons un texte en entrée et nous souhaitons extraire une information de ce texte. La tâche symbolisant cette structure sera ici la détection de sentiment, le but est de donner un texte en entrée et d’estimer si le texte est “positif” ou “négatif” ;
encodeur seq2seq : le but est d’extraire des informations de chaque mot composant le texte en entrée. Nous testerons la détection d’entités nommées ;
cross-encodeur seq2seq : par cross-encodeur, on sous-entend que la modélisation doit exploiter les informations conjointes issues de deux textes juxtaposés. Pour cette tâche particulière allons tester ce qu’on appelle le NLI (Natural Language Inference) ou également connu sous le nom de RTE (Recognizing Textual Entailment). La tâche consiste à dire si un texte prédicat est en contradiction, en accord ou neutre vis-à-vis d’un texte hypothèse, par exemple je peux avoir comme prédicat : “Paule joue à la balle.” et en hypothèse :
accord : “Paul s’est fait mal au pied en tapant trop fort dans le ballon.” ;
contradiction : “Paul posa sa queu de billard pour boir son vers de Whisky pure malt.”
neutre : “Paul aime les voitures, il a lui-même 5 voitures de collection.”
cross-encodeur seq2seq : cette tâche permet d’extraire des informations à l’échelle des mots en fonction du premier. Nous utiliserons la tâche de question/réponse, ou le premier texte est la question et le but est de déterminer le début et la fin de la réponse dans le second texte.
Évidemment, comme le but est de réaliser un modèle moins coûteux, nous déterminerons également le gain en temps d’inférence. Voici le tableau des performances obtenues :
Le score est donné par le f1-score et plus, il est proche de 100 %, meilleur il est. On constate que sur les tâches d’encodeur, le modèle est très bon, voire meilleur que le modèle original. Sur les tâches de cross-encodeur, nous avons une petite baisse de performance pour la tâche de NLI et par contre une relative grosse perte sur la tâche de question/réponse. Ceci n’est pas étonnant puisque les tâches de cross-encodeur sont des tâches plus ardues demandant un plus haut niveau d’abstraction, et ici la taille du modèle est très importante. Cependant, le gain calculatoire est bien réel (gain de 100 %) et les tâches d’encodeurs couvrent une très grosse partie des besoins.
À titre indicatif, tous les exemples donnés dans cet article sont issus du modèle DistilCamemBERT.
Adoption de la modélisation par la communauté
Ce sont des avancées qui vont au-delà du secteur bancaire, il nous semble donc important de pouvoir en faire profiter un maximum de personnes. C’est ce but qui nous a motivés à pousser la modélisation en Open Source. De plus, il existe un hub développé et entretenu par HuggingFace qui permet de pouvoir pousser des modèles de ce type. Ce hub et leur librairie qui va de pair (Transformers) font autorité dans le milieu permettant d’accéder et d’utiliser très facilement les modélisations. Une preuve ? Voici un exemple de code permettant d’utiliser le modèle spécialisé en analyse sentiment que nous avions vu plus tôt dans les exemples :
Vous trouverez tous les modèles sur les liens suivants :
- le modèle de base : https://huggingface.co/cmarkea/distilcamembert-base
- le modèle d’analyse de sentiment : https://huggingface.co/cmarkea/distilcamembert-base-sentiment
- le modèle de détection d’entité nommé : https://huggingface.co/cmarkea/distilcamembert-base-ner
- le modèle de NLI : https://huggingface.co/cmarkea/distilcamembert-base-nli
- le modèle de question/réponse : https://huggingface.co/cmarkea/distilcamembert-base-qa
Que du Python ? Pas seulement, en effet un certain nombre de nos modélisations ont été converties en ONNX (Open Neural Network Exchange), framework développé par Meta et Microsoft permettant de faire tourner ces modélisations sur d’autre langage (Java, C++, etc.), donc le langage n’est pas une barrière !
La modélisation a largement été adoptée avec un nombre de téléchargements important (et promis ce n’est pas nous qui téléchargeons en boucle les modélisations ;-)). Nous sommes dans le million de téléchargements depuis la création des modèles et nous sommes dans les ~30k téléchargements aujourd’hui sur 30 jours glissants.
Conclusion
Merci de votre lecture, si vous êtes arrivés à ces lignes, j’espère que vous avez pris plaisir à rentrer dans le domaine du Machine Learning et du Natural Language Processing autant que j’ai eu à l’écrire. N’hésitez pas à tester et “jouer” avec les modélisations proposées durant cet article, parfois simplement les manipulants des idées d’application peuvent émerger.
Pour les personnes souhaitant aller plus loin, voici l’article que nous avons présenté et eu le plaisir de soutenir à la conférence CAp (Conférence sur l’APprentissage automatique) 2022, bonne lecture !
Bibliographie
[1] : Zellig S. Harris (1954) Distributional Structure, WORD, 10:2-3, 146-162[2] : Mikolov, T., Sutskever, I., Chen, K., Corrado, G. S., and Dean, J. Distributed representations of words and phrases and their compositionality. In NIPS (Neural Information Processing Systems), 2013
[3] : Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł., and Polosukhin, I. Attention is all you need. In NIPS (Neural Information Processing Systems), 2017
[4] : Radford, A., Narasimhan, K., Salimans, T., and Sutskever, I. Improving language understanding by generative pre-training. In OpenAI Blog, 2018
[5] : OpenAI. GPT-4 Technical Report. In OpenAI Blog, 2023
[6] : Devlin, J., Chang M.-W., Lee, K., and Toutanova, K. BERT: Pre-training of deep bidirectional transformers for language understanding. In NAACL-HLT, 2018
[7] : Liu, Y., Ott, M., Goyal, N., Du, J., Joshi, M., Chen, D., Levy, O., Lewis, M., Zettlemoyer, L., and Stoyanov, V. RoBERTa: A robustly optimized BERT pretraining approach, 2019
[8] : Martin, L., Muller, B., Ortiz Suarez, P. J., Dupont, Y., Romary, L., Villemonte de La Clergerie, E., Seddah, D. and Sagot, B. CamemBERT: a tasty French language model. Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics, 2020
[9] : Delestre, C., Amar, A. DistilCamemBERT : une distillation du modèle français CamemBERT. Conférence sur l’Apprentissage automatique, 2022
[10] : Abadji, J., Ortiz Suarez, P. J., Romary, L. and Sagot, B. Towards a Cleaner Document-Oriented Multilingual Crawled Corpus. 2022.