Práctica de separación de hablantes ASR chinos de NeMo (registro de hablantes)

        La separación de oradores, o registro de oradores, resuelve principalmente el problema de cuándo y qué dijo el orador. Escenarios de aplicación típicos: reuniones de varias personas, escenarios de agentes de ventas/servicio al cliente.

        

 La implementación típica se basa en canalizaciones.

Primero, los clips de sonido se segmentan según MarbleNet de VAD (detección de actividad de voz), luego las características de los altavoces se extraen según TitaNet-L, luego los altavoces se distinguen mediante agrupación y, finalmente, las etiquetas de los altavoces se separan mediante redes neuronales.

1. Instalación del entorno Nemo

Consulte la práctica de entrenamiento de ajuste fino del modelo ASR en chino e inglés de NeMo_blog-CSDN de blog-wxl781227

2. Dependencia de referencia

importar nemo.collections.asr como nemo_asr
importar numpy como np
desde IPython.display importar audio, mostrar
importar librosa
importar os
importar wget
importar matplotlib.pyplot como plt

importar nemo
importar glob

importar pprint
pp = pprint.PrettyPrinter(sangría=4)

3. Muestras aisladas localmente

ROOT = os.getcwd()
data_dir = os.path.join(ROOT,'data')
print(data_dir)
os.makedirs(data_dir, exist_ok=True)

AUDIO_FILENAME = os.path.join(data_dir,'prueba.wav')

audio_file_list = glob.glob(f"{data_dir}/test.wav")
print("Lista de archivos de audio de entrada: \n", audio_file_list)

señal, frecuencia_muestra = librosa.load(AUDIO_FILENAME, sr=16000)
print(velocidad_muestra)
visualización(Audio(señal,velocidad=velocidad_muestra))

3. Ajuste de la práctica de capacitación utilizando el modelo entrenado blog-CSDN blog-CSDN de NeMo chino/inglés ASR model_wxl781227

my_asr_model = nemo_asr.models.EncDecCTCModel.restore_from("my_stt_zh_quartznet15x5.nemo")

4. Defina la función de salida de forma de onda y la función de coloración de forma de onda.

def display_waveform(signal,text='Audio',overlay_color=[]):
    fig,ax = plt.subplots(1,1)
    fig.set_figwidth(20)
    fig.set_figheight(2)
    plt.scatter(np.arange(len (señal)),señal,s=1,marcador='o',c='k')
    si len(overlay_color):
        plt.scatter(np.arange(len(señal)),señal,s=1,marcador ='o',c=overlay_color)
    fig.suptitle(texto, tamaño de fuente=16)
    plt.xlabel('tiempo (segundos)', tamaño de fuente=18)
    plt.ylabel('intensidad de la señal', tamaño de fuente=14);
    plt.axis([0,len(señal),-0.5,+0.5])
    time_axis,_ = plt.xticks();
    plt.xticks(time_axis[:-1],time_axis[:-1]/sample_rate);
    
COLORS="bgcm y".split()
importar archivo de sonido
def get_color(signal,speech_labels,sample_rate=sample_rate):
    c=np.array(['k']*len(signal))
    para marca de tiempo en etiquetas de voz:
        inicio, fin, etiqueta = marca de tiempo.split()
        inicio, fin = int (float(start)*sample_rate),int(float(end)*sample_rate),
        corp_wav = señal[start:end]
        soundfile.write(f"/NeMo/tutorials/speaker_tasks/data/test_{start}_{end} _{label}.wav", corp_wav, sample_rate)
        print(label,my_asr_model.transcribe([f"/NeMo/tutorials/speaker_tasks/data/test_{start}_{end}_{label}.wav"]))
        if etiqueta == "voz":
            código = 'rojo'
        else:
            código = COLORES[int(label.split('_')[-1])]
        c[inicio:fin]=código
    
    volver c 

5. Genera la forma de onda antes de la separación.

display_waveform(señal)

6. Introduzca el archivo de configuración yaml original.

from omegaconf import OmegaConf
importshuthil
DOMAIN_TYPE = "meeting" # Puede ser de reunión o telefónico según el tipo de dominio del archivo de audio
CONFIG_FILE_NAME = f"diar_infer_{DOMAIN_TYPE}.yaml"

CONFIG_URL = f"https://raw.githubusercontent.com/NVIDIA/NeMo/main/examples/speaker_tasks/diarization/conf/inference/{CONFIG_FILE_NAME}"

si no os.path.exists(os.path.join(data_dir,CONFIG_FILE_NAME)):
    CONFIG = wget.download(CONFIG_URL, data_dir)
