Ceci est un guide complémentaire à Travailler avec wav2vec2 Partie 1 - Réglage fin de XLS-R pour la reconnaissance vocale automatique (le « guide Partie 1 »). J'ai écrit le guide de la première partie sur la façon d'affiner le modèle wav2vec2 XLS-R ("XLS-R") de Meta AI en espagnol chilien. Il est supposé que vous avez terminé ce guide et généré votre propre modèle XLS-R affiné. Ce guide expliquera les étapes pour exécuter l'inférence sur votre modèle XLS-R affiné via un Kaggle Notebook .
Pour compléter le guide, vous aurez besoin d'avoir :
spanish-asr-inference
.Ce guide utilise l' ensemble de données vocales espagnol péruvien comme source de données de test. À l'instar de l' ensemble de données sur la parole en espagnol chilien , l'ensemble de données des locuteurs péruviens se compose également de deux sous-ensembles de données : 2 918 enregistrements de locuteurs péruviens masculins et 2 529 enregistrements de locuteurs péruviens féminins.
Cet ensemble de données a été téléchargé sur Kaggle sous forme de 2 ensembles de données distincts :
Ajoutez ces deux ensembles de données à votre bloc-notes Kaggle en cliquant sur Add Input .
Vous auriez dû enregistrer votre modèle affiné à l'étape 4 du guide Travailler avec wav2vec2 Partie 1 - Réglage fin de XLS-R pour la reconnaissance vocale automatique en tant que modèle Kaggle .
Ajoutez votre modèle affiné à votre carnet Kaggle en cliquant sur Ajouter une entrée .
Les 16 sous-étapes suivantes construisent chacune des 16 cellules du cahier d'inférence dans l'ordre. Vous remarquerez que bon nombre des mêmes méthodes utilitaires du guide de la partie 1 sont utilisées ici.
La première cellule du bloc-notes d'inférence installe les dépendances. Définissez la première cellule sur :
### CELL 1: Install Packages ### !pip install --upgrade torchaudio !pip install jiwer
La deuxième cellule importe les packages Python requis. Définissez la deuxième cellule sur :
### CELL 2: Import Python packages ### import re import math import random import pandas as pd import torchaudio from datasets import load_metric from transformers import pipeline
La troisième cellule importe la métrique d’évaluation HuggingFace WER. Définissez la troisième cellule sur :
### CELL 3: Load WER metric ### wer_metric = load_metric("wer")
La quatrième cellule définit les constantes qui seront utilisées dans tout le bloc-notes. Définissez la quatrième cellule sur :
### CELL 4: Constants ### # Testing data TEST_DATA_PATH_MALE = "/kaggle/input/google-spanish-speakers-peru-male/" TEST_DATA_PATH_FEMALE = "/kaggle/input/google-spanish-speakers-peru-female/" EXT = ".wav" NUM_LOAD_FROM_EACH_SET = 3 # Special characters SPECIAL_CHARS = r"[\d\,\-\;\!\¡\?\¿\।\'\'\"\–\'\:\/\.\“\”\৷\…\‚\॥\\]" # Sampling rates ORIG_SAMPLING_RATE = 48000 TGT_SAMPLING_RATE = 16000
La cinquième cellule définit des méthodes utilitaires pour lire les fichiers d'index des ensembles de données, ainsi que pour nettoyer le texte de transcription et générer un ensemble aléatoire d'échantillons à partir des données de test. Définissez la cinquième cellule sur :
### CELL 5: Utility methods for reading index files, cleaning text, random indices generator ### def read_index_file_data(path: str, filename: str): data = [] with open(path + filename, "r", encoding = "utf8") as f: lines = f.readlines() for line in lines: file_and_text = line.split("\t") data.append([path + file_and_text[0] + EXT, file_and_text[1].replace("\n", "")]) return data def clean_text(text: str) -> str: cleaned_text = re.sub(SPECIAL_CHARS, "", text) cleaned_text = cleaned_text.lower() return cleaned_text def get_random_samples(dataset: list, num: int) -> list: used = [] samples = [] for i in range(num): a = -1 while a == -1 or a in used: a = math.floor(len(dataset) * random.random()) samples.append(dataset[a]) used.append(a) return samples
La méthode read_index_file_data
lit un fichier d'index de jeu de données line_index.tsv
et produit une liste de listes avec le nom du fichier audio et les données de transcription, par exemple :
[ ["/kaggle/input/google-spanish-speakers-chile-male/clm_08421_01719502739", "Es un viaje de negocios solamente voy por una noche"] ... ]
clean_text
est utilisée pour supprimer chaque transcription de texte des caractères spécifiés par l'expression régulière attribuée à SPECIAL_CHARS
à l'étape 2.4 . Ces caractères, y compris la ponctuation, peuvent être éliminés car ils ne fournissent aucune valeur sémantique lors de la formation du modèle pour apprendre les mappages entre les fonctionnalités audio et les transcriptions de texte.get_random_samples
renvoie un ensemble d'échantillons de test aléatoires avec la quantité définie par la constante NUM_LOAD_FROM_EACH_SET
à l'étape 2.4 . La sixième cellule définit les méthodes utilitaires utilisant torchaudio
pour charger et rééchantillonner les données audio. Définissez la sixième cellule sur :
### CELL 7: Utility methods for loading and resampling audio data ### def read_audio_data(file): speech_array, sampling_rate = torchaudio.load(file, normalize = True) return speech_array, sampling_rate def resample(waveform): transform = torchaudio.transforms.Resample(ORIG_SAMPLING_RATE, TGT_SAMPLING_RATE) waveform = transform(waveform) return waveform[0]
read_audio_data
charge un fichier audio spécifié et renvoie une matrice multidimensionnelle torch.Tensor
des données audio ainsi que la fréquence d'échantillonnage de l'audio. Tous les fichiers audio des données d'entraînement ont un taux d'échantillonnage de 48000
Hz. Ce taux d'échantillonnage "original" est capturé par la constante ORIG_SAMPLING_RATE
à l'étape 2.4 .resample
est utilisée pour sous-échantillonner les données audio d'un taux d'échantillonnage de 48000
au taux d'échantillonnage cible de 16000
. La septième cellule lit les fichiers d'index de données de test pour les enregistrements de locuteurs masculins et les enregistrements de locuteurs féminins à l'aide de la méthode read_index_file_data
définie à l' étape 2.5 . Définissez la septième cellule sur :
### CELL 7: Read test data ### test_data_male = read_index_file_data(TEST_DATA_PATH_MALE, "line_index.tsv") test_data_female = read_index_file_data(TEST_DATA_PATH_FEMALE, "line_index.tsv")
La huitième cellule génère des ensembles d'échantillons de test aléatoires à l'aide de la méthode get_random_samples
définie à l' étape 2.5 . Définissez la huitième cellule sur :
### CELL 8: Generate lists of random test samples ### random_test_samples_male = get_random_samples(test_data_male, NUM_LOAD_FROM_EACH_SET) random_test_samples_female = get_random_samples(test_data_female, NUM_LOAD_FROM_EACH_SET)
La neuvième cellule regroupe les échantillons de test masculins et les échantillons de test femelles en une seule liste. Définissez la neuvième cellule sur :
### CELL 9: Combine test data ### all_test_samples = random_test_samples_male + random_test_samples_female
La dixième cellule parcourt chaque échantillon de données de test et nettoie le texte de transcription associé à l'aide de la méthode clean_text
définie à l' étape 2.5 . Définissez la dixième cellule sur :
### CELL 10: Clean text transcriptions ### for index in range(len(all_test_samples)): all_test_samples[index][1] = clean_text(all_test_samples[index][1])
La onzième cellule charge chaque fichier audio spécifié dans la liste all_test_samples
. Définissez la onzième cellule sur :
### CELL 11: Load audio data ### all_test_data = [] for index in range(len(all_test_samples)): speech_array, sampling_rate = read_audio_data(all_test_samples[index][0]) all_test_data.append({ "raw": speech_array, "sampling_rate": sampling_rate, "target_text": all_test_samples[index][1] })
torch.Tensor
et stockées dans all_test_data
sous forme de liste de dictionnaires. Chaque dictionnaire contient les données audio d'un échantillon particulier, la fréquence d'échantillonnage et la transcription textuelle de l'audio. La douzième cellule rééchantillonne les données audio au taux d'échantillonnage cible de 16000
. Définissez la douzième cellule sur :
### CELL 12: Resample audio data and cast to NumPy arrays ### all_test_data = [{"raw": resample(sample["raw"]).numpy(), "sampling_rate": TGT_SAMPLING_RATE, "target_text": sample["target_text"]} for sample in all_test_data]
La treizième cellule initialise une instance de la classe pipeline
de la bibliothèque transformer
HuggingFace. Définissez la treizième cellule sur :
### CELL 13: Initialize instance of Automatic Speech Recognition Pipeline ### transcriber = pipeline("automatic-speech-recognition", model = "YOUR_FINETUNED_MODEL_PATH")
Le paramètre model
doit être défini sur le chemin d'accès à votre modèle affiné ajouté au Kaggle Notebook à l'étape 1.3 , par exemple :
transcriber = pipeline("automatic-speech-recognition", model = "/kaggle/input/xls-r-300m-chilean-spanish/transformers/hardy-pine/1")
La quatorzième cellule appelle le transcriber
initialisé à l'étape précédente sur les données de test pour générer des prédictions de texte. Définissez la quatorzième cellule sur :
### CELL 14: Generate transcriptions ### transcriptions = transcriber(all_test_data)
La quinzième cellule calcule les scores WER pour chaque prédiction ainsi qu'un score WER global pour toutes les prédictions. Définissez la quinzième cellule sur :
### CELL 15: Calculate WER metrics ### predictions = [transcription["text"] for transcription in transcriptions] references = [transcription["target_text"][0] for transcription in transcriptions] wers = [] for p in range(len(predictions)): wer = wer_metric.compute(predictions = [predictions[p]], references = [references[p]]) wers.append(wer) zipped = list(zip(predictions, references, wers)) df = pd.DataFrame(zipped, columns=["Prediction", "Reference", "WER"]) wer = wer_metric.compute(predictions = predictions, references = references)
La seizième et dernière cellule imprime simplement les calculs WER de l'étape précédente. Définissez la seizième cellule sur :
### CELL 16: Output WER metrics ### pd.set_option("display.max_colwidth", None) print(f"Overall WER: {wer}") print(df)
Étant donné que le notebook génère des prédictions sur des échantillons aléatoires de données de test, le résultat varie à chaque exécution du notebook. La sortie suivante a été générée lors d'une exécution du notebook avec NUM_LOAD_FROM_EACH_SET
défini sur 3
pour un total de 6 échantillons de test :
Overall WER: 0.013888888888888888 Prediction \ 0 quiero que me reserves el mejor asiento del teatro 1 el llano en llamas es un clásico de juan rulfo 2 el cuadro de los alcatraces es una de las pinturas más famosas de diego rivera 3 hay tres cafés que están abiertos hasta las once de la noche 4 quiero que me recomiendes una dieta pero donde uno pueda comer algo no puras verduras 5 cuántos albergues se abrieron después del terremoto del diecinueve de setiembre Reference \ 0 quiero que me reserves el mejor asiento del teatro 1 el llano en llamas es un clásico de juan rulfo 2 el cuadro de los alcatraces es una de las pinturas más famosas de diego rivera 3 hay tres cafés que están abiertos hasta las once de la noche 4 quiero que me recomiendes una dieta pero donde uno pueda comer algo no puras verduras 5 cuántos albergues se abrieron después del terremoto del diecinueve de septiembre WER 0 0.000000 1 0.000000 2 0.000000 3 0.000000 4 0.000000 5 0.090909
Comme on peut le constater, le modèle a fait un excellent travail ! Il n'a commis qu'une seule erreur avec le sixième échantillon (index 5
), en orthographiant mal le mot septiembre
comme setiembre
. Bien entendu, exécuter à nouveau le notebook avec différents échantillons de test et, plus important encore, avec un plus grand nombre d’échantillons de test produira des résultats différents et plus informatifs. Néanmoins, ces données limitées suggèrent que le modèle peut donner de bons résultats sur différents dialectes espagnols - c'est-à-dire qu'il a été formé sur l'espagnol chilien, mais semble donner de bons résultats sur l'espagnol péruvien.
Si vous apprenez simplement à travailler avec les modèles wav2vec2, j'espère que le guide Travailler avec wav2vec2 Partie 1 - Réglage fin de XLS-R pour la reconnaissance vocale automatique et ce guide vous ont été utiles. Comme mentionné, le modèle affiné généré par le guide de la première partie n'est pas tout à fait à la pointe de la technologie, mais devrait néanmoins s'avérer utile pour de nombreuses applications. Bonne construction !