Spaces:
Running
Running
1. Add two models
Browse filessherpa-onnx-streaming-zipformer-zh-int8-2025-06-30
sherpa-onnx-streaming-zipformer-zh-xlarge-int8-2025-06-30
2. Secure weight file selection behavoir especially for int8 only model
- app/asr_worker.py +59 -3
app/asr_worker.py
CHANGED
@@ -18,6 +18,30 @@ to_ZHCN = OpenCC('t2s')
|
|
18 |
|
19 |
# Streaming Zipformer model registry: paths relative to repo root
|
20 |
STREAMING_ZIPFORMER_MODELS = {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
# bilingual zh-en with char+BPE
|
22 |
"csukuangfj/k2fsa-zipformer-bilingual-zh-en-t": {
|
23 |
"tokens": "data/lang_char_bpe/tokens.txt",
|
@@ -177,6 +201,38 @@ STREAMING_ZIPFORMER_MODELS = {
|
|
177 |
def resample_audio(audio: np.ndarray, orig_sr: int, target_sr: int) -> np.ndarray:
|
178 |
return scipy.signal.resample_poly(audio, target_sr, orig_sr)
|
179 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
# Create an online recognizer for a given model and precision
|
181 |
# model_id: full HF repo ID
|
182 |
# precision: "int8" or "fp32"
|
@@ -194,9 +250,9 @@ def create_recognizer(
|
|
194 |
entry = STREAMING_ZIPFORMER_MODELS[model_id]
|
195 |
|
196 |
tokens_file = entry['tokens']
|
197 |
-
encoder_file = entry
|
198 |
-
decoder_file = entry
|
199 |
-
joiner_file
|
200 |
|
201 |
tokens_path = hf_hub_download(repo_id=model_id, filename=tokens_file, cache_dir=str(CACHE_DIR))
|
202 |
encoder_path = hf_hub_download(repo_id=model_id, filename=encoder_file, cache_dir=str(CACHE_DIR))
|
|
|
18 |
|
19 |
# Streaming Zipformer model registry: paths relative to repo root
|
20 |
STREAMING_ZIPFORMER_MODELS = {
|
21 |
+
# csukuangfj/sherpa-onnx-streaming-zipformer-zh-int8-2025-06-30
|
22 |
+
"csukuangfj/sherpa-onnx-streaming-zipformer-zh-int8-2025-06-30": {
|
23 |
+
"tokens": "tokens.txt",
|
24 |
+
"encoder_fp32": "encoder.int8.onnx",
|
25 |
+
"encoder_int8": None,
|
26 |
+
"decoder_fp32": "decoder.onnx",
|
27 |
+
"decoder_int8": None,
|
28 |
+
"joiner_fp32": "joiner.int8.onnx",
|
29 |
+
"joiner_int8": None,
|
30 |
+
"modeling_unit":"cjkchar",
|
31 |
+
"bpe_model": None,
|
32 |
+
},
|
33 |
+
# csukuangfj/sherpa-onnx-streaming-zipformer-zh-xlarge-int8-2025-06-30
|
34 |
+
"csukuangfj/sherpa-onnx-streaming-zipformer-zh-xlarge-int8-2025-06-30": {
|
35 |
+
"tokens": "tokens.txt",
|
36 |
+
"encoder_fp32": "encoder.int8.onnx",
|
37 |
+
"encoder_int8": None,
|
38 |
+
"decoder_fp32": "decoder.onnx",
|
39 |
+
"decoder_int8": None,
|
40 |
+
"joiner_fp32": "joiner.int8.onnx",
|
41 |
+
"joiner_int8": None,
|
42 |
+
"modeling_unit":"cjkchar+bpe",
|
43 |
+
"bpe_model": "bpe.model",
|
44 |
+
},
|
45 |
# bilingual zh-en with char+BPE
|
46 |
"csukuangfj/k2fsa-zipformer-bilingual-zh-en-t": {
|
47 |
"tokens": "data/lang_char_bpe/tokens.txt",
|
|
|
201 |
def resample_audio(audio: np.ndarray, orig_sr: int, target_sr: int) -> np.ndarray:
|
202 |
return scipy.signal.resample_poly(audio, target_sr, orig_sr)
|
203 |
|
204 |
+
def choose_file(entry: dict, component: str, precision: str) -> str | None:
|
205 |
+
"""
|
206 |
+
Pick the best file for the given component ('encoder', 'decoder', or 'joiner'),
|
207 |
+
but only if it really exists on disk.
|
208 |
+
|
209 |
+
1) Look up the two candidates.
|
210 |
+
2) Discard any whose path doesn’t exist.
|
211 |
+
3) If neither exists, print an error.
|
212 |
+
4) If exactly one remains, return it.
|
213 |
+
5) Otherwise, fall back to “int8 if requested & available, else fp32”.
|
214 |
+
"""
|
215 |
+
e8 = entry.get(f'{component}_int8')
|
216 |
+
e32 = entry.get(f'{component}_fp32')
|
217 |
+
|
218 |
+
# Sanity: drop any that aren’t real files
|
219 |
+
if e8 and not os.path.exists(e8):
|
220 |
+
e8 = None
|
221 |
+
if e32 and not os.path.exists(e32):
|
222 |
+
e32 = None
|
223 |
+
|
224 |
+
# If neither exists, error out
|
225 |
+
if e8 is None and e32 is None:
|
226 |
+
print(f"Error: no available files for component '{component}' (neither int8 nor fp32 found).")
|
227 |
+
return None
|
228 |
+
|
229 |
+
# If exactly one exists → pick it
|
230 |
+
if (e8 is None) != (e32 is None):
|
231 |
+
return e8 or e32
|
232 |
+
|
233 |
+
# Otherwise, fall back to “int8 if requested & available, else fp32”
|
234 |
+
return e8 if precision == 'int8' and e8 else e32
|
235 |
+
|
236 |
# Create an online recognizer for a given model and precision
|
237 |
# model_id: full HF repo ID
|
238 |
# precision: "int8" or "fp32"
|
|
|
250 |
entry = STREAMING_ZIPFORMER_MODELS[model_id]
|
251 |
|
252 |
tokens_file = entry['tokens']
|
253 |
+
encoder_file = choose_file(entry, 'encoder', precision)
|
254 |
+
decoder_file = choose_file(entry, 'decoder', precision)
|
255 |
+
joiner_file = choose_file(entry, 'joiner', precision)
|
256 |
|
257 |
tokens_path = hf_hub_download(repo_id=model_id, filename=tokens_file, cache_dir=str(CACHE_DIR))
|
258 |
encoder_path = hf_hub_download(repo_id=model_id, filename=encoder_file, cache_dir=str(CACHE_DIR))
|