Skip to content

Add JavaScript API for FunASR Nano (node-addon) - #3026

Merged
csukuangfj merged 5 commits into
k2-fsa:masterfrom
csukuangfj:javascript-api-funasr-nano-node-addon
Jan 12, 2026
Merged

csukuangfj merged 5 commits into
k2-fsa:masterfrom
csukuangfj:javascript-api-funasr-nano-node-addon

Conversation

@csukuangfj

@csukuangfj csukuangfj commented Jan 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added support for FunASR Nano models for non-streaming speech recognition.
  • Documentation

    • Added example demonstrating how to use FunASR Nano models with detailed setup and execution instructions.
  • Tests

    • Added new test workflow to validate FunASR Nano model functionality.

✏️ Tip: You can customize this high-level summary in your review settings.

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 12, 2026
@coderabbitai

coderabbitai Bot commented Jan 12, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This pull request adds support for the FunASR Nano model to sherpa-onnx. Changes include C++ configuration parsing for the new model type, a Node.js example script demonstrating its usage, CI test integration, and documentation updates describing the feature.

Changes

Cohort / File(s) Summary
C++ Configuration and Integration
harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/non-streaming-asr.cc
Adds GetOfflineFunAsrNanoModelConfig function to parse FunASR Nano configuration fields (encoder_adaptor, llm, embedding, tokenizer, system_prompt, user_prompt, max_new_tokens, temperature, top_p, seed); integrates parsed config into GetOfflineModelConfig; extends FreeConfig to release all FunASR Nano-related string resources.
Node.js Example and Documentation
nodejs-addon-examples/test_asr_non_streaming_funasr_nano.js, nodejs-addon-examples/README.md
Introduces new example script demonstrating non-streaming ASR inference with FunASR Nano model, including waveform loading, recognition execution, and performance metrics; adds table entry and dedicated subsection to README with setup and execution instructions.
CI Testing Workflow
.github/scripts/test-nodejs-addon-npm.sh
Extends test workflow to download, extract, and run FunASR Nano model tests, with corresponding cleanup of artifacts.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

size:M

Poem

🐰 A Nano model hops to play,
With whispers turning words to say,
Through streams both off and on it glides,
While features dance at RTF's tides!
Sherpa's toolkit grows so bright,
FunASR shining, fluffy and right! 🎧

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the main change: adding a JavaScript API for FunASR Nano in the node-addon, which is reflected across all modified files including the new test script, C++ configuration parser, GitHub workflow, and documentation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5437407 and 810220c.

📒 Files selected for processing (4)
  • .github/scripts/test-nodejs-addon-npm.sh
  • harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/non-streaming-asr.cc
  • nodejs-addon-examples/README.md
  • nodejs-addon-examples/test_asr_non_streaming_funasr_nano.js
🔇 Additional comments (8)
harmony-os/SherpaOnnxHar/sherpa_onnx/src/main/cpp/non-streaming-asr.cc (3)

402-407: LGTM! Memory cleanup is complete.

All six string fields allocated in GetOfflineFunAsrNanoModelConfig are properly freed, preventing memory leaks.


305-305: LGTM!

Integration follows the established pattern for other model configurations.


113-136: LGTM! FunASR Nano config parser correctly implements all struct fields.

The implementation:

  • Zero-initializes the struct with memset
  • Guards against missing/invalid funasrNano object
  • Assigns all 10 fields (6 strings, 4 numeric values) using appropriate macros
  • All string fields are properly freed in FreeConfig (lines 402–407)
nodejs-addon-examples/README.md (2)

130-130: LGTM!

Table entry follows the established format and links to the correct test file.


433-441: LGTM!

Documentation section follows the established pattern with proper download, extract, cleanup, and execution commands.

nodejs-addon-examples/test_asr_non_streaming_funasr_nano.js (2)

6-25: LGTM! Config structure is appropriate for FunASR Nano.

The configuration correctly specifies the required model paths. Optional fields like systemPrompt, userPrompt, maxNewTokens, temperature, topP, and seed are omitted and will default to zero/null values per the C++ parser's memset initialization.


30-51: LGTM!

The recognition flow follows the established pattern for non-streaming ASR test scripts:

  1. Create recognizer and stream
  2. Read and accept waveform
  3. Decode and retrieve result
  4. Log timing metrics and RTF
.github/scripts/test-nodejs-addon-npm.sh (1)

13-20: LGTM! Test workflow follows established patterns.

The FunASR Nano test block correctly:

  • Downloads the model archive
  • Extracts and cleans up the archive
  • Runs the test script
  • Removes the model directory after testing

This test runs unconditionally on all platforms by design. The script reserves platform restrictions (arch, platform, node_version checks) for larger models later in the file (e.g., lines 166, 282, 366) that encounter resource constraints on specific platforms.


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.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello @csukuangfj, 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 significantly expands the capabilities of the Sherpa ONNX Node.js addon by integrating the FunASR Nano model for non-streaming automatic speech recognition. The changes provide a complete solution, from the underlying C++ bindings that manage model configuration to a user-friendly JavaScript API and a clear example, making it straightforward for developers to leverage FunASR Nano in their Node.js applications. This enhancement broadens the range of supported ASR models and improves the overall utility of the addon.

