Ingénieur Machine Learning chez Zaion sur le thème de la reconnaissance de la parole (ASR) et le traitement automatique du langage naturel (NLP).
TL;DR
Selon l’entreprise OpenAI, la robustesse et la précision de la reconnaissance vocale en anglais n’a jamais été aussi proche de l’humain que grâce à son nouveau modèle Whisper. À travers cet article de blog, nous allons expliquer notre approche de fine-tuning du modèle Whisper pour atteindre ce niveau de performance sur d’autres langues. C’est ce travail qui nous a permis de remporter le premier prix du Whisper Fine-Tuning Event organisé par HuggingFace 🤗 et Lambda Labs, sur la langue française ainsi que la langue allemande. Les modèles et les démos issus de cet événement sont disponibles sur le Hugging Face Hub.
BY GEORGE MARKS/RETROFILE/GETTY IMAGES.
Préface
Je suis ingénieur en Machine Learning chez Zaion, le leader sur le marché européen des solutions d’IA pour relation client. Un des objectifs de Zaion est de fournir une transcription exacte et précise des conversations du service client. Il est donc crucial pour nous de disposer d’un système de reconnaissance vocale fiable, robuste et prêt à l’usage dans des conditions réelles.
Au Zaion Lab, l’équipe Recherche de l’entreprise Zaion, nous sommes constamment à l’affût des dernières tendances et des nouveautés dans le domaine de la reconnaissance vocale. J’ai ainsi eu l’occasion de participer à l’événement Whisper Fine-Tuning Event organisé par Hugging Face 🤗 et Lambda Labs, qui vise à démocratiser l’utilisation du modèle Whisper et le rendre robuste pour un maximum de langues. J’ai pris part au challenge de la langue française et de la langue allemande, et j’ai remporté le premier prix pour les deux (leaderboard).
Introduction
En septembre 2022, OpenAI a publié un modèle de reconnaissance automatique de la parole (ASR) pré-entraîné appelé Whisper. Les modèles d’apprentissage autosupervisés, tels que wav2vec 2.0, sont généralement pré-entraînés sur des tâches de prédiction masquée à l’aide de données audio non étiquetées, puis fine-tunés sur des données étiquetées pour diverses tâches en aval, notamment la reconnaissance automatique de la parole. En revanche, les modèles Whisper sont entraînés directement sur une grande quantité de données faiblement étiquetées et collectées sur le web.
Ce corpus est constitué de 680 000 heures de données multilingues et multitâches qui comprennent la transcription en plusieurs langues, la traduction de ces langues vers l’anglais, ainsi que la prédiction de l’horodatage. À cette échelle, le modèle démontre une grande robustesse aux accents, au bruit de fond et au langage technique.
Whisper est un modèle de séquence à séquence, un encodeur-décodeur basé sur un Transformer – qui fait correspondre la représentation en spectrogramme d’un enregistrement à la séquence d’unités sous-lexicales correspondante. Cette représentation acoustique est calculée par une transformation mathématique à partir des formes d’onde du signal brut , puis analysée par l’encodeur du Transformer. Ensuite, le décodeur prédit de manière auto-régressive la sortie (ou unité sous-lexicale) suivante en fonction des sorties précédentes et des états cachés de l’encodeur. La figure ci-dessous résume l’architecture du modèle.
L’architecture du modèle Whisper. Source: OpenAI Whisper Blog
Dans ce blog, nous allons montrer comment fine-tuner la version du modèle Whisper medium sur la langue française. Cette version du modèle comporte 24 couches d’encodeur et de décodeur et 769 millions de paramètres. Le code complet peut être trouvé ici.
Préparation des données et du modèle
Chargement du modèle
Commençons par charger la version medium du modèle pré-entraîné Whisper :
Vous trouverez certains arguments définis dans le modèle Whisper tels que « forced_decoder_ids » et « suppress_tokens ». Ces arguments sont définis dans GenerationConfig pour la tâche de génération.Cependant, ces arguments ne sont pas utilisés pendant l’apprentissage afin de laisser le modèle les apprendre par lui-même.
Nous désactivons également la fonction use_cache dans le décodeur Whisper. Elle nous permet de réutiliser la clé et les valeurs calculées des blocs d’auto-attention et d’attention croisée pour accélérer l’étape de décodage en cours. Cependant, elle est incompatible avec le checkpointing du gradient qui sera appliqué dans une étape ultérieure pour réduire l’empreinte mémoire.
Chargement des jeux de données
Nous allons utiliser la bibliothèque 🤗 Datasets pour télécharger et préparer les jeux de données. Nous mélangeons les données d’entraînement de Common Voice 11.0 et de Multilingual LibriSpeech pour former un ensemble d’entraînement plus important, et nous n’utilisons que les données de test de Common Voice 11.0 pour l’évaluation.
Il est toujours recommandé de collecter autant de données d’entraînement que possible. Il existe d’autres jeux de données de reconnaissance vocale disponibles sur le Hugging Face Hub, tels que Voxpopuli et Fleurs. Si vous voulez charger votre corpus local, jetez un coup d’oeil à cette page.
Le taux d’échantillonnage du signal audio est de 48kHz dans Common Voice et de 16kHz dans Multilingual LibriSpeech. Nous nous assurons que les échantillons audio sont rééchantillonnés à 16kHz, non seulement pour unifier le taux d’échantillonnage de différents ensembles de données, mais aussi parce que c’est le taux d’échantillonnage de 680 000 heures de corpus de pré-entraînement des modèles Whisper. Le rééchantillonnage peut être facilement réalisé à la volée en utilisant la méthode « cast_column » et l’objet « Audio » de Datasets.
Afin de mélanger différents jeux de données, il est également nécessaire de s’assurer que tous les jeux de données ont les mêmes champs de données. Ici, nous ne conservons que la colonne audio et la phrase de deux jeux de données.
Si vous avez des contraintes liées à l’espace disque, vous pouvez charger les ensembles de données à la volée avec le mode streaming.
Augmentation des données
Nous avons remarqué que les échantillons audio du jeu de données LibriSpeech Multilingue sont assez intelligibles. Afin que le modèle soit robuste dans des environnements bruyants et qu’il puisse être généralisé à différents locuteurs, nous augmentons les données à l’aide de la bibliothèque Audiomentations. Plusieurs augmentations sont appliquées aux échantillons audio, notamment TimeStretch, Gain, PitchShift, et l’une des options AddBackgroundNoise ou AddGaussianNoise.
Cette méthode d’augmentation est réalisée de la manière suivante :
Ensuite, nous appliquons l’augmentation à tous les exemples d’apprentissage en utilisant la méthode « map » :
Note : L’augmentation des données n’est effectuée que sur l’ensemble d’apprentissage. Nous conservons également une version originale de l’ensemble d’entraînement, puis nous la composons avec l’ensemble d’entraînement augmenté.
Normalisation du texte
« Si la diversité de la qualité audio peut aider un modèle à être robuste, la diversité de la qualité de la transcription n’est pas aussi bénéfique. »
La diversité ici se reflète sur le format de transcription, c’est-à-dire que la casse et la ponctuation existent dans le jeu de données Common Voice, mais pas dans le jeu de données Multilingual LibriSpeech. Nous devons nous assurer que les transcriptions sont en minuscules et supprimer toute ponctuation lorsque nous les utilisons ensemble. Cela simplifiera la tâche – puisque le modèle n’a plus besoin de distinguer les caractères majuscules et minuscules, ni de prédire les signes de ponctuation entre les caractères.
Toutefois, si vous souhaitez disposer de transcriptions faciles à lire ou nécessitant une casse ou une ponctuation, il est préférable de les conserver et de n’utiliser que des jeux de données avec casse et ponctuation tels que Common Voice et Fleurs.
Note : Le modèle est toujours évalué sur les transcriptions normalisées, c’est-à-dire sans majuscules et non ponctuées.
Vous pouvez trouver la normalisation utilisée pour l’anglais et les autres langues dans l’annexe C de l’article Whisper.
Prétraitement des données
Vous pouvez trouver la normalisation utilisée pour l’anglais et les autres langues dans l’annexe C de l’article Whisper.
Comme nous l’avons montré dans l’introduction, le modèle Whisper prend le spectrogramme log-Mel en entrée et produit des tokens BPE. Nous devons donc préparer nos données dans le format adéquat. Cela peut être réalisé par deux classes utilitaires ; WhisperFeatureExtractor et WhisperTokenizer, utilisées respectivement sur les entrées audio et les transcriptions ou prédictions du modèle. La bibliothèque de transformateurs regroupe ces deux classes en une seule classe WhisperProcessor, qui peut être chargée comme indiquée ci-dessous :
Il nous suffit de spécifier la langue cible et la tâche pour que « WhisperTokenizer » préfixe les tokens de langue et de tâche correspondants lors de l’encodage des transcriptions en IDs d’étiquettes.
Voyons ce qui se trouve dans notre fonction de préparation des données :
Ensuite, nous appliquons la fonction de préparation des données à tous les exemples de l’ensemble de données en utilisant la méthode « map » :
Suppression de l’audio long
Dans l’étape précédente, les exemples dont l’audio dépasse 30s ont été tronqués par le « WhisperFeatureExtractor ». Si l’audio est tronqué, la transcription ne l’est pas, ce qui déstabilise gravement l’apprentissage. Ici, nous définissons une fonction pour filtrer tout audio de plus de 30s :
Nous appliquons ensuite notre fonction de filtrage à tous les exemples en utilisant la méthode « filter » :
Suppression des textes longs
Le décodeur Whisper utilise une représentation de position appris dont la longueur maximale est de 448 tokens. Il ne peut donc pas décoder une transcription de plus de 448 identifiants d’étiquettes. Nous définissons ici une fonction de filtrage sur les identifiants d’étiquettes :
Puis on l’applique à tous les exemples par la méthode « filter » :
Apprentissage et évaluation
Collateur de données
Le collateur de données prend une liste d’échantillons prétraités et les rassemble en un lot de tenseurs Pytorch. Nous devons nous assurer que toutes les features audio du lot ont la même longueur, et cette règle s’applique également à toutes les étiquettes du lot.
Les features audio sont déjà paddées ou tronquées à une dimension fixe par le « WhisperFeatureExtractor », donc nous avons seulement besoin de les convertir en tenseurs Pytorch en utilisant la méthode « pad ». D’autre part, les identifiants des étiquettes ne sont pas paddés. Nous devons d’abord les paginer à la longueur maximale du lot en utilisant la méthode « pad », puis remplacer les tokens de pagination par « -100 » afin que ces tokens ne soient pas pris en compte dans le calcul de la perte.
Définissons notre collateur de données comme suit :
Ensuite, nous pouvons initialiser le collateur de données que nous venons de définir :
Mesures d’évaluation
Nous utilisons la métrique du taux d’erreur de mots (WER)pour évaluer les performances du modèle. La métrique WER peut être simplement chargée par 🤗 Evaluate :
Nous devons ensuite définir une fonction qui prend les identifiants réels des étiquettes et les prédictions du modèle, puis renvoie la métrique WER. Dans cette fonction, nous devons remplacer « -100 » par le « pad_token_id » (en annulant l’étape dans le collateur de données pour ignorer les tokens paddés) afin que les ids d’étiquettes puissent être correctement dé-tokénisés en chaînes de caractères.
Configuration de l’apprentissage
Dans cette étape, nous définissons tous les paramètres liés à l’apprentissage. Pour plus de détails sur les autres arguments d’apprentissage, reportez-vous à la documentation « Seq2SeqTrainingArguments« .
L’apprentissage
Dans la dernière étape, nous allons initialiser le trainer en passant en tant qu’arguments, le modèle, l’ensemble de données, le collateur de données, les arguments d’apprentissage et la fonction de calcul des métriques.
Lançons l’apprentissage !
N’oubliez pas de sauvegarder votre modèle et votre processeur une fois l’apprentissage terminé :
Récapitulons !
Dans ce blog, nous avons présenté un guide étape par étape sur le fine-tuning de Whisper pour ASR sur des données françaises. Le WER de la version Whisper medium a été réduit de 16.00% à 9.03% sur Common Voice. Avec la version Whisper large , il est passé de 13.90% à 8.15%.
Vous pouvez trouver ici une démo pour l’ASR français utilisant des modèles de Whisper fine-tunés.
Vous pouvez également fine-tuner Whisper dans d’autres langues : il suffit de collecter et de nettoyer des jeux de données dans cette langue, puis de spécifier le code de langue correspondant lors du chargement de « WhisperProcessor ».
Références
- Robust Speech Recognition via Large-Scale Weak Supervision
- Fine-Tune Whisper For Multilingual ASR with 🤗 Transformers
- Whisper Fine-Tuning Event
Enfin, je tiens à remercier mes collègues du Zaion Lab, pour leur aide précieuse et leurs commentaires constructifs : Mohamed Bouaziz, Tiphaine Fievet, Imed Laaridh, Lorraine Vanel, Yingzhi Wang et Alya Yacoubi !