Skip to content

Export NeMo unified streaming 0.6b models#3602

Merged
csukuangfj merged 1 commit into
k2-fsa:masterfrom
csukuangfj:export-nemo-unified-streaming
May 12, 2026
Merged

Export NeMo unified streaming 0.6b models#3602
csukuangfj merged 1 commit into
k2-fsa:masterfrom
csukuangfj:export-nemo-unified-streaming

Conversation

@csukuangfj

@csukuangfj csukuangfj commented May 12, 2026

Copy link
Copy Markdown
Collaborator

See also #3575
cc @milanleonard

The exported models can be found at
https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models

Screenshot 2026-05-12 at 11 41 34

Usage

wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms.tar.bz2

tar xvf sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms.tar.bz2
 ls -lh sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms
total 1296528
-rw-r--r--@ 1 fangjun  staff   1.0K 12 May 11:26 bias.md
-rw-r--r--@ 1 fangjun  staff   6.9M 12 May 11:25 decoder.int8.onnx
-rw-r--r--@ 1 fangjun  staff   624M 12 May 11:25 encoder.int8.onnx
-rw-r--r--@ 1 fangjun  staff   2.4K 12 May 11:26 explainability.md
-rw-r--r--@ 1 fangjun  staff   1.7M 12 May 11:25 joiner.int8.onnx
-rw-r--r--@ 1 fangjun  staff   4.0K 12 May 11:26 privacy.md
-rw-r--r--@ 1 fangjun  staff   782B 12 May 11:26 safety.md
drwxr-xr-x@ 3 fangjun  staff    96B 12 May 11:26 test_wavs
-rw-r--r--@ 1 fangjun  staff   8.7K 12 May 11:24 tokens.txt
  ./build/bin/sherpa-onnx \
    --debug=1 \
    --encoder=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/encoder.int8.onnx \
    --decoder=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/decoder.int8.onnx \
    --joiner=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/joiner.int8.onnx \
    --tokens=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/tokens.txt \
    --num-threads=3 \
    ./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/test_wavs/0.wav

Logs are

/Users/fangjun/open-source/sherpa-onnx/sherpa-onnx/csrc/parse-options.cc:Read:373 ./build/bin/sherpa-onnx --debug=1 --encoder=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/encoder.int8.onnx --decoder=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/decoder.int8.onnx --joiner=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/joiner.int8.onnx --tokens=./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/tokens.txt --num-threads=3 ./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/test_wavs/0.wav 

OnlineRecognizerConfig(feat_config=FeatureExtractorConfig(sampling_rate=16000, feature_dim=80, low_freq=20, high_freq=-400, dither=0, normalize_samples=True, snip_edges=False), model_config=OnlineModelConfig(transducer=OnlineTransducerModelConfig(encoder="./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/encoder.int8.onnx", decoder="./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/decoder.int8.onnx", joiner="./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/joiner.int8.onnx"), paraformer=OnlineParaformerModelConfig(encoder="", decoder=""), wenet_ctc=OnlineWenetCtcModelConfig(model="", chunk_size=16, num_left_chunks=4), zipformer2_ctc=OnlineZipformer2CtcModelConfig(model=""), nemo_ctc=OnlineNeMoCtcModelConfig(model=""), t_one_ctc=OnlineToneCtcModelConfig(model=""), provider_config=ProviderConfig(device=0, provider="cpu", cuda_config=CudaConfig(cudnn_conv_algo_search=1), trt_config=TensorrtConfig(trt_max_workspace_size=2147483647, trt_max_partition_iterations=10, trt_min_subgraph_size=5, trt_fp16_enable="True", trt_detailed_build_log="False", trt_engine_cache_enable="True", trt_engine_cache_path=".", trt_timing_cache_enable="True", trt_timing_cache_path=".",trt_dump_subgraphs="False" )), tokens="./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/tokens.txt", num_threads=3, warm_up=0, debug=True, model_type="", modeling_unit="cjkchar", bpe_vocab=""), lm_config=OnlineLMConfig(model="", scale=0.5, lodr_scale=0.01, lodr_fst="", lodr_backoff_id=-1, shallow_fusion=True), endpoint_config=EndpointConfig(rule1=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=2.4, min_utterance_length=0), rule2=EndpointRule(must_contain_nonsilence=True, min_trailing_silence=1.2, min_utterance_length=0), rule3=EndpointRule(must_contain_nonsilence=False, min_trailing_silence=0, min_utterance_length=20)), ctc_fst_decoder_config=OnlineCtcFstDecoderConfig(graph="", max_active=3000), enable_endpoint=True, max_active_paths=4, hotwords_score=1.5, hotwords_file="", decoding_method="greedy_search", blank_penalty=0, temperature_scale=2, rule_fsts="", rule_fars="", reset_encoder=False, hr=HomophoneReplacerConfig(lexicon="", rule_fsts=""))
/Users/fangjun/open-source/sherpa-onnx/sherpa-onnx/csrc/online-transducer-nemo-parakeet-unified-model.cc:InitEncoder:194 ---nemo parakeet unified encoder---
url=https://huggingface.co/nvidia/parakeet-unified-en-0.6b
version=2
model_author=NeMo
chunk_feature_frames=16
left_feature_frames=560
left_encoder_frames=70
normalize_type=per_feature
buffered_streaming=1
streaming_model_type=nemo_parakeet_unified_streaming
right_encoder_frames=5
comment=Buffered streaming export, latency=560ms
latency=560ms
model_type=EncDecRNNTBPEModel
pred_rnn_layers=2
right_feature_frames=40
chunk_encoder_frames=2
pred_hidden=640
subsampling_factor=8
feat_dim=128
vocab_size=1024


Start to create recognizer
Recognizer created in 0.82846 s
./sherpa-onnx-nemo-parakeet-unified-en-0.6b-int8-streaming-560ms/test_wavs/0.wav
Number of threads: 3, Elapsed seconds: 7.8, Audio duration (s): 7.4, Real time factor (RTF) = 7.8/7.4 = 1.1
 Well, I don't wish to see it anymore, observed Phoebe, turning away her eyes. It is certainly very like the old portrait
{ "text": " Well, I don't wish to see it anymore, observed Phoebe, turning away her eyes. It is certainly very like the old portrait", "tokens": [" We", "ll", ",", " I", " don", "'", "t", " w", "ish", " to", " see", " it", " any", "m", "ore", ",", " ob", "s", "er", "ved", " P", "h", "o", "e", "be", ",", " t", "ur", "ning", " a", "way", " her", " ey", "es", ".", " It", " is", " cer", "tain", "ly", " ", "very", " li", "ke", " the", " old", " p", "ort", "ra", "it"], "timestamps": [0.96, 0.96, 1.04, 1.12, 1.20, 1.20, 1.20, 1.28, 1.28, 1.52, 1.60, 1.76, 1.92, 2.00, 2.00, 2.32, 2.48, 2.48, 2.48, 2.56, 2.88, 2.88, 2.96, 2.96, 2.96, 3.44, 3.60, 3.60, 3.60, 3.84, 3.92, 4.16, 4.24, 4.24, 5.20, 5.44, 5.52, 5.60, 5.60, 5.68, 6.08, 6.08, 6.24, 6.24, 6.48, 6.56, 6.80, 6.80, 6.88, 6.88], "ys_probs": [], "lm_probs": [], "context_scores": [], "segment": 0, "words": [], "start_time": 0.00, "is_final": false, "is_eof": false}

Summary by CodeRabbit

  • Chores
    • Added GitHub Actions workflow automating build, export, and publication of Nemo Parakeet streaming model variants (multiple latencies, fp32/int8 formats) to Hugging Face and GitHub releases
    • New automation script for model export, ONNX testing, and artifact packaging
    • Updated copyright headers in test utilities

Review Change Stack

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

coderabbitai Bot commented May 12, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

This PR introduces a complete streaming export pipeline for NeMo Parakeet unified models, comprising a shell script that automates model download, ONNX artifact export across multiple latency configurations, inference testing, and output packaging, paired with a GitHub Actions workflow that orchestrates execution on macOS, publishes models to Hugging Face, and uploads release artifacts.

Changes

NeMo Parakeet Streaming Export Pipeline

Layer / File(s) Summary
Export and test script
scripts/nemo/parakeet-unified-en-0.6b/run-streaming.sh
Bash script downloads the Parakeet model and documentation markdown, installs NeMo toolkit and dependencies (with numpy<2), downloads a sample WAV from S3, iterates over target latencies, exports ONNX streaming variants (encoder/decoder/joiner), runs fp32 and int8 inference tests via test helpers, creates output directories per latency, packages model files plus documentation and sample, and compresses the int8 variant into a tarball.
GitHub Actions workflow orchestration
.github/workflows/export-nemo-parakeet-unified-en-0.6b-streaming.yaml
Workflow triggers on push to export-nemo-unified-streaming-2 or manual dispatch, runs on macOS with Python 3.10 (gated to owner k2-fsa or csukuangfj), frees disk space, executes the export script, clones multiple Hugging Face model repositories, copies artifacts with Git LFS tracking for selected file types, commits and pushes to main with retry logic, and uploads all generated tarballs to the GitHub release under tag asr-models.
Copyright header updates
scripts/nemo/parakeet-unified-en-0.6b/test_buffered_streaming_helpers.py, scripts/nemo/parakeet-unified-en-0.6b/test_onnx_streaming.py
Copyright attributions updated to credit Milan Leonard as author in test file headers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • k2-fsa/sherpa-onnx#3555: Both PRs modify the NeMo streaming export pipeline—exporting ONNX encoder/decoder/joiner variants across multiple chunk/latency sizes and packaging/publishing those per-chunk artifacts.

Suggested labels

size:M


🐰 A streaming export takes flight,
Latencies tested, packages tight,
HuggingFace beckons with open arms,
GitHub releases hold Parakeet's charms,
Models unified, tested with care,
Automation everywhere! 🚀

