Choultion-Rudas commited on
Commit
55e806a
·
verified ·
1 Parent(s): ffe9f6b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +184 -34
app.py CHANGED
@@ -1,50 +1,200 @@
1
  import gradio as gr
2
- from funasr import AutoModel
3
  import torch
 
 
4
 
5
- model_name = "iic/SenseVoiceSmall"
 
 
 
 
 
 
 
6
 
7
- device = "cuda:0" if torch.cuda.is_available() else "cpu"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
- try:
10
- model = AutoModel(
11
- model=model_name,
12
- vad_model="fsmn-vad",
13
- vad_kwargs={"max_single_segment_time": 30000},
14
- device=device,
15
- )
16
- model_loaded_successfully = True
17
- except Exception:
18
- model = None
19
- model_loaded_successfully = False
20
 
 
 
 
21
 
22
- def transcribe_audio(audio_file_path):
23
- if not model_loaded_successfully:
24
- return "模型加载失败。很可能是免费硬件的内存不足,请按教程切换到 'iic/SenseVoiceSmall' 模型。"
25
 
26
- if audio_file_path is None:
27
- return "错误:请上传或录制音频。"
 
 
 
 
 
 
 
28
 
29
  res = model.generate(
30
- input=audio_file_path,
31
- batch_size_s=60,
32
- language="auto",
33
  use_itn=True,
 
 
34
  )
35
 
36
- return res[0]["text"]
 
37
 
 
 
 
38
 
