Skip to content

Update Python APIs for Moonshine v2 models - #3235

Merged
csukuangfj merged 1 commit into
k2-fsa:masterfrom
csukuangfj:python-api-moonshine-v2
Feb 27, 2026
Merged

csukuangfj merged 1 commit into
k2-fsa:masterfrom
csukuangfj:python-api-moonshine-v2

Conversation

@csukuangfj

@csukuangfj csukuangfj commented Feb 27, 2026 •

Copy link
Copy Markdown
Collaborator

Usage

(py312) fangjuns-MacBook-Pro:sherpa-onnx fangjun$ python3 ./python-api-examples/offline-moonshine-decode-files-v2.py
/Users/fangjun/open-source/sherpa-onnx/sherpa-onnx/csrc/offline-stream.cc:AcceptWaveformImpl:133 Creating a resampler:
   in_sample_rate: 24000
   output_sample_rate: 16000

{"lang": "", "emotion": "", "event": "", "text": " Ask not what your country can do for you. Ask what you can do for your country.", "timestamps": [], "durations": [], "tokens":[" Ask", " not", " what", " your", " country", " can", " do", " for", " you", ".", " Ask", " what", " you", " can", " do", " for", " your", " country", "."], "ys_log_probs": [], "words": []}
./sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27/test_wavs/0.wav
Text:  Ask not what your country can do for you. Ask what you can do for your country.
Audio duration: 3.845 s
Elapsed:        0.056 s
RTF = 0.056/3.845 = 0.015

Summary by CodeRabbit

  • New Features

    • Added Python example demonstrating offline audio decoding with Moonshine v2 model, including timing metrics and real-time factor calculations.
    • Expanded testing infrastructure for Moonshine v2 and FireRedASR CTC models.
  • Bug Fixes

    • Fixed default parameter values in Moonshine model configuration for improved API usability.

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Feb 27, 2026
@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces support for Moonshine v2 models within the Python API, providing users with a new example to facilitate their integration. It also enhances the CI pipeline to automatically test this new functionality, ensuring stability and correctness. Additionally, a minor but important correction was made to the Python bindings for model configuration, aligning default argument types with their expected string values.

Highlights

  • Moonshine v2 Python API Example: A new Python example script, offline-moonshine-decode-files-v2.py, has been added to demonstrate how to use non-streaming Moonshine v2 models for decoding audio files.
  • CI Pipeline Update: The CI testing script (.github/scripts/test-python.sh) was updated to include steps for downloading, extracting, running, and cleaning up Moonshine v2 models, ensuring continuous validation of the new API.
  • Python Bindings Refinement: The Python C++ bindings for OfflineMoonshineModelConfig were updated to correctly use empty strings ("") as default values for string arguments in the constructor, instead of empty dictionaries ({}).
Changelog
  • .github/scripts/test-python.sh
    • Added steps to download, extract, run, and clean up Moonshine v2 model files for testing purposes.
  • python-api-examples/offline-moonshine-decode-files-v2.py
    • Added a new Python script demonstrating how to use sherpa_onnx.OfflineRecognizer.from_moonshine_v2 to decode audio files with Moonshine v2 models.
  • sherpa-onnx/python/csrc/offline-moonshine-model-config.cc
    • Modified the default argument values for string parameters in the OfflineMoonshineModelConfig constructor from empty dictionaries to empty strings in the Python C++ bindings.
Activity
  • No specific activity (comments, reviews, etc.) has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@coderabbitai

coderabbitai Bot commented Feb 27, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa61676 and 5915c93.

📒 Files selected for processing (3)
  • .github/scripts/test-python.sh
  • python-api-examples/offline-moonshine-decode-files-v2.py
  • sherpa-onnx/python/csrc/offline-moonshine-model-config.cc

📝 Walkthrough

Walkthrough

Adds operational steps to the CI test script for Moonshine v2 and FireRedASR models, introduces a new Python example script demonstrating offline Moonshine v2 decoding with audio processing, and updates default parameter values in the Python binding for OfflineMoonshineModelConfig from braces to empty strings.

Changes

Cohort / File(s) Summary
CI Testing Script
.github/scripts/test-python.sh
Adds test workflow steps to download and execute Moonshine v2 tiny en quantized and FireRedASR CTC zh_en int8 model tests, including extraction and cleanup operations.
Python Example Script
python-api-examples/offline-moonshine-decode-files-v2.py
New example script implementing offline Moonshine v2 model decoding with audio file input, real-time factor computation, and error handling for missing model files.
Python Binding Configuration
sherpa-onnx/python/csrc/offline-moonshine-model-config.cc
Changes default constructor parameter values from empty braces to empty strings for preprocessor, encoder, uncached_decoder, cached_decoder, and merged_decoder arguments.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🌙 A Moonshine glow in code so bright,
New tests and scripts ignite the night,
Offline decoding takes its flight,
With default strings set just right! ✨

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@csukuangfj
csukuangfj merged commit 3ff34bb into k2-fsa:master Feb 27, 2026
0 of 7 checks passed
@csukuangfj
csukuangfj deleted the python-api-moonshine-v2 branch February 27, 2026 09:00

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Python APIs for Moonshine v2 models, introducing a new example script for offline decoding and a corresponding test case in the CI script. The changes are generally good, but I have a few suggestions to improve code quality and maintainability. In both the test script and the new Python example, hardcoded model paths are repeated; refactoring these into variables would make future updates easier. Additionally, the Python example uses datetime.now() for performance measurement, which could be replaced with the more accurate time.perf_counter() for timing operations.

Comment on lines +13 to +21
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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 ls command also appears to be for debugging and could be removed from the script.

Suggested change
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
MODEL_ARCHIVE="sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27.tar.bz2"
MODEL_DIR="sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27"
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/${MODEL_ARCHIVE}
tar xvf "${MODEL_ARCHIVE}"
rm "${MODEL_ARCHIVE}"
python3 ./python-api-examples/offline-moonshine-decode-files-v2.py
rm -rf "${MODEL_DIR}"

Comment on lines +18 to +19
import datetime as dt
from pathlib import Path

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To support more accurate performance measurement with time.perf_counter(), please import the time module.

Suggested change
import datetime as dt
from pathlib import Path
import datetime as dt
import time
from pathlib import Path

Comment on lines +26 to +31
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"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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
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"
model_dir = Path("./sherpa-onnx-moonshine-tiny-en-quantized-2026-02-27")
encoder = model_dir / "encoder_model.ort"
decoder = model_dir / "decoder_model_merged.ort"
tokens = model_dir / "tokens.txt"
test_wav = model_dir / "test_wavs/0.wav"

Comment on lines +59 to +66
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()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For measuring performance, time.perf_counter() is generally more suitable than datetime.datetime.now(). perf_counter() provides a high-resolution monotonic clock that is not affected by system time changes, making it ideal for timing short-duration intervals.

Suggested change
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()
start_t = time.perf_counter()
stream = recognizer.create_stream()
stream.accept_waveform(sample_rate, audio)
recognizer.decode_stream(stream)
end_t = time.perf_counter()
elapsed_seconds = end_t - start_t

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant