chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Run all model tests and report results"""
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
|
||||
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
PROJECT_DIR = os.path.dirname(TEST_DIR)
|
||||
|
||||
tests = [
|
||||
"test_fsmn_vad.py",
|
||||
"test_ct_transformer.py",
|
||||
"test_paraformer.py",
|
||||
"test_sensevoice.py",
|
||||
"test_campplus.py",
|
||||
"test_paraformer_streaming.py",
|
||||
"test_qwen3_asr.py",
|
||||
"test_glm_asr.py",
|
||||
"test_eres2netv2.py",
|
||||
]
|
||||
|
||||
SEP = "-" * 60
|
||||
DSEP = "=" * 60
|
||||
|
||||
def main():
|
||||
results = {}
|
||||
total_start = time.time()
|
||||
|
||||
env = os.environ.copy()
|
||||
env["PYTHONPATH"] = PROJECT_DIR + ":" + env.get("PYTHONPATH", "")
|
||||
|
||||
print(DSEP)
|
||||
print("FunASR Model Tests")
|
||||
print(DSEP)
|
||||
|
||||
for test_file in tests:
|
||||
test_path = os.path.join(TEST_DIR, test_file)
|
||||
print("\n" + SEP)
|
||||
print("Running: " + test_file)
|
||||
print(SEP)
|
||||
|
||||
t0 = time.time()
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[sys.executable, test_path],
|
||||
cwd=PROJECT_DIR,
|
||||
env=env,
|
||||
timeout=300,
|
||||
capture_output=False,
|
||||
)
|
||||
elapsed = time.time() - t0
|
||||
results[test_file] = ("PASSED" if result.returncode == 0 else "FAILED", elapsed)
|
||||
except subprocess.TimeoutExpired:
|
||||
elapsed = time.time() - t0
|
||||
results[test_file] = ("TIMEOUT", elapsed)
|
||||
print(" TIMEOUT after %.1fs" % elapsed)
|
||||
except Exception as e:
|
||||
elapsed = time.time() - t0
|
||||
results[test_file] = ("ERROR", elapsed)
|
||||
print(" ERROR: %s" % e)
|
||||
|
||||
total_elapsed = time.time() - total_start
|
||||
|
||||
print("\n" + DSEP)
|
||||
print("SUMMARY")
|
||||
print(DSEP)
|
||||
passed = 0
|
||||
failed = 0
|
||||
for test_file, (status, elapsed) in results.items():
|
||||
icon = "+" if status == "PASSED" else "x"
|
||||
print(" %s %-35s %-8s (%.1fs)" % (icon, test_file, status, elapsed))
|
||||
if status == "PASSED":
|
||||
passed += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
print("\n Total: %d passed, %d failed, %.1fs elapsed" % (passed, failed, total_elapsed))
|
||||
print(DSEP)
|
||||
return 0 if failed == 0 else 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test CAM++: Speaker Verification"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
print("[CAM++] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(model="iic/speech_campplus_sv_zh-cn_16k-common", device="cpu", disable_update=True)
|
||||
print("[CAM++] Model loaded in %.1fs" % (time.time()-t0))
|
||||
|
||||
print("[CAM++] Extracting speaker embedding...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav",
|
||||
)
|
||||
print("[CAM++] Inference done in %.1fs" % (time.time()-t0))
|
||||
|
||||
if res and len(res) > 0:
|
||||
spk_embedding = res[0].get("spk_embedding", None)
|
||||
if spk_embedding is not None:
|
||||
print("[CAM++] Embedding shape: %s" % str(spk_embedding.shape))
|
||||
print("[CAM++] PASSED")
|
||||
return 0
|
||||
print("[CAM++] FAILED - no speaker embedding")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test CT-Transformer: Punctuation Restoration"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
print("[CT-Transformer] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(model="iic/punc_ct-transformer_zh-cn-common-vocab272727-pytorch", device="cpu", disable_update=True)
|
||||
print("[CT-Transformer] Model loaded in %.1fs" % (time.time()-t0))
|
||||
|
||||
print("[CT-Transformer] Running inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(input="那今天的天气呢也是蛮好的啊你觉得怎么样呢我觉得还不错")
|
||||
print("[CT-Transformer] Inference done in %.1fs" % (time.time()-t0))
|
||||
print("[CT-Transformer] Result: %s" % res)
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[CT-Transformer] PASSED")
|
||||
return 0
|
||||
else:
|
||||
print("[CT-Transformer] FAILED - no punctuation result")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,67 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test ERes2NetV2: speaker verification/diarization with ASR"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
url_zh = "https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav"
|
||||
|
||||
# Test 1: ERes2NetV2 as spk_model combined with VAD + ASR
|
||||
print("[ERes2NetV2] Loading model with VAD + ASR + SPK...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch",
|
||||
vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch",
|
||||
vad_kwargs={"max_single_segment_time": 60000},
|
||||
spk_model="iic/speech_eres2netv2_sv_zh-cn_16k-common",
|
||||
device="cuda:0",
|
||||
disable_update=True,
|
||||
)
|
||||
print("[ERes2NetV2] Model loaded in %.1fs" % (time.time() - t0))
|
||||
|
||||
# Test with speaker diarization
|
||||
print("[ERes2NetV2] Running inference with speaker diarization...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input=url_zh,
|
||||
batch_size_s=300,
|
||||
)
|
||||
print("[ERes2NetV2] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[ERes2NetV2] Result: %s" % res[0]["text"])
|
||||
if "spk" in res[0]:
|
||||
print("[ERes2NetV2] Speaker: %s" % res[0]["spk"])
|
||||
print("[ERes2NetV2] Test 1 PASSED")
|
||||
else:
|
||||
print("[ERes2NetV2] Test 1 FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
# Test 2: ERes2NetV2 standalone speaker embedding
|
||||
print("[ERes2NetV2] Test 2: Standalone speaker embedding...")
|
||||
t0 = time.time()
|
||||
spk_model = AutoModel(
|
||||
model="iic/speech_eres2netv2_sv_zh-cn_16k-common",
|
||||
device="cuda:0",
|
||||
disable_update=True,
|
||||
)
|
||||
res = spk_model.generate(input=url_zh)
|
||||
print("[ERes2NetV2] Embedding done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if res and len(res) > 0 and "spk_embedding" in res[0]:
|
||||
emb = res[0]["spk_embedding"]
|
||||
print("[ERes2NetV2] Embedding shape: %s" % str(emb.shape))
|
||||
print("[ERes2NetV2] Test 2 PASSED")
|
||||
else:
|
||||
print("[ERes2NetV2] Test 2 FAILED - no spk_embedding in result")
|
||||
return 1
|
||||
|
||||
print("[ERes2NetV2] All tests PASSED")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test FSMN-VAD: Voice Activity Detection"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
print("[FSMN-VAD] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch", device="cpu", disable_update=True)
|
||||
print("[FSMN-VAD] Model loaded in %.1fs" % (time.time()-t0))
|
||||
|
||||
print("[FSMN-VAD] Running inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav",
|
||||
)
|
||||
print("[FSMN-VAD] Inference done in %.1fs" % (time.time()-t0))
|
||||
print("[FSMN-VAD] Result: %s" % res)
|
||||
|
||||
if res and len(res) > 0 and "value" in res[0]:
|
||||
print("[FSMN-VAD] Detected %d speech segments" % len(res[0]["value"]))
|
||||
print("[FSMN-VAD] PASSED")
|
||||
return 0
|
||||
else:
|
||||
print("[FSMN-VAD] FAILED - no VAD segments detected")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test FSMN-VAD Streaming: chunk-by-chunk voice activity detection"""
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
|
||||
def main():
|
||||
import soundfile
|
||||
from funasr import AutoModel
|
||||
|
||||
print("[FSMN-VAD-Streaming] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch",
|
||||
device="cpu",
|
||||
disable_update=True,
|
||||
disable_pbar=True,
|
||||
)
|
||||
print("[FSMN-VAD-Streaming] Model loaded in %.1fs" % (time.time() - t0))
|
||||
|
||||
wav_file = os.path.join(model.model_path, "example/vad_example.wav")
|
||||
speech, sample_rate = soundfile.read(wav_file)
|
||||
chunk_size = 200 # ms
|
||||
chunk_stride = int(chunk_size * sample_rate / 1000)
|
||||
|
||||
total_chunk_num = int((len(speech) - 1) / chunk_stride + 1)
|
||||
print("[FSMN-VAD-Streaming] Audio: %.2fs, %d chunks of %dms" % (
|
||||
len(speech) / sample_rate, total_chunk_num, chunk_size))
|
||||
|
||||
print("[FSMN-VAD-Streaming] Running streaming inference...")
|
||||
t0 = time.time()
|
||||
|
||||
cache = {}
|
||||
all_events = []
|
||||
for i in range(total_chunk_num):
|
||||
speech_chunk = speech[i * chunk_stride:(i + 1) * chunk_stride]
|
||||
is_final = i == total_chunk_num - 1
|
||||
res = model.generate(
|
||||
input=speech_chunk,
|
||||
cache=cache,
|
||||
is_final=is_final,
|
||||
chunk_size=chunk_size,
|
||||
)
|
||||
if res[0]["value"]:
|
||||
all_events.extend(res[0]["value"])
|
||||
|
||||
print("[FSMN-VAD-Streaming] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
# Parse streaming VAD events into complete segments
|
||||
# Streaming output: [beg, -1] = speech start, [-1, end] = speech end, [beg, end] = complete
|
||||
complete_segments = []
|
||||
pending_start = None
|
||||
for event in all_events:
|
||||
if event[0] >= 0 and event[1] == -1:
|
||||
pending_start = event[0]
|
||||
elif event[0] == -1 and event[1] >= 0:
|
||||
if pending_start is not None:
|
||||
complete_segments.append([pending_start, event[1]])
|
||||
pending_start = None
|
||||
elif event[0] >= 0 and event[1] >= 0:
|
||||
complete_segments.append(event)
|
||||
|
||||
print("[FSMN-VAD-Streaming] Raw events: %d, Complete segments: %d" % (
|
||||
len(all_events), len(complete_segments)))
|
||||
print("[FSMN-VAD-Streaming] Segments: %s" % complete_segments)
|
||||
|
||||
if not complete_segments:
|
||||
print("[FSMN-VAD-Streaming] FAILED - no complete segments")
|
||||
return 1
|
||||
|
||||
# Verify segments have valid ranges
|
||||
for seg in complete_segments:
|
||||
if seg[1] <= seg[0]:
|
||||
print("[FSMN-VAD-Streaming] FAILED - invalid segment: %s" % seg)
|
||||
return 1
|
||||
|
||||
# Verify consistency: run again with fresh cache
|
||||
cache2 = {}
|
||||
all_events2 = []
|
||||
for i in range(total_chunk_num):
|
||||
speech_chunk = speech[i * chunk_stride:(i + 1) * chunk_stride]
|
||||
is_final = i == total_chunk_num - 1
|
||||
res = model.generate(
|
||||
input=speech_chunk, cache=cache2, is_final=is_final, chunk_size=chunk_size,
|
||||
)
|
||||
if res[0]["value"]:
|
||||
all_events2.extend(res[0]["value"])
|
||||
|
||||
if all_events != all_events2:
|
||||
print("[FSMN-VAD-Streaming] FAILED - inconsistent across sessions")
|
||||
return 1
|
||||
|
||||
print("[FSMN-VAD-Streaming] Consistency: 2 sessions identical")
|
||||
print("[FSMN-VAD-Streaming] PASSED")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test Fun-ASR-Nano + VAD + SPK + PUNC: full pipeline with speaker diarization"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
print("[Fun-ASR-Nano-SPK] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="FunAudioLLM/Fun-ASR-Nano-2512",
|
||||
trust_remote_code=True,
|
||||
remote_code="./model.py",
|
||||
vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch",
|
||||
vad_kwargs={"max_single_segment_time": 30000},
|
||||
spk_model="iic/speech_campplus_sv_zh-cn_16k-common",
|
||||
device="cpu",
|
||||
disable_update=True,
|
||||
hub="hf",
|
||||
)
|
||||
print("[Fun-ASR-Nano-SPK] Model loaded in %.1fs" % (time.time() - t0))
|
||||
|
||||
wav_path = model.model_path + "/example/zh.mp3"
|
||||
|
||||
print("[Fun-ASR-Nano-SPK] Running inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(input=[wav_path], cache={}, batch_size=1, language="中文")
|
||||
print("[Fun-ASR-Nano-SPK] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if not res or len(res) == 0:
|
||||
print("[Fun-ASR-Nano-SPK] FAILED - empty result")
|
||||
return 1
|
||||
|
||||
result = res[0]
|
||||
keys = list(result.keys())
|
||||
print("[Fun-ASR-Nano-SPK] Result keys: %s" % keys)
|
||||
print("[Fun-ASR-Nano-SPK] Text: %s" % result.get("text", ""))
|
||||
|
||||
# Verify timestamp
|
||||
ts = result.get("timestamp", None)
|
||||
if ts is None or len(ts) == 0:
|
||||
print("[Fun-ASR-Nano-SPK] FAILED - no timestamp")
|
||||
return 1
|
||||
print("[Fun-ASR-Nano-SPK] Timestamp count: %d, first: %s" % (len(ts), ts[0]))
|
||||
|
||||
# Verify sentence_info with speaker labels
|
||||
si = result.get("sentence_info", None)
|
||||
if si is None or len(si) == 0:
|
||||
print("[Fun-ASR-Nano-SPK] FAILED - no sentence_info")
|
||||
return 1
|
||||
|
||||
print("[Fun-ASR-Nano-SPK] sentence_info:")
|
||||
for s in si:
|
||||
print(" spk=%d | [%d-%d] %s" % (s["spk"], s["start"], s["end"], s.get("text", s.get("sentence", ""))))
|
||||
|
||||
has_spk = all("spk" in s for s in si)
|
||||
if not has_spk:
|
||||
print("[Fun-ASR-Nano-SPK] FAILED - missing spk label in sentence_info")
|
||||
return 1
|
||||
|
||||
print("[Fun-ASR-Nano-SPK] PASSED")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test GLM-ASR: robust multi-language speech recognition"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
url_zh = "https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav"
|
||||
url_en = "https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_en.wav"
|
||||
|
||||
# Standard FunASR usage
|
||||
# Default hub="ms" (ModelScope), use hub="hf" for HuggingFace
|
||||
print("[GLM-ASR] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="zai-org/GLM-ASR-Nano-2512",
|
||||
hub="hf",
|
||||
device="cuda:0",
|
||||
disable_update=True,
|
||||
)
|
||||
print("[GLM-ASR] Model loaded in %.1fs" % (time.time() - t0))
|
||||
|
||||
# Test 1: Chinese audio
|
||||
print("[GLM-ASR] Test 1: Chinese inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(input=url_zh)
|
||||
print("[GLM-ASR] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[GLM-ASR] Result (zh): %s" % res[0]["text"])
|
||||
print("[GLM-ASR] Test 1 PASSED")
|
||||
else:
|
||||
print("[GLM-ASR] Test 1 FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
# Test 2: English audio
|
||||
print("[GLM-ASR] Test 2: English inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(input=url_en)
|
||||
print("[GLM-ASR] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[GLM-ASR] Result (en): %s" % res[0]["text"])
|
||||
print("[GLM-ASR] Test 2 PASSED")
|
||||
else:
|
||||
print("[GLM-ASR] Test 2 FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
print("[GLM-ASR] All tests PASSED")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test Paraformer-large: offline ASR (Chinese)"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
print("[Paraformer] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="iic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch",
|
||||
vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch",
|
||||
vad_kwargs={"max_single_segment_time": 60000},
|
||||
punc_model="iic/punc_ct-transformer_zh-cn-common-vocab272727-pytorch",
|
||||
device="cpu",
|
||||
disable_update=True,
|
||||
)
|
||||
print("[Paraformer] Model loaded in %.1fs" % (time.time()-t0))
|
||||
|
||||
print("[Paraformer] Running inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input="https://isv-data.oss-cn-hangzhou.aliyuncs.com/ics/MaaS/ASR/test_audio/asr_example_zh.wav",
|
||||
cache={},
|
||||
)
|
||||
print("[Paraformer] Inference done in %.1fs" % (time.time()-t0))
|
||||
print("[Paraformer] Result: %s" % res)
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[Paraformer] PASSED")
|
||||
return 0
|
||||
else:
|
||||
print("[Paraformer] FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test Paraformer-Streaming: chunk-by-chunk streaming ASR"""
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
|
||||
def main():
|
||||
import soundfile
|
||||
from funasr import AutoModel
|
||||
|
||||
print("[Paraformer-Streaming] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="iic/speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-online",
|
||||
device="cpu",
|
||||
disable_update=True,
|
||||
disable_pbar=True,
|
||||
)
|
||||
print("[Paraformer-Streaming] Model loaded in %.1fs" % (time.time() - t0))
|
||||
|
||||
wav_file = os.path.join(model.model_path, "example/asr_example.wav")
|
||||
speech, sample_rate = soundfile.read(wav_file)
|
||||
|
||||
chunk_size = [0, 10, 5]
|
||||
encoder_chunk_look_back = 4
|
||||
decoder_chunk_look_back = 1
|
||||
chunk_stride = chunk_size[1] * 960 # 600ms
|
||||
|
||||
print("[Paraformer-Streaming] Running streaming inference (%.2fs audio, %d chunks)..." % (
|
||||
len(speech) / sample_rate, int((len(speech) - 1) / chunk_stride + 1)))
|
||||
t0 = time.time()
|
||||
|
||||
cache = {}
|
||||
total_chunk_num = int((len(speech) - 1) / chunk_stride + 1)
|
||||
all_text = ""
|
||||
|
||||
for i in range(total_chunk_num):
|
||||
speech_chunk = speech[i * chunk_stride:(i + 1) * chunk_stride]
|
||||
is_final = i == total_chunk_num - 1
|
||||
res = model.generate(
|
||||
input=speech_chunk,
|
||||
cache=cache,
|
||||
is_final=is_final,
|
||||
chunk_size=chunk_size,
|
||||
encoder_chunk_look_back=encoder_chunk_look_back,
|
||||
decoder_chunk_look_back=decoder_chunk_look_back,
|
||||
)
|
||||
txt = res[0].get("text", "") if res else ""
|
||||
all_text += txt
|
||||
|
||||
print("[Paraformer-Streaming] Inference done in %.1fs" % (time.time() - t0))
|
||||
print("[Paraformer-Streaming] Result: '%s'" % all_text)
|
||||
|
||||
expected = "欢迎大家来体验达摩院推出的语音识别模型"
|
||||
if expected in all_text:
|
||||
print("[Paraformer-Streaming] PASSED")
|
||||
return 0
|
||||
else:
|
||||
print("[Paraformer-Streaming] FAILED - expected text not found")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test Qwen3-ASR: multi-language speech recognition via AutoModel"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
|
||||
url_zh = "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-ASR-Repo/asr_zh.wav"
|
||||
url_en = "https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen3-ASR-Repo/asr_en.wav"
|
||||
|
||||
# Standard FunASR usage: model path from ModelScope/HuggingFace
|
||||
# Default hub="ms" (ModelScope), use hub="hf" for HuggingFace
|
||||
print("[Qwen3-ASR] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="Qwen/Qwen3-ASR-1.7B",
|
||||
hub="hf",
|
||||
device="cuda:0",
|
||||
disable_update=True,
|
||||
)
|
||||
print("[Qwen3-ASR] Model loaded in %.1fs" % (time.time() - t0))
|
||||
|
||||
# Test 1: Chinese audio with forced language
|
||||
print("[Qwen3-ASR] Test 1: Chinese inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input=url_zh,
|
||||
language="Chinese",
|
||||
)
|
||||
print("[Qwen3-ASR] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[Qwen3-ASR] Result (zh): %s" % res[0]["text"])
|
||||
print("[Qwen3-ASR] Test 1 PASSED")
|
||||
else:
|
||||
print("[Qwen3-ASR] Test 1 FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
# Test 2: English audio with forced language
|
||||
print("[Qwen3-ASR] Test 2: English inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input=url_en,
|
||||
language="English",
|
||||
)
|
||||
print("[Qwen3-ASR] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[Qwen3-ASR] Result (en): %s" % res[0]["text"])
|
||||
print("[Qwen3-ASR] Test 2 PASSED")
|
||||
else:
|
||||
print("[Qwen3-ASR] Test 2 FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
# Test 3: Auto language detection (no forced language)
|
||||
print("[Qwen3-ASR] Test 3: Auto language detection...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input=url_zh,
|
||||
)
|
||||
print("[Qwen3-ASR] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
print("[Qwen3-ASR] Result (auto): %s" % res[0]["text"])
|
||||
if "language" in res[0]:
|
||||
print("[Qwen3-ASR] Detected language: %s" % res[0]["language"])
|
||||
print("[Qwen3-ASR] Test 3 PASSED")
|
||||
else:
|
||||
print("[Qwen3-ASR] Test 3 FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
print("[Qwen3-ASR] All tests PASSED")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test SenseVoice: multi-task speech understanding"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
from funasr.utils.postprocess_utils import rich_transcription_postprocess
|
||||
|
||||
print("[SenseVoice] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="iic/SenseVoiceSmall",
|
||||
vad_model="fsmn-vad",
|
||||
vad_kwargs={"max_single_segment_time": 30000},
|
||||
device="cpu",
|
||||
disable_update=True,
|
||||
)
|
||||
print("[SenseVoice] Model loaded in %.1fs" % (time.time()-t0))
|
||||
|
||||
print("[SenseVoice] Running inference (Chinese)...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input=model.model_path + "/example/zh.mp3",
|
||||
cache={},
|
||||
language="auto",
|
||||
use_itn=True,
|
||||
batch_size_s=60,
|
||||
merge_vad=True,
|
||||
merge_length_s=15,
|
||||
)
|
||||
print("[SenseVoice] Inference done in %.1fs" % (time.time()-t0))
|
||||
|
||||
if res and len(res) > 0 and "text" in res[0]:
|
||||
text = rich_transcription_postprocess(res[0]["text"])
|
||||
print("[SenseVoice] Result: %s" % text)
|
||||
print("[SenseVoice] PASSED")
|
||||
return 0
|
||||
else:
|
||||
print("[SenseVoice] FAILED - no text in result")
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Test SenseVoice + VAD + SPK + PUNC: speaker diarization with SenseVoice"""
|
||||
import sys
|
||||
import time
|
||||
|
||||
def main():
|
||||
from funasr import AutoModel
|
||||
from funasr.utils.postprocess_utils import rich_transcription_postprocess
|
||||
|
||||
print("[SenseVoice-SPK] Loading model...")
|
||||
t0 = time.time()
|
||||
model = AutoModel(
|
||||
model="iic/SenseVoiceSmall",
|
||||
vad_model="iic/speech_fsmn_vad_zh-cn-16k-common-pytorch",
|
||||
vad_kwargs={"max_single_segment_time": 30000},
|
||||
spk_model="iic/speech_campplus_sv_zh-cn_16k-common",
|
||||
device="cpu",
|
||||
disable_update=True,
|
||||
)
|
||||
print("[SenseVoice-SPK] Model loaded in %.1fs" % (time.time() - t0))
|
||||
|
||||
wav_path = model.model_path + "/example/zh.mp3"
|
||||
|
||||
print("[SenseVoice-SPK] Running inference...")
|
||||
t0 = time.time()
|
||||
res = model.generate(
|
||||
input=wav_path, cache={}, language="auto", use_itn=True,
|
||||
batch_size_s=60, merge_vad=True, merge_length_s=15,
|
||||
)
|
||||
print("[SenseVoice-SPK] Inference done in %.1fs" % (time.time() - t0))
|
||||
|
||||
if not res or len(res) == 0:
|
||||
print("[SenseVoice-SPK] FAILED - empty result")
|
||||
return 1
|
||||
|
||||
result = res[0]
|
||||
keys = list(result.keys())
|
||||
print("[SenseVoice-SPK] Result keys: %s" % keys)
|
||||
|
||||
# Verify text
|
||||
text = rich_transcription_postprocess(result.get("text", ""))
|
||||
print("[SenseVoice-SPK] Text: %s" % text)
|
||||
if not text:
|
||||
print("[SenseVoice-SPK] FAILED - empty text")
|
||||
return 1
|
||||
|
||||
# Verify timestamp exists
|
||||
ts = result.get("timestamp", None)
|
||||
if ts is None or len(ts) == 0:
|
||||
print("[SenseVoice-SPK] FAILED - no timestamp")
|
||||
return 1
|
||||
print("[SenseVoice-SPK] Timestamp count: %d" % len(ts))
|
||||
|
||||
# Verify sentence_info with speaker labels
|
||||
si = result.get("sentence_info", None)
|
||||
if si is None or len(si) == 0:
|
||||
print("[SenseVoice-SPK] FAILED - no sentence_info")
|
||||
return 1
|
||||
|
||||
print("[SenseVoice-SPK] sentence_info:")
|
||||
for s in si:
|
||||
print(" spk=%d | [%d-%d] %s" % (s["spk"], s["start"], s["end"], rich_transcription_postprocess(s.get("text", s.get("sentence", "")))))
|
||||
|
||||
has_spk = all("spk" in s for s in si)
|
||||
if not has_spk:
|
||||
print("[SenseVoice-SPK] FAILED - missing spk label")
|
||||
return 1
|
||||
|
||||
print("[SenseVoice-SPK] PASSED")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user