39
- iface = gr.Interface(
40
- fn=transcribe_audio,
41
- inputs=gr.Audio(
42
- sources=["upload", "microphone"], type="filepath", label="上传音频或录音"
43
- ),
44
- outputs=gr.Textbox(label="识别结果"),
45
- title="SenseVoice 在线体验版",
46
- description="应用启动时需要下载和加载模型,请耐心等待。",
47
- allow_flagging="never",
48
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
- iface.launch()
 
1
  import gradio as gr
2
+ import numpy as np
3
  import torch
4
+ import torchaudio
5
+ from funasr import AutoModel
6
 
7
+ print("正在加载SenseVoice-Small模型,请稍候...")
8
+ model = AutoModel(
9
+ model="iic/SenseVoiceSmall",
10
+ vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch",
11
+ vad_kwargs={"max_single_segment_time": 30000},
12
+ trust_remote_code=True,
13
+ )
14
+ print("模型加载成功!")
15
 
16
+ emo_dict = {
17
+ "<|HAPPY|>": "😊",
18
+ "<|SAD|>": "😔",
19
+ "<|ANGRY|>": "😡",
20
+ "<|NEUTRAL|>": "",
21
+ "<|FEARFUL|>": "😰",
22
+ "<|DISGUSTED|>": "🤢",
23
+ "<|SURPRISED|>": "😮",
24
+ }
25
+
26
+ event_dict = {
27
+ "<|BGM|>": "🎼",
28
+ "<|Speech|>": "",
29
+ "<|Applause|>": "👏",
30
+ "<|Laughter|>": "😀",
31
+ "<|Cry|>": "😭",
32
+ "<|Sneeze|>": "🤧",
33
+ "<|Breath|>": "",
34
+ "<|Cough|>": "🤧",
35
+ }
36
+
37
+ emoji_dict = {
38
+ "<|nospeech|><|Event_UNK|>": "❓",
39
+ "<|zh|>": "",
40
+ "<|en|>": "",
41
+ "<|yue|>": "",
42
+ "<|ja|>": "",
43
+ "<|ko|>": "",
44
+ "<|nospeech|>": "",
45
+ "<|HAPPY|>": "😊",
46
+ "<|SAD|>": "😔",
47
+ "<|ANGRY|>": "😡",
48
+ "<|NEUTRAL|>": "",
49
+ "<|BGM|>": "🎼",
50
+ "<|Speech|>": "",
51
+ "<|Applause|>": "👏",
52
+ "<|Laughter|>": "😀",
53
+ "<|FEARFUL|>": "😰",
54
+ "<|DISGUSTED|>": "🤢",
55
+ "<|SURPRISED|>": "😮",
56
+ "<|Cry|>": "😭",
57
+ "<|EMO_UNKNOWN|>": "",
58
+ "<|Sneeze|>": "🤧",
59
+ "<|Breath|>": "",
60
+ "<|Cough|>": "😷",
61
+ "<|Sing|>": "",
62
+ "<|Speech_Noise|>": "",
63
+ "<|withitn|>": "",
64
+ "<|woitn|>": "",
65
+ "<|GBG|>": "",
66
+ "<|Event_UNK|>": "",
67
+ }
68
+
69
+ lang_dict = {
70
+ "<|zh|>": "<|lang|>",
71
+ "<|en|>": "<|lang|>",
72
+ "<|yue|>": "<|lang|>",
73
+ "<|ja|>": "<|lang|>",
74
+ "<|ko|>": "<|lang|>",
75
+ "<|nospeech|>": "<|lang|>",
76
+ }
77
+
78
+ emo_set = {"😊", "😔", "😡", "😰", "🤢", "😮"}
79
+ event_set = {"🎼", "👏", "😀", "😭", "🤧", "😷"}
80
+
81
+
82
+ def format_str_v2(s):
83
+ sptk_dict = {}
84
+ for sptk in emoji_dict:
85
+ sptk_dict[sptk] = s.count(sptk)
86
+ s = s.replace(sptk, "")
87
+ emo = "<|NEUTRAL|>"
88
+ for e in emo_dict:
89
+ if sptk_dict.get(e, 0) > sptk_dict.get(emo, 0):
90
+ emo = e
91
+ for e in event_dict:
92
+ if sptk_dict.get(e, 0) > 0:
93
+ s = event_dict[e] + s
94
+ s = s + emo_dict.get(emo, "")
95
+
96
+ for emoji in emo_set.union(event_set):
97
+ s = s.replace(" " + emoji, emoji)
98
+ s = s.replace(emoji + " ", emoji)
99
+ return s.strip()
100
+
101
+
102
+ def format_str_v3(s):
103
+ def get_emo(s):
104
+ return s[-1] if s and s[-1] in emo_set else None
105
+
106
+ def get_event(s):
107
+ return s[0] if s and s[0] in event_set else None
108
+
109
+ s = s.replace("<|nospeech|><|Event_UNK|>", "❓")
110
+ for lang in lang_dict:
111
+ s = s.replace(lang, "<|lang|>")
112
+ s_list = [format_str_v2(s_i).strip(" ") for s_i in s.split("<|lang|>")]
113
+ new_s = " " + (s_list[0] if s_list else "")
114
+ cur_ent_event = get_event(new_s)
115
+ for i in range(1, len(s_list)):
116
+ if not s_list[i]:
117
+ continue
118
+ if get_event(s_list[i]) == cur_ent_event and cur_ent_event is not None:
119
+ s_list[i] = s_list[i][1:]
120
+ cur_ent_event = get_event(s_list[i])
121
+ if get_emo(s_list[i]) is not None and get_emo(s_list[i]) == get_emo(new_s):
122
+ new_s = new_s[:-1]
123
+ new_s += s_list[i].strip().lstrip()
124
+ new_s = new_s.replace("The.", " ")
125
+ return new_s.strip()
126
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
+ def model_inference(audio_input, language):
129
+ if audio_input is None:
130
+ return "错误:请先上传或录制音频。"
131
 
132
+ fs, input_wav = audio_input
133
+ input_wav = input_wav.astype(np.float32) / 32768.0
 
134
 
135
+ if len(input_wav.shape) > 1:
136
+ input_wav = input_wav.mean(-1)
137
+
138
+ if fs != 16000:
139
+ print(f"音频采样率不是16k,正在重采样: {fs}")
140
+ resampler = torchaudio.transforms.Resample(orig_freq=fs, new_freq=16000)
141
+ input_wav = resampler(torch.from_numpy(input_wav)).numpy()
142
+
143
+ print(f"开始识别... 语言: {language}")
144
 
145
  res = model.generate(
146
+ input=input_wav,
147
+ cache={},
148
+ language=language,
149
  use_itn=True,
150
+ batch_size_s=60,
151
+ merge_vad=True,
152
  )
153
 
154
+ raw_text = res[0].get("text", "未能识别出文本。")
155
+ print(f"原始输出: {raw_text}")
156
 
157
+ # 使用格式化函数处理文本
158
+ formatted_text = format_str_v3(raw_text)
159
+ print(f"格式化输出: {formatted_text}")
160
 
161
+ return formatted_text
162
+
163
+
164
+ html_content = """
165
+ <div style="text-align: center;">
166
+ <h2 style="font-size: 22px;">语音理解模型: SenseVoice-Small</h2>
167
+ <p style="font-size: 16px;">
168
+ 这是一个部署在Hugging Face上的SenseVoice-Small语音识别模型。<br>
169
+ 它支持中、英、粤、日、韩等多语言识别,并能识别情感和声音事件。
170
+ </p>
171
+ <p style="font-size: 16px;">
172
+ <b>用法:</b> 上传音频或使用麦克风录音,在下方“配置”中选择识别语言,然后点击“开始”。
173
+ </p>
174
+ </div>
175
+ """
176
+
177
+ with gr.Blocks(theme=gr.themes.Soft()) as demo:
178
+ gr.HTML(html_content)
179
+
180
+ with gr.Row():
181
+ with gr.Column():
182
+ audio_inputs = gr.Audio(label="上传音频或使用麦克风录音")
183
+
184
+ with gr.Accordion("配置", open=True):
185
+ language_inputs = gr.Dropdown(
186
+ choices=["auto", "zh", "en", "yue", "ja", "ko", "nospeech"],
187
+ value="auto",
188
+ label="选择语言 (Select Language)",
189
+ )
190
+
191
+ fn_button = gr.Button("开始识别", variant="primary")
192
+
193
+ with gr.Row():
194
+ text_outputs = gr.Textbox(label="识别结果", lines=20)
195
+
196
+ fn_button.click(
197
+ fn=model_inference, inputs=[audio_inputs, language_inputs], outputs=text_outputs
198
+ )
199
 
200
+ demo.launch()