NLP & fastai | SentencePiece

Pierre Guillou
7 min readDec 2, 2019

--

Ce post concerne une partie des vidéos 10 du cours fastai de Rachel Thomas sur NLP (A code-first introduction to NLP) de 2019 et 10 (notes) de 2018 sur NLP du cours de Jeremy Howard (Introduction to Machine Learning for Coders). Son objectif est d’expliquer les concepts clés du tokenizer/numerizer SentencePiece présenté dans les vidéos et son notebook associé: nn-turkish.ipynb (NLP, 2019).

Autres posts de la série NLP & fastai: Topic Modeling | Sentiment Classification | Language Model | Transfer Learning | ULMFiT | MultiFiT | French Language Model | Portuguese Language Model | RNN | LSTM & GRU | Sequence-to-Sequence Model (seq2seq) | Attention Mechanism | Transformer Model | GPT-2

Motivation

Pour qu’un modèle de Deep Learning appliqué au NLP (Natural Language Processing) puisse “lire” un texte, il est nécessaire de le pré-processer afin de le transformer en série de numéros (note: même s’il ne s’agit pas du même processus de pré-traitement, nous pouvons comparer ce processus avec celui appliqué aux images qui sont “vues” par un modèle ConvNet comme une série de numéros qui sont les valeurs des pixels).

Tokenizer/Numerizer

Ce pré-traitement se fait via un tokenizer qui va détecter les tokens les plus fréquents dans le corpus d’entraînement (mots, ensembles de caractères, signes de ponctuation…) afin de les lister dans ce qui est appelé un vocabulaire dont la taille (nombre de tokens) est définie au préalable (les tailles les plus courantes sont 15 000, 30 000 et 60 000).

Une fois obtenu ce vocabulaire, chaque token du texte peut-être remplacé via le numerizer par son numéro qui est son index dans le vocabulaire (des tokens spéciaux comme le token UNKNOW permet de numériser tout token non listé dans le vocabulaire). Le corpus d’entraînement est ainsi numérisé et peut alors être utilisé par le modèle de Deep Learning.

Note: le même vocabulaire sera utilisé pour les datasets de validation et test.

SpaCy

Un tokenizer/numerizer très utilisé et qui est d’ailleurs celui par défaut de fastai v1 est SpaCy avec un vocabulaire de 60 000 tokens.

Ce tokenizer va appliquer une série de règles par défaut en fonction du langage du corpus auquel il s’applique afin de détecter les tokens les plus fréquents (les mots et les signes de ponctuations), créer le vocabulaire et le numériser.

Cependant, cette dépendance de SpaCy aux règles spécifiques de chaque langage ainsi que la recherche de solution au problème des mots rares a amené la création d’autres tokenizers/numerizers indépendants du langage du corpus d’entraînement.

Image source: SpaCy Tokenization

SentencePiece

En 2018, Taku Kudo et John Richardson de Google ont créé SentencePiece, un tokenizer/numerizer de sous-mots qui est indépendant du langage du corpus d’entraînement et qui tente de résoudre “open vocabulary problem” des NMT (Neural Machine Translation), cad le traitement des mots rares qui ne se trouvent pas dans le vocabulaire des tokenizers/numerizers classiques de mots:

Voici une présentation de SentencePiece extraite de l’article original:

As NMT (Neural Machine Translation) approaches are standardized and mov-ing forward to more language-agnostic architectures, it is becoming more important for the NLP community to develop a simple, efficient, reproducible and language independent pre- and post-processor that can easily be integrated into Neural Network-based NLP systems, including NMT.

In this demo paper, we describe SentencePiece, a simple and language independent text tokenizer and detokenizer mainly for Neural Network-based text generation systems where the size of vocabulary is predetermined prior to the Neural model training.

SentencePiece implements two subword segmentation algorithms, byte-pair-encoding (BPE) (Sennrich et al.,2016) and unigram language model (Kudo,2018), with the extension of direct training from raw sentences. SentencePiece enables building a purely end-to-end system that does not depend on any language-specific processing.

2 algorithmes de segmentation de sous-mots

L’objectif d’un tokenizer/numerizer en sous-mots comme SentencePiece est de répondre aux questions suivantes:

  1. Comment améliorer la traduction de mots rares et non traduits en traduction neuronale en les représentant via des unités de sous-mots?
  2. Quelle segmentation en unités de sous-mots convient le mieux en termes de taille de vocabulaire, de taille du texte et de qualité de traduction?

Pour répondre à ces questions, SentencePiece dispose (au choix) de deux algorithmes de segmentation de sous-mots (par défault, c’est le modèle de langage unigramme qui est utilisé):

  1. le codage par paire d’octets (BPE ou Byte-Pair Encoding) (“Neural Machine Translation of Rare Words with Subword Units”, Sennrich et al., 2016)
  2. (défault) et le modèle de langage unigramme (“Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates”, Kudo, 2018) qui est un processus de “subword regularization”.

BPE

Il s’agit d’un algorithme (issu d’un algorithme de compression de 1994…) de combinaison de paires d’unités de caractères qui se suivent, une unité représentant au début 1 caractère.

