litagin commited on
Commit
e8d283c
·
verified ·
1 Parent(s): 9a753f9

Add app.py

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