Insanely Fast Whisper : projet open source de transcription rapide et efficace de la parole en texte
Introduction générale
insanely-fast-whisper est un outil de transcription audio qui combine le modèle Whisper d'OpenAI avec diverses techniques d'optimisation (par exemple Transformers, Optimum, Flash Attention) pour fournir une interface de ligne de commande (CLI) conçue pour transcrire de grandes quantités d'audio rapidement et efficacement. Il utilise le modèle Whisper Large v3 et est capable de transcrire 150 minutes de contenu audio en moins de 98 secondes. Les utilisateurs peuvent obtenir plus de détails, des guides d'installation et une aide à l'utilisation via le dépôt GitHub.
reconnaissance de plusieurs locuteurs
pyannote.audio est une boîte à outils open source pour la diarisation du locuteur écrite en Python. Basé sur le cadre d'apprentissage machine PyTorch, il propose des modèles pré-entraînés de pointe et des pipelines pour affiner vos propres données afin d'obtenir de meilleures performances.
faster-whisper + pyannote.audio implémente la reconnaissance du locuteur, en fait, en combinant simplement les résultats des deux méthodes.
Entrepôt officiel : https://github.com/pyannote/pyannote-audio
Liste des fonctions
Transcription audio à l'aide du modèle Whisper Large v3
Adoption des technologies Transformer, Optimum, Flash Attention et autres
Fournit une interface CLI
Prise en charge de différents types d'optimisation et présentation de données de référence
Utiliser l'aide
Installation : Installation et configuration avec pip
Utilisation : Passer des paramètres et exécuter des tâches de transcription directement à partir de la ligne de commande
Obtenir de l'aide : visitez le dépôt GitHub pour lire la documentation et discuter avec la communauté.
https://github.com/SYSTRAN/faster-whisper项目编写的code google colab
# Installation des bibliothèques nécessairesget_ipython().system('pip install faster-whisper')# Importer les bibliothèques nécessairesfrom faster_whisper import available_modelstorche d'importationimport ipywidgets en tant que widgetsfrom IPython.display import display, clear_outputimport os # Importer les bibliothèques du système d'exploitation pour gérer les opérations sur les fichiersimport gc # import bibliothèque de collecte des déchets# Détecte automatiquement le type d'appareil et sélectionne le GPU ou le CPUdevice = "cuda" if torch.cuda.is_available() else "cpu"model_size = "large-v2" # Sélection par défaut de la taille du modèlecompute_type = "float16" if device == "cuda" else "float32" # Passage à float32 si le CPU est utilisé# Obtenir la liste des modèles disponiblesliste_des_modèles = modèles_disponibles()# Liste des langues par défautsupported_languages = ['en', 'fr', 'de', 'zh', '...'] # utilise la liste de langues par défautdefault_language = 'zh' if 'zh' in supported_languages else supported_languages[0] # Si 'zh' figure dans la liste, l'utiliser comme valeur par défaut ; sinon, utiliser la première valeur de la liste.
# Création d'une interface GUImodel_label = widgets.Label('Select model:')model_dropdown = widgets.Dropdown(options=models_list, value=model_size)language_label = widgets.Label('Language:')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('Compute type:')si device == "cuda".options de type de calcul = ['float16', 'int8']d'autre part.compute_type_options = ['float32'] # Si CPU, verrouillage sur float32compute_type_dropdown = widgets.Dropdown(options=compute_type_options, value=compute_type)mode_label = widgets.Label('Format Mode:')mode_dropdown = widgets.Dropdown(options=['normal', 'timeline', 'subtitle'], value='normal')initial_prompt_label = widgets.Label('Initial Prompt:') # Ajout d'une nouvelle étiquette pour l'invite initialeinitial_prompt_text = widgets.Text(value='') # Ajout d'une zone de saisie pour l'invite initialefile_name_text = widgets.Text(description='File name:', value='/content/') # Permettre à l'utilisateur de saisir le nom du fichiertranscribe_button = widgets.Button(description='Transcribe')output_area = widgets.Output()
# Définition de la fonction de traductiondef transcribe_audio(b).avec output_area.clear_output()print("Début de la transcription...")from faster_whisper import WhisperModel # Importation dynamique de WhisperModel : importation si nécessaire pour économiser de la RAMessayer.file_name = file_name_text.value # Utiliser le nom de fichier saisi par l'utilisateurinitial_prompt = initial_prompt_text.value # Invite initiale utilisant les données de l'utilisateur# S'assurer de l'existence du documentif not os.path.exists(nom_de_fichier): : if not os.path.exists(nom_de_fichier).print(f "Le fichier {nom_du_fichier} n'existe pas, veuillez vérifier que le nom du fichier et le chemin d'accès sont corrects")retour# Acquisition de modèles sélectionnésmodèle_sélectionné = modèle_dropdown.valeurselected_compute_type = compute_type_dropdown.valueselected_language = language_dropdown.value# Créer une nouvelle instance de modèle et effectuer la traductionmodel = WhisperModel(selected_model, device=device, compute_type=selected_compute_type)essayer.# Audio traduitsegments, info = model.transcribe(file_name, beam_size=beam_size_slider.value, language=selected_language, initial_prompt=initial_prompt ) Paramètres d'invite initiale ajoutés à ## Résultats d'impressionprint("Langue détectée '%s' avec probabilité %f" % (info.language, info.language_probability))pour segment dans segments :si mode_dropdown.value == 'normal'.print("%s " % (segment.texte))elif mode_dropdown.value == 'timeline'.print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))else : sous-titre #start_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.end % 1) * 1000))print("%d\nTP1T --> %s\nTP1T\n" % (segment.id, start_time, end_time, segment.text))enfin.# Supprimer l'instance de modèle pour libérer de la RAMmodèle delsauf Exception comme e.print("Une erreur s'est produite pendant la transcription :")print(str(e))enfin.# Appel à la collecte des ordures ménagèresgc.collect()print("Transcription terminée.")
Interface GUI de l'assemblage #display(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)
Exemple de reconnaissance d'un code à plusieurs locuteurs
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 timestamp_textsdef 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).
sentence = ''.join([item[-1] for item 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(start, end), spk, sentencePUNC_SENT_END = [',', '.' , ' ? , '!' , ",", "." , " ?" , " !"]
def merge_sentence(spk_text).
merged_spk_text = []pre_spk = None
text_cache = []for seg, spk, text in spk_text :
si spk ! = pre_spk et pre_spk n'est pas None et len(text_cache) > 0 :.
merged_spk_text.append(merge_cache(text_cache))
text_cache = [(seg, spk, text)]pre_spk = spkelif text and len(text) > 0 and 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
d'autre part.
text_cache.append((seg, spk, text))
pre_spk = spk
si 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).
avec open(file, 'w') as fp.
pour seg, spk, sentence dans spk_sent.
line = f'{seg.start :.2f} {seg.end :.2f} {spk} {sentence}\n'
fp.write(line)
torche d'importation
l'importation chuchoter
import numpy as np
from pydub import AudioSegment
from loguru import logger
from faster_whisper import WhisperModel
from pyannote.audio import Pipeline
from pyannote.audio import Audiofrom common.error.import ErrorCode
chemin_modèle = 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 jeton")
spk_rec_pipeline.to(torch.device("cuda"))asr_result, info = asr_model.transcribe(audio, language="zh", beam_size=5)
résultat de la diarisation = spk_rec_pipeline(audio)résultat final = diarize_text(asr_result, diarisation_result)
pour segment, spk, sent dans final_result :
print("[%.2fs -> %.2fs] %s %s" % (segment.start, segment.end, sent, spk))
Ressources connexes
Projet principal : https://github.com/SYSTRAN/faster-whisper
Code court : https://www.letswrite.tw/colab-faster-whisper/
Tube vidéo vers sous-titres : https://github.com/lewangdev/faster-whisper-youtube
Transcription vocale en temps réel Fast Whisper : https://www.kaggle.com/code/xiu0714/faster-whisper
Paquet d'installation en un clic
https://pan.quark.cn/s/1b74d4cec6d6
Code de décryptage 1434
© déclaration de droits d'auteur
L'article est protégé par le droit d'auteur et ne doit pas être reproduit sans autorisation.
Articles connexes
Pas de commentaires...