lambda-audio-v6 / app.py
KeisukeMiyamoto's picture
Join transcription segments without line breaks
3a2ffbd verified
Raw History Blame Contribute Delete
3.93 kB
import spaces
# isort: split
from collections.abc import Iterator
from itertools import batched
import gradio as gr
import torch
from silero_vad import load_silero_vad
from src.environment import load_hf_token
from src.shared.transcription import transcribe
from src.space.runtime import SpaceConfig, load_space_components, read_recording
def create_app() -> gr.Blocks:
# ---------------------------------------------------------
# Place model weights on CUDA during startup for ZeroGPU sharing.
# ---------------------------------------------------------
config = SpaceConfig()
components = load_space_components(load_hf_token())
device = torch.device("cuda")
components.model.to(device)
vad_model = load_silero_vad(onnx=True)
@spaces.GPU(duration=30)
def generate(audio: list[bytes]) -> list[str]:
results = transcribe(components.model, components.feature_extractor, components.tokenizer, config, device, audio)
return [result.text for result in results]
def transcribe_recording(audio_path: str | None) -> Iterator[str]:
segments = read_recording(audio_path, vad_model)
if not segments:
yield "音声内に発話が見つかりませんでした。"
return
texts: list[str] = []
for batch in batched(segments, 4):
texts.extend(generate(list(batch)))
yield "".join(texts).replace("\r", "").replace("\n", "")
# ---------------------------------------------------------
# Provide one audio input and one transcription action.
# ---------------------------------------------------------
with gr.Blocks(title="LambdaAudio v6", delete_cache=(3600, 3600)) as app:
gr.Markdown("# LambdaAudio v6\n日本語の音声をアップロードするか、マイクで録音してください。\n\n[モデルの詳細](https://huggingface.co/KeisukeMiyamoto/lambda-audio-v6)")
audio = gr.Audio(sources=["microphone", "upload"], type="filepath", format="wav", label="音声", editable=False, elem_id="recording-input")
button = gr.Button("文字起こし", variant="primary", elem_id="transcribe-button")
submit = gr.Button(visible="hidden", elem_id="transcribe-submit")
output = gr.Textbox(label="文字起こし結果", lines=5, interactive=False, buttons=["copy"])
submit.click(transcribe_recording, inputs=audio, outputs=output, api_name="transcribe", concurrency_limit=1)
# ---------------------------------------------------------
# Stop the browser recorder before submitting its uploaded audio.
# The stop_recording event fires after Gradio finishes uploading.
# ---------------------------------------------------------
button.click(
fn=None,
queue=False,
js="""() => {
const audio = document.getElementById('recording-input');
if (audio.dataset.submitAfterRecording) return;
const stop = [...audio.querySelectorAll('.stop-button, .stop-button-paused')]
.find(button => button.checkVisibility());
if (stop) {
audio.dataset.submitAfterRecording = 'true';
stop.click();
return;
}
document.getElementById('transcribe-submit').click();
}""",
)
audio.stop_recording(
fn=None,
queue=False,
js="""() => {
const audio = document.getElementById('recording-input');
if (!audio.dataset.submitAfterRecording) return;
delete audio.dataset.submitAfterRecording;
document.getElementById('transcribe-submit').click();
}""",
)
return app.queue(max_size=10)
if __name__ == "__main__":
create_app().launch(max_file_size="200mb")