Repository navigation
Update Python APIs for Moonshine v2 models #3235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -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 | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 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" | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To improve readability and maintainability, you can define the model directory path once and reuse it to construct the full paths for the model files. This avoids repeating the long directory name and makes the code cleaner.
Suggested change
|
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| 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() | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+59
to
+66
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For measuring performance,
Suggested change
|
||||||||||||||||||||||||||||||||||
| 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() | ||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To improve maintainability and reduce redundancy, consider using variables for the model archive and directory names. This makes it easier to update the model version in the future. The
lscommand also appears to be for debugging and could be removed from the script.