🚥 Pre-merge checks | ✅ 4 | ❌ 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 (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately summarizes the main purpose of the PR—exporting NeMo unified streaming 0.6b models.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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 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 introduces a new bash script for streaming ASR with the Parakeet Unified model and updates copyright headers in associated test files. Review feedback identifies several issues in the bash script: redundant directory listings, a configuration error where the fp32 test incorrectly uses an int8 encoder, and a potential script failure caused by moving the tokens file instead of copying it within a loop.

Comment on lines +41 to +44
ls -lh
echo "---"
ls -lh
echo "---"

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

These lines are redundant as they perform the same directory listing twice consecutively without any intervening operations. It is recommended to remove the duplicate calls.

Suggested change
ls -lh
echo "---"
ls -lh
echo "---"
ls -lh
echo "---"


echo "---fp32----"
python3 ./test_onnx_streaming.py \
--encoder ./encoder.int8.onnx \

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

In the fp32 test section, the encoder path incorrectly points to the int8 version (./encoder.int8.onnx). This should be updated to ./encoder.onnx to ensure the fp32 model is tested correctly.

Suggested change
--encoder ./encoder.int8.onnx \
--encoder ./encoder.onnx \

mv -v encoder.int8.onnx $d
mv -v decoder.int8.onnx $d
mv -v joiner.int8.onnx $d
mv -v tokens.txt $d

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

tokens.txt is moved (mv) here, but it was copied (cp) at line 72. If tokens.txt is not regenerated by the export script in every loop iteration, the script will fail in subsequent iterations because the file will be missing. Using cp is safer and more consistent with how other metadata files are handled.

Suggested change
mv -v tokens.txt $d
cp -v tokens.txt $d

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/export-nemo-parakeet-unified-en-0.6b-streaming.yaml:
- Around line 93-97: The workflow currently runs git add . followed by git
commit -m "first commit" which fails when there are no staged changes; update
the step to detect whether there are staged changes (e.g., use git diff --cached
--quiet or equivalent) and only run git commit -m "first commit" when changes
exist, otherwise skip the commit and continue to the git push
https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/$m main step so the
publish is idempotent.

In `@scripts/nemo/parakeet-unified-en-0.6b/run-streaming.sh`:
- Around line 57-63: The fp32 smoke test is incorrectly using the int8 encoder
file (encoder.int8.onnx) so the fp32 path is never exercised; update the fp32
block that echoes "---fp32----" to pass the fp32 encoder (e.g., encoder.onnx) to
test_onnx_streaming.py instead of encoder.int8.onnx, ensuring the call that
includes --encoder matches the fp32 model filename and that the int8 test block
still uses encoder.int8.onnx.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b0e3fa9a-d821-4555-ac68-52feccffa61e

📥 Commits

Reviewing files that changed from the base of the PR and between 11519a4 and 8e8c35b.

📒 Files selected for processing (5)
  • .github/workflows/export-nemo-parakeet-unified-en-0.6b-streaming.yaml
  • scripts/nemo/parakeet-unified-en-0.6b/export_onnx_streaming.py
  • scripts/nemo/parakeet-unified-en-0.6b/run-streaming.sh
  • scripts/nemo/parakeet-unified-en-0.6b/test_buffered_streaming_helpers.py
  • scripts/nemo/parakeet-unified-en-0.6b/test_onnx_streaming.py

Comment on lines +93 to +97
git add .
git status
git commit -m "first commit"
git push https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/$m main
cd ..

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make HF publish idempotent by guarding empty commits.

git commit at Line 95 fails when there are no staged changes, which can fail the whole publish step even though nothing is wrong.

Suggested fix
               git add .
               git status
-              git commit -m "first commit"
-              git push https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/$m main
+              if git diff --cached --quiet; then
+                echo "No changes to push for $m"
+              else
+                git commit -m "Update model artifacts"
+                git push https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/$m main
+              fi
               cd ..
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
git add .
git status
git commit -m "first commit"
git push https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/$m main
cd ..
git add .
git status
if git diff --cached --quiet; then
echo "No changes to push for $m"
else
git commit -m "Update model artifacts"
git push https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/$m main
fi
cd ..
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/export-nemo-parakeet-unified-en-0.6b-streaming.yaml around
lines 93 - 97, The workflow currently runs git add . followed by git commit -m
"first commit" which fails when there are no staged changes; update the step to
detect whether there are staged changes (e.g., use git diff --cached --quiet or
equivalent) and only run git commit -m "first commit" when changes exist,
otherwise skip the commit and continue to the git push
https://csukuangfj2:$HF_TOKEN@huggingface.co/csukuangfj2/$m main step so the
publish is idempotent.

Comment on lines +57 to +63
echo "---fp32----"
python3 ./test_onnx_streaming.py \
--encoder ./encoder.int8.onnx \
--decoder ./decoder.onnx \
--joiner ./joiner.onnx \
--tokens ./tokens.txt \
--wav 2086-149220-0033.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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

fp32 smoke test is wired to the int8 encoder.

Line 59 points to encoder.int8.onnx inside the ---fp32---- block, so the fp32 encoder path is never actually tested.

Suggested fix
   echo "---fp32----"
   python3 ./test_onnx_streaming.py \
-    --encoder ./encoder.int8.onnx \
+    --encoder ./encoder.onnx \
     --decoder ./decoder.onnx \
     --joiner ./joiner.onnx \
     --tokens ./tokens.txt \
     --wav 2086-149220-0033.wav
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
echo "---fp32----"
python3 ./test_onnx_streaming.py \
--encoder ./encoder.int8.onnx \
--decoder ./decoder.onnx \
--joiner ./joiner.onnx \
--tokens ./tokens.txt \
--wav 2086-149220-0033.wav
echo "---fp32----"
python3 ./test_onnx_streaming.py \
--encoder ./encoder.onnx \
--decoder ./decoder.onnx \
--joiner ./joiner.onnx \
--tokens ./tokens.txt \
--wav 2086-149220-0033.wav
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/nemo/parakeet-unified-en-0.6b/run-streaming.sh` around lines 57 - 63,
The fp32 smoke test is incorrectly using the int8 encoder file
(encoder.int8.onnx) so the fp32 path is never exercised; update the fp32 block
that echoes "---fp32----" to pass the fp32 encoder (e.g., encoder.onnx) to
test_onnx_streaming.py instead of encoder.int8.onnx, ensuring the call that
includes --encoder matches the fp32 model filename and that the int8 test block
still uses encoder.int8.onnx.

@csukuangfj csukuangfj merged commit f95b772 into k2-fsa:master May 12, 2026
1 check passed
@csukuangfj csukuangfj deleted the export-nemo-unified-streaming branch May 12, 2026 06:33
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