import os import wikipedia os.system("pip install git+https://github.com/openai/whisper.git") import gradio as gr import whisper import jiwer from share_btn import community_icon_html, loading_icon_html, share_js model = whisper.load_model("small") wikipedia.set_lang("en") def set_default_passage(): sum = wikipedia.summary("pirate code", sentences=2) return sum def update_passage(passage_name): sum = "Please specify your article theme differently" if passage_name : try: sum = wikipedia.summary(wikipedia.search(passage_name)[0], sentences=2, auto_suggest=False) # print(sum, wikipedia.search(passage_name)) passage.value = sum except: sum = "Please specify your article theme differently" return sum, "", gr.update(visible=False), gr.update(visible=False), gr.update(visible=False) def inference(audio, gt: str): audio = whisper.load_audio(audio) audio_length = audio.shape[-1]/16000 audio = whisper.pad_or_trim(audio) mel = whisper.log_mel_spectrogram(audio).to(model.device) _, probs = model.detect_language(mel) options = whisper.DecodingOptions(fp16 = False) result = whisper.decode(model, mel, options) transformation = jiwer.Compose([ jiwer.ToLowerCase(), jiwer.RemovePunctuation(), jiwer.RemoveWhiteSpace(replace_by_space=True), jiwer.RemoveMultipleSpaces(), jiwer.ReduceToListOfListOfWords(word_delimiter=" ") ]) error = jiwer.wer( gt, result.text, truth_transform=transformation, hypothesis_transform=transformation ) # error = jiwer.wer(passage, result.text) we_num = error * len(gt.split()) # print(f"WER is {we_num}") print(result.text, gt) return f"For a {audio_length} second audio, {we_num} errors were made, resulting in a final time of {audio_length + we_num}.\n The adjusted speed is thus {round(60*len(gt.split())/(audio_length + we_num))} words per minute, you can compare to Eminem's top speed of 387 words per minute !\n\n{result.text}", gr.update(visible=True), gr.update(visible=True), gr.update(visible=True) css = """ .gradio-container { font-family: 'IBM Plex Sans', sans-serif; } .gr-button { color: white; border-color: black; background: black; } input[type='range'] { accent-color: black; } .dark input[type='range'] { accent-color: #dfdfdf; } .container { max-width: 730px; margin: auto; padding-top: 1.5rem; } .details:hover { text-decoration: underline; } .gr-button { white-space: nowrap; } .gr-button:focus { border-color: rgb(147 197 253 / var(--tw-border-opacity)); outline: none; box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000); --tw-border-opacity: 1; --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color); --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px var(--tw-ring-offset-width)) var(--tw-ring-color); --tw-ring-color: rgb(191 219 254 / var(--tw-ring-opacity)); --tw-ring-opacity: .5; } .footer { margin-bottom: 45px; margin-top: 35px; text-align: center; border-bottom: 1px solid #e5e5e5; } .footer>p { font-size: .8rem; display: inline-block; padding: 0 10px; transform: translateY(10px); background: white; } .dark .footer { border-color: #303030; } .dark .footer>p { background: #0b0f19; } .prompt h4{ margin: 1.25em 0 .25em 0; font-weight: bold; font-size: 115%; } .animate-spin { animation: spin 1s linear infinite; } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } #share-btn-container { display: flex; margin-top: 1.5rem !important; padding-left: 0.5rem !important; padding-right: 0.5rem !important; background-color: #000000; justify-content: center; align-items: center; border-radius: 9999px !important; width: 13rem; } #share-btn { all: initial; color: #ffffff;font-weight: 600; cursor:pointer; font-family: 'IBM Plex Sans', sans-serif; margin-left: 0.5rem !important; padding-top: 0.25rem !important; padding-bottom: 0.25rem !important; } #share-btn * { all: unset; } """ block = gr.Blocks(css=css) with block: gr.HTML( """
The point of the game is to say the given text as fast as possible without errors. Each error adds a one second penalty to the final time and is measured by the WER metric multiplied by text length. Once you mastered the pirate code example (my PB is 15.4), challenge your friends with another article of your choice ! Warning ⚠️, the audio recording is known to bug on iPhones for the moment... The STT is powered by OpenAI Whisper, a general-purpose speech recognition model. It is trained on a large dataset of diverse audio and is also a multi-task model that can perform multilingual speech recognition as well as speech translation and language identification. This demo cuts audio after around 30 secs.