más:
    CONFIG = os.path.join(data_dir,CONFIG_FILE_NAME)

cfg = OmegaConf.load(CONFIG)
imprimir(OmegaConf.to_yaml(cfg))

7. Crear archivo principal

# Cree un archivo de manifiesto para la entrada con el siguiente formato. 
# {"audio_filepath": "/ruta/al/audio_file", "offset": 0, "duration": null, "label": "infer", "text": "-", # "num_speakers": null 
, "rttm_filepath": "/path/to/rttm/file", "uem_filepath"="/path/to/uem/filepath"} import json meta = { '
audio_filepath
'     : AUDIO_FILENAME,      'offset': 0,      'duration' :Ninguno,      'etiqueta': 'inferir',      'texto': '-',      'num_speakers': Ninguno,      'rttm_filepath': Ninguno,      'uem_filepath':











cfg.diarizer.manifest_filepath = os.path.join(data_dir,'input_manifest.json')
!cat {cfg.diarizer.manifest_filepath}

8. Configure el modelo de canalización utilizado.

pretrained_speaker_model='titanet-l.nemo'
cfg.diarizer.manifest_filepath = cfg.diarizer.manifest_filepath
cfg.diarizer.out_dir = data_dir #Directorio para almacenar archivos intermedios y resultados de predicción
cfg.diarizer.speaker_embeddings.model_path = pretrained_speaker_model
cfg.diarizer.clustering .parameters.oracle_num_speakers=Ninguno

# Usando Neural VAD y Conformer ASR 
cfg.diarizer.vad.model_path = 'vad_multilingual_marblenet'
cfg.diarizer.asr.model_path = 'my_stt_zh_quartznet15x5.nemo'
cfg.diarizer.oracle_vad = False # ----> No usando Oracle VAD 
cfg. diarizer.asr.parameters.asr_based_vad = Falso
cfg.batch_size = 2

9. Ejecute ASR para obtener la marca de tiempo.

de nemo.collections.asr.parts.utils.decoder_timestamps_utils importar ASRDecoderTimeStamps
asr_decoder_ts = ASRDecoderTimeStamps(cfg.diarizer)
asr_model = asr_decoder_ts.set_asr_model()
word_hyp, word_ts_hyp = asr_decoder_ts.run_ASR(asr_model)

print("Diccionario de salida de palabras decodificadas: \n", word_hyp['test'])
print("Diccionario de marcas de tiempo a nivel de palabras: \n", word_ts_hyp['test'])

10. Cree un objeto de separación fuera de línea de ASR

de nemo.collections.asr.parts.utils.diarization_utils importar OfflineDiarWithASR
asr_diar_offline = OfflineDiarWithASR(cfg.diarizer)
asr_diar_offline.word_ts_anchor_offset = asr_decoder_ts.word_ts_anchor_offset

11. Realizar separación fuera de línea

diar_hyp, diar_score = asr_diar_offline.run_diarization(cfg, word_ts_hyp)
print("Salida de la hipótesis de diarización: \n", diar_hyp['test'])

12. Muestra los resultados de la separación fuera de línea.

def read_file(path_to_file):
    con open(path_to_file) como f:
        contenidos = f.read().splitlines()
    devolver contenido

predicted_speaker_label_rttm_path = f"{data_dir}/pred_rttms/test.rttm"
pred_rttm = read_file(predicted_speaker_label_rttm_path)

pp.pprint(pred_rttm)

de nemo.collections.asr.parts.utils.speaker_utils importar rttm_to_labels
pred_labels = rttm_to_labels(predicted_speaker_label_rttm_path)

color = get_color(señal, pred_labels)
display_waveform(señal,'Audio con etiquetas de altavoz', color)
display(Audio(señal,velocidad=velocidad_muestra))

[ 'Prueba de ALTAVOZ2 1 0.000 4.125 <NA> <NA> altavoz_1 <NA> <NA>', 
    'Prueba de ALTAVOZ2 1 4.125 4.565 <NA> <NA> altavoz_0 <NA> <NA>']
Transcripción: 0%| | 0/1 [00:00<?, ?it/s]
altavoz_1 ['Oye, anteayer me dijiste cuál es la tasa de interés a 12 períodos']
Transcripción: 0%| | 0/1 [00:00<?, ?it/s]
altavoz_0 ['Si el número de trabajo es 908262, entonces será 0,810,000, luego se dividirá entre 120,000 y el interés será 80']

 

Supongo que te gusta

Origin blog.csdn.net/wxl781227/article/details/132292782
Recomendado
Clasificación