chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:25:10 +08:00
commit c397331b1e
3684 changed files with 990993 additions and 0 deletions
+84
View File
@@ -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())
+31
View File
@@ -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())
+28
View File
@@ -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())
+67
View File
@@ -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())
+31
View File
@@ -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())
+98
View File
@@ -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())
+66
View File
@@ -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())
+56
View File
@@ -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())
+38
View File
@@ -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())
+63
View File
@@ -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())
+79
View File
@@ -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())
+44
View File
@@ -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())
+73
View File
@@ -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())