Spaces:
Running on Zero
Running on Zero
File size: 3,258 Bytes
e8d283c 84dabd4 e8d283c bc0e8a5 e8d283c bc0e8a5 e8d283c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | """Japanese ASR demo for sbintuitions/kana-whisper on Hugging Face ZeroGPU.
The model is Whisper large-v3-turbo fine-tuned to transcribe Japanese speech
into *katakana* (pronunciation), e.g. キョーワイイテンキデスネ. It was built as
the ASR component for evaluating the reading accuracy of Japanese TTS systems.
"""
import numpy as np
import spaces
import torch
import gradio as gr
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor, pipeline
MODEL_ID = "sbintuitions/kana-whisper"
# ZeroGPU exposes CUDA at startup, so we can load straight onto the GPU. The
# @spaces.GPU decorator on transcribe() is what actually reserves the slice at
# call time; on non-ZeroGPU hardware the decorator is a no-op. We detect the
# device so the Space still builds/runs on plain CPU hardware (just slower).
if torch.cuda.is_available():
device = "cuda"
torch_dtype = torch.float16
else:
device = "cpu"
torch_dtype = torch.float32
model = AutoModelForSpeechSeq2Seq.from_pretrained(
MODEL_ID,
dtype=torch_dtype,
low_cpu_mem_usage=True,
use_safetensors=True,
).to(device)
processor = AutoProcessor.from_pretrained(MODEL_ID)
asr = pipeline(
"automatic-speech-recognition",
model=model,
tokenizer=processor.tokenizer,
feature_extractor=processor.feature_extractor,
dtype=torch_dtype,
device=device,
)
GENERATE_KWARGS = {"language": "ja", "task": "transcribe"}
def _to_float_mono(sampling_rate: int, data: np.ndarray) -> dict:
"""Normalize Gradio's (sr, ndarray) audio into what the ASR pipeline wants:
a float32 mono waveform in [-1, 1] with its sampling rate (the feature
extractor resamples to 16 kHz internally)."""
data = np.asarray(data)
if data.ndim > 1: # stereo -> mono
data = data.mean(axis=1)
if np.issubdtype(data.dtype, np.integer):
data = data.astype(np.float32) / np.iinfo(data.dtype).max
else:
data = data.astype(np.float32)
return {"array": data, "sampling_rate": int(sampling_rate)}
@spaces.GPU
def transcribe(audio: tuple | None) -> str:
if audio is None:
return ""
sampling_rate, data = audio
inputs = _to_float_mono(sampling_rate, data)
result = asr(inputs, generate_kwargs=GENERATE_KWARGS)
return result["text"]
DESCRIPTION = """
# 🎙️ Kana Whisper — Japanese ASR → Katakana
Record or upload a short Japanese audio clip and get back its **katakana**
transcription (pronunciation, not kanji) using
[`sbintuitions/kana-whisper`](https://huggingface.co/sbintuitions/kana-whisper)
— a Whisper large-v3-turbo model fine-tuned by SB Intuitions.
> Example output: `キョーワイイテンキデスネ`
"""
with gr.Blocks(title="Kana Whisper — Japanese ASR") as demo:
gr.Markdown(DESCRIPTION)
with gr.Row():
audio_in = gr.Audio(
sources=["microphone", "upload"],
type="numpy",
label="Japanese audio (short clip)",
)
text_out = gr.Textbox(
label="Katakana transcription",
lines=4,
)
transcribe_btn = gr.Button("Transcribe", variant="primary")
transcribe_btn.click(fn=transcribe, inputs=audio_in, outputs=text_out)
if __name__ == "__main__":
demo.launch()
|