Highlights

  • New JavaScript API: Introduced a new JavaScript API for the FunASR Nano model, enabling its use for non-streaming speech recognition within Node.js environments.
  • C++ Bindings: Added C++ bindings to handle the configuration and integration of the FunASR Nano model, including parameters like encoder adaptor, LLM, embedding, and tokenizer.
  • New Example Script: Provided a new JavaScript example script (test_asr_non_streaming_funasr_nano.js) demonstrating how to set up and use the FunASR Nano model for speech recognition.
  • CI and Documentation Updates: Integrated the FunASR Nano example into the CI testing pipeline and updated the README.md to include instructions and details for the new example.
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. ↩

@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 adds support for FunASR Nano models to the Node.js addon, including C++ bindings, a new JavaScript example, CI test script updates, and documentation. The changes are well-integrated, especially the C++ part which correctly handles memory management. I've provided a few suggestions to enhance the shell script and JavaScript example for better maintainability by reducing hardcoded, repeated strings.

Comment on lines +15 to +20
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
tar xvf sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
rm sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2

node ./test_asr_non_streaming_funasr_nano.js
rm -rf sherpa-onnx-funasr-nano-int8-2025-12-30

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 script robustness and maintainability, it's better to chain commands that depend on each other with &&. This ensures that the script will stop if a command fails. Also, using a variable for the model name avoids repetition and makes it easier to update.

Consider adding set -e at the top of your script to make it exit immediately if a command exits with a non-zero status.

Suggested change
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
tar xvf sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
rm sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
node ./test_asr_non_streaming_funasr_nano.js
rm -rf sherpa-onnx-funasr-nano-int8-2025-12-30
MODEL_NAME="sherpa-onnx-funasr-nano-int8-2025-12-30"
curl -SL -O "https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/${MODEL_NAME}.tar.bz2" && \
tar xvf "${MODEL_NAME}.tar.bz2" && \
rm "${MODEL_NAME}.tar.bz2"
node ./test_asr_non_streaming_funasr_nano.js
rm -rf "${MODEL_NAME}"

Comment on lines +436 to +440
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
tar xvf sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
rm sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2

node ./test_asr_non_streaming_funasr_nano.js

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 better maintainability and to avoid repeating the long model filename, consider introducing a variable in this example script. This makes it easier to update the model version in the future.

For example:

MODEL_NAME="sherpa-onnx-funasr-nano-int8-2025-12-30"
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/${MODEL_NAME}.tar.bz2
tar xvf "${MODEL_NAME}.tar.bz2"
rm "${MODEL_NAME}.tar.bz2"

node ./test_asr_non_streaming_funasr_nano.js

Comment on lines +6 to +28
const config = {
'featConfig': {
'sampleRate': 16000,
'featureDim': 80,
},
'modelConfig': {
'funasrNano': {
'encoderAdaptor':
'./sherpa-onnx-funasr-nano-int8-2025-12-30/encoder_adaptor.int8.onnx',
'llm': './sherpa-onnx-funasr-nano-int8-2025-12-30/llm.int8.onnx',
'embedding':
'./sherpa-onnx-funasr-nano-int8-2025-12-30/embedding.int8.onnx',
'tokenizer': './sherpa-onnx-funasr-nano-int8-2025-12-30/Qwen3-0.6B',
},
'tokens': '',
'numThreads': 2,
'provider': 'cpu',
'debug': 1,
}
};

const waveFilename =
'./sherpa-onnx-funasr-nano-int8-2025-12-30/test_wavs/lyrics.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

The model directory path is hardcoded in multiple places. To improve maintainability, it's a good practice to define it as a constant and reuse it. This makes it much easier to update the model version in the future.

For example:

const modelDir = './sherpa-onnx-funasr-nano-int8-2025-12-30';
const config = {
  'featConfig': {
    'sampleRate': 16000,
    'featureDim': 80,
  },
  'modelConfig': {
    'funasrNano': {
      'encoderAdaptor': `${modelDir}/encoder_adaptor.int8.onnx`,
      'llm': `${modelDir}/llm.int8.onnx`,
      'embedding': `${modelDir}/embedding.int8.onnx`,
      'tokenizer': `${modelDir}/Qwen3-0.6B`,
    },
    'tokens': '',
    'numThreads': 2,
    'provider': 'cpu',
    'debug': 1,
  }
};

const waveFilename = `${modelDir}/test_wavs/lyrics.wav`;

@csukuangfj
csukuangfj merged commit b97c8c5 into k2-fsa:master Jan 12, 2026
1 check passed
@csukuangfj
csukuangfj deleted the javascript-api-funasr-nano-node-addon branch January 12, 2026 10:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant