Dans cette vidéo nous allons voir ensemble quel est le composant normalizer que l'on retrouve au
début de chaque tokenizer.
L'opération de normalisation consiste à appliquer une succession de règles de normalisation au
texte brut.
Nous choisissons des règles de normalisation pour supprimer le bruit dans le texte qui semble inutile pour l'apprentissage
et l'utilisation de notre modèle de langage.
Prenons une phrase très diversifiée avec différentes polices, caractères majuscules et minuscules, accents,
ponctuation et espaces multiples, pour voir comment plusieurs tokenizers la normalisent.
Le tokenizer du modèle FNet a transformé les lettres avec des variantes de police ou encerclées
dans leur version de base et a supprimé les espaces multiples.
Et maintenant si nous regardons la normalisation avec le tokenizer de Retribert, nous pouvons voir qu'il
conserve les caractères avec plusieurs variantes de police et conserve les multiples espaces mais il supprime
tous les accents.
Et si nous continuons à tester la normalisation de nombreux autres tokenizers associés à des modèles
que vous pouvez trouver sur le Hub, nous pouvons voir qu'ils proposent également d'autres normalisations.
Avec les tokenizers rapides, il est très facile d'observer la normalisation choisie pour le
tokenizer actuellement chargé.
En effet, chaque instance d'un fast tokenizer a un tokenizer sous-jacent de la
bibliothèque Tokenizers stocké dans l'attribut backend_tokenizer.
Cet objet possède lui-même un attribut normalizer que nous pouvons utiliser grâce à la méthode `normalize_str`
pour normaliser une chaîne.
Il est donc très pratique que cette normalisation qui a été utilisée lors de l'apprentissage
du tokenizer ait été sauvegardée et qu'elle s'applique automatiquement lorsque vous demandez à un tokenizer entraîné
de tokeniser un texte.
Par exemple, si nous n'avions pas inclus le tokenizer albert, nous aurions eu beaucoup de
tokens inconnus en tokenisant cette phrase avec des accents et des majuscules.
Ces transformations peuvent aussi être indétectables avec un simple « print ».
En effet, gardez à l'esprit que pour un ordinateur, le texte n'est qu'une succession de 0 et de 1 et il
arrive que des successions différentes de 0 et de 1 rendent le même caractère.
Les 0 et les 1 vont par groupes de 8 pour entraîner un octet.
L'ordinateur doit alors décoder cette séquence d'octets en une séquence de « points de code ».
Dans notre exemple, les 2 octets sont transformés en un seul « point de code » par UTF-8.
La norme unicode permet alors de trouver le caractère correspondant à ce « point de code » :
la cédille c.
Répétons la même opération avec cette nouvelle séquence composée de 3 octets, cette fois
elle est transformée en 2 « point de code », ce qui correspondent aussi au caractère c cédille !
Il s'agit en fait de la composition de la lettre minuscule latine C unicode et de la cédille combinatoire.
Mais c'est embêtant car ce qui nous apparaît comme un personnage unique n'est pas du tout
la même chose pour l'ordinateur.
Heureusement, il existe des normes de normalisation unicode connues sous le nom de NFC, NFD, NFKC et NFKD
qui permettent d'effacer certaines de ces différences.
Ces standards sont souvent utilisés par les tokenizers !
Sur tous ces exemples précédents, même si les normalisations changeaient l'apparence du texte,
elles ne changeaient pas le contenu : on pouvait toujours lire « Hello world, normalize this
phrase ».
Cependant, il faut être conscient que certaines normalisations peuvent être très néfastes si elles ne sont pas adaptées
à leur corpus.
Par exemple, si vous prenez la phrase française « un père indigné »
et que vous la normalisez avec le tokenizer bert-base-uncase qui supprime les accents, la
phrase devient « un père indigne ».
Si vous regardez cette vidéo pour construire votre propre tokenizer, il n'y a pas de règles absolues pour
choisir ou non une normalisation pour votre tout nouveau tokenizer mais je vous conseille de prendre le
temps de les sélectionner afin qu'ils ne vous fassent pas perdre des informations importantes.