A chaque passage sur l’ensemble du corpus, les paires sont classées par fréquence d’apparition, chaque paire devenant une unité pour le passage suivant (au premier passage une unité représente 1 caractère, au second passage une unité représente 1 caractère associé au caractère suivant (donc 2 caractères), au troisième passage une unité représente 2 caractères associés au caractère suivant (donc 3 caractères), et ainsi de suite). Au final, classés par fréquence d’apparition, la liste des sous-mots les plus fréquents dans le corpus est établie. Il s’agit du vocabulaire.

Note: pour éviter de créer des sous-mots (paire d’unités de caractères) sur 2 mots différents, les associations de caractères se font dans chaque mot du corpus d’entraînement.

Image source: Byte Pair Encoding — The Dark Horse of Modern NLP

Comme la méthodologie de BPE est systématique, le vocabulaire trouvé est unique. Or, il ne s’agit peut-être pas toujours des sous-mots qui couvrent le mieux le spectre des possibilités (et en particulier des mots rares) du corpus d’entraînement.

En savoir plus sur BPE: “Byte Pair Encoding — The Dark Horse of Modern NLP”.

Modèle de langage unigramme (MLU)

Afin de tenter de trouver le vocabulaire de sous-mots qui couvre le plus de possibilités possibles, l’idée est d’entraîner un modèle de segmentation de sous-mots basé sur un modèle de langage unigramme (un modèle probabiliste), capable de produire plusieurs segmentations de sous-mots avec des probabilités afin de choisir la liste de sous-mots avec la plus grande probabilité globale pour le corpus d’entraînement.

SentencePiece comprend quatre composants principaux: Normalizer, Trainer, Encoder et Decoder.

  • Le Normalizer est un module permettant de normaliser des caractères Unicode équivalents sur le plan sémantique en formes canoniques.
  • Le Trainer entraîne le modèle de segmentation des sous-mots sélectionné (BPE ou le modèle de langage unigramme) à partir du corpus normalisé.
  • L’Encoder exécute en interne le Normalizer pour normaliser le texte d’entrée et le transforme en une séquence de sous-mots avec le modèle de sous-mot entraîné par le Trainer.
  • Le Decoder convertit la séquence de sous-mots en texte normalisé.

Caractéristiques de SentencePiece

  • La taille du vocabulaire (nombre de tokens uniques (sous-mots)) est prédéterminée avant l’entraînement du modèle.
  • L’entraînement du modèle se fait à partir des phrases brutes du corpus (aucun pré-traitement n’est nécessaire).
  • Les espaces blancs entre les mots sont traités comme un symbole de base, ce qui permet de détokenizer sans connaissance de la langue du corpus.
  • La régularisation des sous-mots est une méthode de régularisation simple qui augmente virtuellement les données d’apprentissage avec un échantillonnage à la volée des sous-mots, ce qui contribue à améliorer la précision et la robustesse des modèles de NMT.

En savoir plus sur MLU: “A Deep Dive into the Wonderful World of Preprocessing in NLP”.

SentencePiece via fastai v1

Comme le tokenizer par défaut dans fastai v1 est SpaCy, il faut spécifier l’utilisation de SentencePiece lors de l’entraînement du modèle de langage général. Pour cela, il faut donner la taille du vocabulaire lors de la création du Databunch et utiliser la class SPProcessor.

Voici ci-dessous un exemple de code fastai avec un vocabulaire de taille 15 000:

data = (TextList.from_folder(dest, processor=[OpenFileProcessor(), SPProcessor(max_vocab_sz=15000)])
.split_by_rand_pct(0.1, seed=42)
.label_for_lm()
.databunch(bs=bs, num_workers=1))

Lors du Transfer Learning du modèle de langage général pour le spécialiser à un corpus de la même langue, il faut passer dans le Databunch du nouveau corpus le modèle et le vocabulaire créés par SentencePiece dans le corpus du modèle général.

Voici ci-dessous un exemple de code fastai:

# un répertoire tmp dans le répertoire corpus_general a été automatiquement créé lors de la première utilisation de SentencePiece (databunch du modèle de langage général) afin d'enregistrer les paramêtres du modèle et le vocabulaire détecté
dest = path/corpus_general
data_lm = (TextList.from_df(df_trn_val, path, cols=reviews, processor=SPProcessor.load(dest))
.split_by_rand_pct(0.1, seed=42)
.label_for_lm()
.databunch(bs=bs, num_workers=1))

Annexe | Présentation de SentencePiece par Jeremy Howard

SentencePiece par Jeremy Howard dans la vidéo 10 (notes) de 2018 sur le NLP de son cours Introduction to Machine Learning for Coders
SentencePiece par Jeremy Howard dans la vidéo 10 “ULMFit for non-English Languages” du cours fastai 2019 de Rachel Thomas sur NLP (A code-first introduction to NLP)

À propos de l’auteur: Pierre Guillou est consultant en Intelligence Artificielle au Brésil et en France. Merci de le contacter via son profil Linkedin.

--

--

Pierre Guillou

AI, Generative AI, Deep learning, NLP models author | Europe (Paris, Bruxelles, Liège) & Brazil