From 5915c93ef3b4512fb4c1f03cc5d0db66add9d2f4 Mon Sep 17 00:00:00 2001 From: Fangjun Kuang Date: Fri, 27 Feb 2026 16:56:57 +0800 Subject: [PATCH] Update Python APIs for Moonshine v2 models --- .github/scripts/test-python.sh | 12 +++ .../offline-moonshine-decode-files-v2.py | 79 +++++++++++++++++++ .../csrc/offline-moonshine-model-config.cc | 6 +- 3 files changed, 94 insertions(+), 3 deletions(-) create mode 100755 python-api-examples/offline-moonshine-decode-files-v2.py diff --git a/.github/scripts/test-python.sh b/.github/scripts/test-python.sh index 5039e95ee8..8662149430 100755 --- a/.github/scripts/test-python.sh +++ b/.github/scripts/test-python.sh @@ -8,6 +8,18 @@ log() { echo -e "$(date '+%Y-%m-%d %H:%M:%S') (${fname}:${BASH_LINENO[0]}:${FUNCNAME[1]}) $*" } +log "test Moonshine v2" + +curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27.tar.bz2 +tar xvf sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27.tar.bz2 +rm sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27.tar.bz2 + +ls -lh sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27 + +python3 ./python-api-examples/offline-moonshine-decode-files-v2.py + +rm -rf sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27 + log "test FireRedASR CTC" curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-fire-red-asr2-ctc-zh_en-int8-2026-02-25.tar.bz2 diff --git a/python-api-examples/offline-moonshine-decode-files-v2.py b/python-api-examples/offline-moonshine-decode-files-v2.py new file mode 100755 index 0000000000..acca6ef3b9 --- /dev/null +++ b/python-api-examples/offline-moonshine-decode-files-v2.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +""" +This file shows how to use a non-streaming Moonshine model from +https://github.com/usefulsensors/moonshine +to decode files. + +Please download model files from +https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models + +For instance, + +wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27.tar.bz2 +tar xvf sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27.tar.bz2 +rm sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27.tar.bz2 +""" + +import datetime as dt +from pathlib import Path + +import sherpa_onnx +import soundfile as sf + + +def create_recognizer(): + encoder = "./sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27/encoder_model.ort" + decoder = ( + "./sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27/decoder_model_merged.ort" + ) + tokens = "./sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27/tokens.txt" + test_wav = "./sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27/test_wavs/0.wav" + + if not Path(encoder).is_file() or not Path(test_wav).is_file(): + raise ValueError( + """Please download model files from + https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models + """ + ) + return ( + sherpa_onnx.OfflineRecognizer.from_moonshine_v2( + encoder=encoder, + decoder=decoder, + tokens=tokens, + debug=False, # Set to True to see more logs + ), + test_wav, + ) + + +def main(): + recognizer, wave_filename = create_recognizer() + + audio, sample_rate = sf.read(wave_filename, dtype="float32", always_2d=True) + audio = audio[:, 0] # only use the first channel + + # audio is a 1-D float32 numpy array normalized to the range [-1, 1] + # sample_rate does not need to be 16000 Hz + + start_t = dt.datetime.now() + + stream = recognizer.create_stream() + stream.accept_waveform(sample_rate, audio) + recognizer.decode_stream(stream) + + end_t = dt.datetime.now() + elapsed_seconds = (end_t - start_t).total_seconds() + duration = audio.shape[-1] / sample_rate + rtf = elapsed_seconds / duration + + print(stream.result) + print(wave_filename) + print("Text:", stream.result.text) + print(f"Audio duration:\t{duration:.3f} s") + print(f"Elapsed:\t{elapsed_seconds:.3f} s") + print(f"RTF = {elapsed_seconds:.3f}/{duration:.3f} = {rtf:.3f}") + + +if __name__ == "__main__": + main() diff --git a/sherpa-onnx/python/csrc/offline-moonshine-model-config.cc b/sherpa-onnx/python/csrc/offline-moonshine-model-config.cc index 66ab7988e0..e957fde4a8 100644 --- a/sherpa-onnx/python/csrc/offline-moonshine-model-config.cc +++ b/sherpa-onnx/python/csrc/offline-moonshine-model-config.cc @@ -17,9 +17,9 @@ void PybindOfflineMoonshineModelConfig(py::module *m) { .def(py::init(), - py::arg("preprocessor") = {}, py::arg("encoder") = {}, - py::arg("uncached_decoder") = {}, py::arg("cached_decoder") = {}, - py::arg("merged_decoder") = {}) + py::arg("preprocessor") = "", py::arg("encoder") = "", + py::arg("uncached_decoder") = "", py::arg("cached_decoder") = "", + py::arg("merged_decoder") = "") .def_readwrite("preprocessor", &PyClass::preprocessor) .def_readwrite("encoder", &PyClass::encoder) .def_readwrite("uncached_decoder", &PyClass::uncached_decoder)