Notre retour d’expérience sur le Whisper Fine-Tuning Event

27/02/2024

Bofeng Huang

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).

 

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).

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 :

Preparation des données

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

 

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.

Mélange 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 :

Augmentation des données

Ensuite, nous appliquons l’augmentation à tous les exemples d’apprentissage en utilisant la méthode « map » :

apprentissage

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.

Jeux de données

 

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 :

bibliothèque de données

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 :

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 » :

Méthodes des cartes

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 :

Suppression audio long

Nous appliquons ensuite notre fonction de filtrage à tous les exemples en utilisant la méthode « filter » :

Méthode du filtre

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 :

Suppression des textes longs

Puis on l’applique à tous les exemples par la méthode « filter » :

Méthode filtrage

 

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 :

Collateur de données

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 :

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.

Dé-tokénisés

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« .

Définition des paramètres

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.

Calcul des métriques

Lançons l’apprentissage !

Lançons l’apprentissage !

N’oubliez pas de sauvegarder votre modèle et votre processeur une fois l’apprentissage terminé :

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

  1. Robust Speech Recognition via Large-Scale Weak Supervision 
  2. Fine-Tune Whisper For Multilingual ASR with 🤗 Transformers 
  3. Whisper Fine-Tuning Event 

Enfin, je tiens à remercier mes collègues du Zaion Lab, pour leur aide précieuse et leurs commentaires constructifs : Mohamed BouazizTiphaine Fievet, Imed Laaridh, Lorraine Vanel, Yingzhi Wang et Alya Yacoubi !

Actualités Zaion

Restez au courant des dernières actualités, tendances et analyses
dans le domaine de la Relation Client augmentée par l'IA Conversationnelle, Générative et Vocale.

Découvrez les solutions Zaion

* sont obligatoires