Эффективная диаризация динамиков

Я запускаю экземпляр виртуальной машины в облаке Google. Моя цель — применить диаризацию говорящего к нескольким файлам .wav, хранящимся в облачных корзинах.

Я пробовал следующие альтернативы с последующими проблемами:

  1. Диариза динамиков в Google API. Кажется, что это происходит быстро, но результаты не имеют никакого смысла. Я уже видел подобные проблемы , и я сам открыл тему, но не получил ответа... Результат этого возвращает максимум два динамика со случайными метками. Вот код, который я пробовал на питоне:
      from google.cloud import speech_v1p1beta1 as speech
from google.cloud import storage
import os
import json
import sys

storage_client = storage.Client()
client = speech.SpeechClient()


if "--channel" in sys.argv:
    index = sys.argv.index("--channel") + 1
    if index < len(sys.argv):
        channel = sys.argv[index]
        print("Channel:", channel)
    else:
        print("--channel option requires a value")


audio_folder=f'audio_{channel}'
# channel='tve'
transcript_folder=f'transcript_output'

bucket = storage_client.bucket(audio_folder)
bucket2 = storage_client.bucket(transcript_folder)
wav_files=[i.name for i in bucket.list_blobs()]
json_files=[i.name.split(f'{channel}/')[-1] for i in bucket2.list_blobs(prefix=channel)]



for file in wav_files:
    if not file.endswith('.wav'):
        continue
    transcript_name=file.replace('.wav','.json')
    if transcript_name in json_files:
        continue
    gcs_uri = f"gs://{audio_folder}/{file}"
    # gcs_uri = f"gs://{audio_folder}/out2.wav"
    audio = speech.RecognitionAudio(uri=gcs_uri)

    diarization_config = speech.SpeakerDiarizationConfig(
        enable_speaker_diarization=True,
        min_speaker_count=2,
        #max_speaker_count=10,
    )
    config = speech.RecognitionConfig(
            encoding=speech.RecognitionConfig.AudioEncoding.LINEAR16,
            #sample_rate_hertz=8000,
            language_code="es-ES",
            diarization_config=diarization_config,
            #audio_channel_count = 2,
        )

    print("Waiting for operation to complete...")
    operation = client.long_running_recognize(config=config, audio=audio)
    response=operation.result()
    result = response.results[-1]
    # print(result)
    # print(type(result))
    with open(transcript_name,'w') as f:
        json.dump(str(result),f)
    # transcript_name=file.replace('.wav','.txt')
    # result = response.results[-1]
    # with open(transcript_name,'w') as f:
    #     f.write(result)
    os.system(f'gsutil cp  {transcript_name} gs://transcript_output/{channel}')
    os.remove(transcript_name)
    print(f'File {file} processed. ')
    

Независимо от того, как max_speaker или min изменены, результаты одинаковы.

  1. примечание:

Так как вышеописанное не сработало, решил попробовать с pyannote. Производительность у него очень хорошая, но есть одна проблема, он очень медленный. Для wav-файла длительностью 30 минут требуется более 3 часов для завершения диаризации.

Вот мой код:

      
#import packages
import os
from datetime import datetime
import pandas as pd
from pyannote.audio import Pipeline
from pyannote.audio import Model
from pyannote.core.json import dump
from pyannote.core.json import load
from pyannote.core.json import loads
from pyannote.core.json import load_from
import subprocess
from pyannote.database.util import load_rttm
from google.cloud import speech_v1p1beta1 as speech
from google.cloud import storage
import sys

# channel='a3'
storage_client = storage.Client()
if "--channel" in sys.argv:
    index = sys.argv.index("--channel") + 1
    if index < len(sys.argv):
        channel = sys.argv[index]
        print("Channel:", channel)
    else:
        print("--channel option requires a value")

audio_folder=f'audio_{channel}'
transcript_folder=f'transcript_{channel}'
bucket = storage_client.bucket(audio_folder)
bucket2 = storage_client.bucket(transcript_folder)
wav_files=[i.name for i in bucket.list_blobs()]
rttm_files=[i.name for i in bucket2.list_blobs()]



token="XXX"
pipeline = Pipeline.from_pretrained("pyannote/speaker-diarization@2.1",
                                    use_auth_token=token)


# this load the model
model = Model.from_pretrained("pyannote/segmentation",
                                    use_auth_token=token)
                                    

for file in wav_files:
    if not file.endswith('.wav'):
        continue
    rttm_name=file.replace('.wav','.rttm')
    if rttm_name in rttm_files:
        continue
    if '2023' not in file:
        continue
    
    print(f'Doing file {file}')
    gcs_uri = f"gs://{audio_folder}/{file}"     
    os.system(f'gsutil cp {gcs_uri} {file}')   
    diarization = pipeline(file)                             
    with open(rttm_name, "w") as rttm:
        diarization.write_rttm(rttm)        
    os.system(f'gsutil cp {rttm_name} gs://transcript_{channel}/{rttm_name}')
    os.remove(file)
    os.remove(rttm_name)
    


Я запускаю это с python3.9 на экземпляре виртуальной машины с графическим процессором NVIDIA-T4.

Это нормально? Я видел, что pyannote.audio немного медленнее в 1 раз или около того, на этот раз это намного больше, учитывая, что теоретически он должен работать на выделенном графическом процессоре для этого...

Есть ли более быстрые альтернативы? Есть ли способ улучшить код или разработать виртуальную машину, которая может увеличить скорость?

1 ответ

Чтобы это быстро работало на графическом процессоре (в качестве примера используется Google Colab): вам необходимо сначала установить pyannote:

      !pip install -qq https://github.com/pyannote/pyannote-audio/archive/refs/heads/develop.zip

А потом:

      from pyannote.audio import Pipeline
import torch

pipeline = Pipeline.from_pretrained(
        "pyannote/speaker-diarization@2.1",
        use_auth_token='your hugging face token here')

pipeline.to(torch.device('cuda')) # switch to gpu
diarization = pipeline(audio_file_path)
Другие вопросы по тегам