Esta es una guía complementaria para Trabajar con wav2vec2 Parte 1: Ajuste de XLS-R para el reconocimiento automático de voz (la "guía de la Parte 1"). Escribí la guía de la Parte 1 sobre cómo ajustar el modelo wav2vec2 XLS-R ("XLS-R") de Meta AI en español de Chile. Se supone que ha completado esa guía y ha generado su propio modelo XLS-R ajustado. Esta guía explicará los pasos para ejecutar la inferencia en su modelo XLS-R ajustado a través de una computadora portátil Kaggle .
Para completar la guía, necesitarás tener:
spanish-asr-inference
.Esta guía utiliza el conjunto de datos del habla del español peruano como fuente de datos de prueba. Al igual que el conjunto de datos de habla del español de Chile , el conjunto de datos de hablantes peruanos también consta de dos subconjuntos de datos: 2918 grabaciones de hablantes peruanos varones y 2529 grabaciones de hablantes peruanos mujeres.
Este conjunto de datos se cargó en Kaggle como 2 conjuntos de datos distintos:
Agregue ambos conjuntos de datos a su Kaggle Notebook haciendo clic en Agregar entrada .
Debería haber guardado su modelo ajustado en el Paso 4 de la guía Trabajar con wav2vec2 Parte 1: Ajuste fino de XLS-R para el reconocimiento automático de voz como modelo Kaggle .
Agregue su modelo ajustado a su Kaggle Notebook haciendo clic en Agregar entrada .
Los siguientes 16 subpasos construyen en orden cada una de las 16 celdas del cuaderno de inferencia. Notará que aquí se utilizan muchos de los mismos métodos de utilidad de la guía de la Parte 1.
La primera celda del cuaderno de inferencia instala dependencias. Establezca la primera celda en:
### CELL 1: Install Packages ### !pip install --upgrade torchaudio !pip install jiwer
La segunda celda importa los paquetes Python requeridos. Establezca la segunda celda en:
### 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 tercera celda importa la métrica de evaluación WER de HuggingFace. Establezca la tercera celda en:
### CELL 3: Load WER metric ### wer_metric = load_metric("wer")
La cuarta celda establece constantes que se utilizarán en todo el cuaderno. Establezca la cuarta celda en:
### 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 quinta celda define métodos de utilidad para leer los archivos de índice del conjunto de datos, así como para limpiar el texto de transcripción y generar un conjunto aleatorio de muestras a partir de datos de prueba. Establezca la quinta celda en:
### 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
El método read_index_file_data
lee un archivo de índice del conjunto de datos line_index.tsv
y produce una lista de listas con nombres de archivos de audio y datos de transcripción, por ejemplo:
[ ["/kaggle/input/google-spanish-speakers-chile-male/clm_08421_01719502739", "Es un viaje de negocios solamente voy por una noche"] ... ]
clean_text
se utiliza para eliminar de cada transcripción de texto los caracteres especificados por la expresión regular asignada a SPECIAL_CHARS
en el Paso 2.4 . Estos caracteres, incluida la puntuación, se pueden eliminar ya que no proporcionan ningún valor semántico al entrenar el modelo para aprender asignaciones entre funciones de audio y transcripciones de texto.get_random_samples
devuelve un conjunto de muestras de prueba aleatorias con la cantidad establecida por la constante NUM_LOAD_FROM_EACH_SET
en el Paso 2.4 . La sexta celda define métodos de utilidad que utilizan torchaudio
para cargar y volver a muestrear datos de audio. Establezca la sexta celda en:
### 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
carga un archivo de audio específico y devuelve una matriz multidimensional torch.Tensor
de los datos de audio junto con la frecuencia de muestreo del audio. Todos los archivos de audio de los datos de entrenamiento tienen una frecuencia de muestreo de 48000
Hz. Esta frecuencia de muestreo "original" es capturada por la constante ORIG_SAMPLING_RATE
en el Paso 2.4 .resample
se utiliza para reducir la resolución de datos de audio desde una frecuencia de muestreo de 48000
a la frecuencia de muestreo objetivo de 16000
. La séptima celda lee los archivos de índice de datos de prueba para las grabaciones de hablantes masculinos y las grabaciones de hablantes femeninas utilizando el método read_index_file_data
definido en el Paso 2.5 . Establezca la séptima celda en:
### 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 octava celda genera conjuntos de muestras de prueba aleatorias utilizando el método get_random_samples
definido en el Paso 2.5 . Establezca la octava celda en:
### 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 novena celda combina las muestras de prueba masculinas y las muestras de prueba femeninas en una sola lista. Establezca la novena celda en:
### CELL 9: Combine test data ### all_test_samples = random_test_samples_male + random_test_samples_female
La décima celda itera sobre cada muestra de datos de prueba y limpia el texto de transcripción asociado utilizando el método clean_text
definido en el Paso 2.5 . Establezca la décima celda en:
### 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 undécima celda carga cada archivo de audio especificado en la lista all_test_samples
. Establezca la undécima celda en:
### 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
y se almacenan en all_test_data
como una lista de diccionarios. Cada diccionario contiene los datos de audio para una muestra particular, la frecuencia de muestreo y la transcripción de texto del audio. La duodécima celda vuelve a muestrear los datos de audio a la frecuencia de muestreo objetivo de 16000
. Establezca la duodécima celda en:
### 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 decimotercera celda inicializa una instancia de la clase pipeline
de la biblioteca transformer
HuggingFace. Establezca la decimotercera celda en:
### CELL 13: Initialize instance of Automatic Speech Recognition Pipeline ### transcriber = pipeline("automatic-speech-recognition", model = "YOUR_FINETUNED_MODEL_PATH")
El parámetro model
debe establecerse en la ruta a su modelo ajustado agregado al Kaggle Notebook en el Paso 1.3 , por ejemplo:
transcriber = pipeline("automatic-speech-recognition", model = "/kaggle/input/xls-r-300m-chilean-spanish/transformers/hardy-pine/1")
La decimocuarta celda llama al transcriber
inicializado en el paso anterior con los datos de prueba para generar predicciones de texto. Establezca la decimocuarta celda en:
### CELL 14: Generate transcriptions ### transcriptions = transcriber(all_test_data)
La decimoquinta celda calcula las puntuaciones WER para cada predicción, así como una puntuación WER general para todas las predicciones. Establezca la decimoquinta celda en:
### 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 decimosexta y última celda simplemente imprime los cálculos de WER del paso anterior. Establezca la decimosexta celda en:
### CELL 16: Output WER metrics ### pd.set_option("display.max_colwidth", None) print(f"Overall WER: {wer}") print(df)
Dado que el cuaderno genera predicciones sobre muestras aleatorias de datos de prueba, el resultado variará cada vez que se ejecute el cuaderno. El siguiente resultado se generó en una ejecución del portátil con NUM_LOAD_FROM_EACH_SET
establecido en 3
para un total de 6 muestras de prueba:
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
Como puede verse, ¡el modelo hizo un excelente trabajo! Sólo cometió un error con la sexta muestra (índice 5
), al escribir mal la palabra septiembre
como setiembre
. Por supuesto, volver a ejecutar el portátil con diferentes muestras de prueba y, lo que es más importante, con una mayor cantidad de muestras de prueba, producirá resultados diferentes y más informativos. No obstante, estos datos limitados sugieren que el modelo puede funcionar bien en diferentes dialectos del español; es decir, fue entrenado en español chileno, pero parece funcionar bien en español peruano.
Si recién está aprendiendo a trabajar con modelos wav2vec2, espero que la guía Trabajar con wav2vec2 Parte 1 - Ajuste de XLS-R para el reconocimiento automático de voz y esta guía le hayan resultado útiles. Como se mencionó, el modelo ajustado generado por la guía de la Parte 1 no es del todo avanzado, pero aún así debería resultar útil para muchas aplicaciones. ¡Feliz edificio!