Allgemeine Einführung
insanely-fast-whisper ist ein Audiotranskriptionstool, das das Whisper-Modell von OpenAI mit verschiedenen Optimierungstechniken (z. B. Transformers, Optimum, Flash Attention) kombiniert, um eine Befehlszeilenschnittstelle (CLI) für die schnelle und effiziente Transkription großer Audiomengen bereitzustellen. Es verwendet das Modell Whisper Large v3 und ist in der Lage, 150 Minuten Audioinhalte in weniger als 98 Sekunden zu transkribieren. Benutzer können weitere Details, Installationsanleitungen und Nutzungshilfen über das GitHub-Repository erfahren.
Multi-Sprecher-Erkennung
pyannote.audio ist ein in Python geschriebenes Open-Source-Toolkit für die Sprechertagebuchführung. Es basiert auf dem PyTorch-Framework für maschinelles Lernen und bietet hochmoderne vortrainierte Modelle und Pipelines zur weiteren Feinabstimmung Ihrer eigenen Daten für eine bessere Leistung.
faster-whisper + pyannote.audio implementiert die Sprechererkennung, indem es einfach die Ergebnisse der beiden Programme kombiniert
Offizielles Lagerhaus: https://github.com/pyannote/pyannote-audio
Funktionsliste
Audiotranskription mit dem Modell Whisper Large v3
Einführung von Transformatoren, Optimum, Flash Attention und anderen Technologien
Bietet eine CLI-Schnittstelle
Unterstützung verschiedener Optimierungstypen und Anzeige von Benchmarks
Hilfe verwenden
Installation: Installation und Konfiguration mit pip
Verwendung: Übergeben Sie Parameter und führen Sie Transkriptionsaufgaben direkt von der Befehlszeile aus
Holen Sie sich Hilfe: Besuchen Sie das GitHub-Repository für die Dokumentation und die Interaktion mit der Community.
https://github.com/SYSTRAN/faster-whisper项目编写的google colab code
# Installieren der erforderlichen Bibliothekenget_ipython().system('pip install faster-whisper')# Importieren Sie die erforderlichen Bibliothekenfrom faster_whisper import available_modelsImportfackelipywidgets als Widgets importierenfrom IPython.display import display, clear_outputimport os # Importieren von Betriebssystembibliotheken zur Handhabung von Dateioperationenimport gc # import Müllsammelbibliothek# Erkennt automatisch den Gerätetyp und wählt zwischen GPU und CPUGerät = "cuda" if torch.cuda.is_available() else "cpu"model_size = "large-v2" # Standardauswahl der Modellgrößecompute_type = "float16" if device == "cuda" else "float32" # Wechsel zu float32, wenn CPU verwendet wird# Eine Liste der verfügbaren Modelle erhaltenmodels_list = available_models()# Standard-Sprachlistesupported_languages = ['en', 'fr', 'de', 'zh', '...'] # verwendet die Standardliste der Sprachendefault_languages = 'zh' if 'zh' in supported_languages else supported_languages[0] # Wenn 'zh' in der Liste steht, wird es als Standard verwendet; andernfalls wird der erste Wert in der Liste verwendet
# Erstellen einer GUI-Schnittstellemodel_label = widgets.Label('Modell auswählen:')model_dropdown = widgets.Dropdown(options=models_list, value=model_size)language_label = widgets.Label('Sprache:')language_dropdown = widgets.Dropdown(options=supported_languages, value=default_language)beam_size_label = widgets.Label('Beam size:')beam_size_slider = widgets.IntSlider(value=5, min=1, max=10, step=1)compute_type_label = widgets.Label('Rechentyp:')wenn Gerät == "cuda".compute_type_options = ['float16', 'int8']sonst.compute_type_options = ['float32'] # Wenn CPU, sperren auf float32compute_type_dropdown = widgets.Dropdown(options=compute_type_options, value=compute_type)mode_label = widgets.Label('Formatmodus:')mode_dropdown = widgets.Dropdown(options=['normal', 'timeline', 'subtitle'], value='normal')initial_prompt_label = widgets.Label('Initial Prompt:') # Neue Bezeichnung für die anfängliche Eingabeaufforderung hinzugefügtinitial_prompt_text = widgets.Text(value='') # Ursprüngliches Eingabefeld für die Eingabeaufforderung hinzugefügtfile_name_text = widgets.Text(description='Dateiname:', value='/content/') # Eingabe des Dateinamens durch den Benutzertranscribe_button = widgets.Button(description='Transcribe')output_area = widgets.Output()
# Definieren der Übersetzungsfunktiondef transcribe_audio(b).mit output_area.clear_output()print("Beginn der Transkription...")from faster_whisper import WhisperModel # Dynamischer Import von WhisperModel: Import bei Bedarf, um RAM zu sparenversuchen.file_name = file_name_text.value # Vom Benutzer eingegebenen Dateinamen verwendeninitial_prompt = initial_prompt_text.value # Initiale Eingabeaufforderung mit Benutzereingabe# Sicherstellen, dass das Dokument vorhanden istif not os.path.exists(file_name):: if not os.path.exists(file_name).print(f "Die Datei {Dateiname} existiert nicht, bitte überprüfen Sie, ob der Dateiname und der Pfad korrekt sind.")return# Erwerb von ausgewählten Modellenausgewähltes_Modell = model_dropdown.valueselected_compute_type = compute_type_dropdown.valueselected_language = language_dropdown.value# Erstellen Sie eine neue Modellinstanz und führen Sie die Übersetzung durchmodel = WhisperModel(selected_model, device=Gerät, compute_type=selected_compute_type)versuchen.# Übersetztes AudioSegmente, info = model.transcribe(Dateiname, beam_size=beam_size_slider.value, language=selected_language, initial_prompt=initial_prompt ) Initiale Prompt-Parameter zu # hinzugefügt# Druckergebnisseprint("Erkannte Sprache '%s' mit Wahrscheinlichkeit %f" % (info.language, info.language_probability))für Segment in Segmente:wenn mode_dropdown.value == 'normal'.print("%s " % (segment.text))elif mode_dropdown.value == 'timeline'.print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))sonst: # Untertitelstart_time = "{:02d}:{:02d}:{:02d},{:03d}".format(int(segment.start // 3600), int((segment.start % 3600) // 60), int(segment.start % 60), int((segment.start % 1) * 1000))end_time = "{:02d}:{:02d}:{:02d},{:03d}".format(int(segment.end // 3600), int((segment.end % 3600) // 60), int(segment.end % 60), int((segment. Segment.Ende % 1) * 1000))print("%d\n%s --> %s\n%s\n" % (segment.id, start_time, end_time, segment.text))endlich.# Modellinstanz löschen, um RAM freizugebenDel-Modellaußer Ausnahme wie e.print("Bei der Transkription ist ein Fehler aufgetreten:")print(str(e))endlich.# Aufruf der Müllabfuhrgc.collect()print("Transkription abgeschlossen.")
#-Baugruppe GUI-Schnittstelledisplay(model_label, model_dropdown, language_label, language_dropdown, beam_size_label, beam_size_slider, compute_type_label, compute_ type_dropdown, mode_label, mode_dropdown, initial_prompt_label, initial_prompt_text, file_name_text, transcribe_button, output_area)transcribe_button.on_click(transcribe_audio)
from pyannote.core import Segment
def get_text_with_timestamp(transcribe_res).
timestamp_texts = []
for item in transcribe_res:
start = item.start
end = item.end
text = item.text.strip()
timestamp_texts.append((Segment(start, end), text))
return zeitstempel_textedef add_speaker_info_to_text(timestamp_texts, ann).
spk_text = []
for seg, text in timestamp_texts:
spk = ann.crop(seg).argmax()
spk_text.append((seg, spk, text))
return spk_textdef merge_cache(text_cache).
Satz = ''.join([Element[-1] für Element in text_cache])
spk = text_cache[0][1]
start = round(text_cache[0][0].start, 1)
end = round(text_cache[-1][0].end, 1)
return Segment(Anfang, Ende), spk, SatzPUNC_SENT_END = [',', '.' , '? , '!' , ",", "." , "?" , "!"]
def merge_sentence(spk_text).
merged_spk_text = []
pre_spk = Keine
text_cache = []
für seg, spk, text in spk_text:
wenn spk ! = pre_spk und pre_spk ist nicht None und len(text_cache) > 0:.
merged_spk_text.append(merge_cache(text_cache))
text_cache = [(seg, spk, text)]
pre_spk = spkelif text und len(text) > 0 und text[-1] in PUNC_SENT_END:
text_cache.append((seg, spk, text))
merged_spk_text.append(merge_cache(text_cache))
text_cache = []
pre_spk = spk
sonst.
text_cache.append((seg, spk, text))
pre_spk = spk
wenn len(text_cache) > 0.
merged_spk_text.append(merge_cache(text_cache))
return merged_spk_textdef diarize_text(transcribe_res, diarisation_result)::
timestamp_texts = get_text_with_timestamp(transcribe_res)
spk_text = add_speaker_info_to_text(timestamp_texts, diarisation_result)
res_processed = merge_sentence(spk_text)
return res_processeddef write_to_txt(spk_sent, file).
with open(datei, 'w') as fp.
for seg, spk, sentence in spk_sent.
line = f'{seg.start:.2f} {seg.end:.2f} {spk} {sentence}\n'
fp.write(Zeile)
Importfackel
Flüstern einführen
numpy als np importieren
von pydub import AudioSegment
von loguru importieren logger
from faster_whisper import WhisperModel
from pyannote.audio import Pipeline
from pyannote.audio import Audiofrom common.error.import ErrorCode
model_path = config["asr"]["faster-whisper-large-v3"]
# Test Audio: https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_speaker_demo.wav
audio = ". /test/asr/data/asr_speaker_demo.wav"
asr_model = WhisperModel(model_path, device="cuda", compute_type="float16")
spk_rec_pipeline = Pipeline.from_pretrained("pyannote/speaker-diarisation-3.1", use_auth_token="your huggingface Token")
spk_rec_pipeline.to(torch.device("cuda"))asr_result, info = asr_model.transcribe(audio, language="zh", beam_size=5)
diarisation_result = spk_rec_pipeline(audio)final_result = diarize_text(asr_result, diarisation_result)
for segment, spk, sent in final_result:
print("[%.2fs -> %.2fs] %s %s" % (segment.start, segment.end, sent, spk))