Skip to content

feat(asr): add Parakeet TDT 0.6B engine via sherpa-onnx - #771

Open
AlexThunder1989 wants to merge 5 commits into
VocaHQ:mainfrom
AlexThunder1989:feature/parakeet-engine
Open

feat(asr): add Parakeet TDT 0.6B engine via sherpa-onnx#771
AlexThunder1989 wants to merge 5 commits into
VocaHQ:mainfrom
AlexThunder1989:feature/parakeet-engine

Conversation

@AlexThunder1989

Copy link
Copy Markdown

Description

Adds a parakeet speech recognition engine backed by sherpa-onnx, running NVIDIA Parakeet TDT 0.6B int8 models on CPU:

  • v3-european — 25 European languages, automatic language detection (639 MB)
  • v2-english — English (630 MB)

Output is punctuated and capitalized without post-processing.

On an Intel Core Ultra 7 155H it decodes at about 12x realtime on CPU (RTF 0.08), roughly 8x faster than whisper.cpp large-v3-turbo over the same clips with its Vulkan GPU backend (RTF 0.59). Being a transducer it has no 30 s window to pad, so a short push-to-talk utterance returns in ~0.3 s rather than ~2.4 s. Measured over four EN/DE/ES/FR clips.

utils/parakeet_model_info.py holds the catalog plus get_model_path / is_model_downloaded / list_downloaded_models / delete_model, mirroring vosk_model_info.py and whispercpp_model_info.py. _init_parakeet / _transcribe_with_parakeet / _download_parakeet_model follow the same shape as their whisper.cpp counterparts and reuse _stream_model_download, so progress, speed, ETA and cancellation behave as for the other engines. model_size is validated with a fallback as in _init_whispercpp.

Registered in the engine dispatch (init, transcribe, reconfigure, resume-reinit), the Settings engine/model/language pickers, the model info card, both download prompts, the unused-downloads list and delete path, install.sh and the README engine list.

Models download to <models_dir>/parakeet/<model>/ as temp files renamed on success; is_model_downloaded requires all four bundle files, so an interrupted download is retried rather than half-loaded.

_init_parakeet does not take _model_lock, because reconfigure() and reinitialize_after_resume() already hold that non-reentrant lock when they call it.

Installed via the new parakeet extra (sherpa-onnx); uv.lock regenerated.

Related Issue

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to change)
  • 📖 Documentation update
  • 🧹 Code refactoring
  • ✅ Test update

Checklist

  • My code follows the code style of this project (black, isort)
  • I have updated the documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests pass locally
  • Pre-commit hooks pass

Adds a "parakeet" engine backed by sherpa-onnx, running NVIDIA Parakeet
TDT 0.6B int8 models on CPU: v3 (25 European languages, auto-detected)
and v2 (English). Output is punctuated and capitalized.

On an Intel Core Ultra 7 155H it decodes at about 12x realtime on CPU
(RTF 0.08), roughly 8x faster than whisper.cpp large-v3-turbo over the
same clips with its Vulkan GPU backend (RTF 0.59). Being a transducer it
also has no 30s window to pad, so a short push-to-talk utterance returns
in ~0.3s instead of ~2.4s.

Follows the existing engine layout: utils/parakeet_model_info.py holds
the catalog and the get_model_path / is_model_downloaded /
list_downloaded_models / delete_model helpers, while _init_parakeet /
_transcribe_with_parakeet / _download_parakeet_model follow the same shape as their
whisper.cpp counterparts and reuse _stream_model_download for progress
and cancellation.

Registered in the engine dispatch, the settings engine/model/language
pickers, the model info card, the download prompts, the unused-downloads
list and install.sh.

Models download to <models_dir>/parakeet/<model>/ via temp files renamed
on success; is_model_downloaded requires all four files, so an
interrupted download is retried rather than loaded.

Requires the new "parakeet" extra (sherpa-onnx).
@netlify

netlify Bot commented Sep 3, 2026

Copy link
Copy Markdown

Deploy Preview for voca-linux canceled.

Name Link
🔨 Latest commit b6d5815
🔍 Latest deploy log https://app.netlify.com/projects/voca-linux/deploys/6a997a28e6cbc200083756ac

@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown

Thanks @AlexThunder1989. A maintainer will review it.


Meanwhile, connect with us:

Discord X

@github-actions github-actions Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file app Core Python application (src, packaging) installer Install/uninstall scripts labels Sep 3, 2026
@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 15.82734% with 117 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ocalinux/speech_recognition/recognition_manager.py 4.12% 89 Missing and 4 partials ⚠️
src/vocalinux/utils/parakeet_model_info.py 42.85% 24 Missing ⚠️

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented Sep 3, 2026

Copy link
Copy Markdown

Greptile Summary

Adds a CPU-based Parakeet speech-recognition engine using sherpa-onnx.

  • Registers Parakeet across installation, configuration, runtime dispatch, and settings.
  • Adds pinned model catalogs, multi-file downloading, model management, and dependency metadata.

Confidence Score: 2/5

The PR is not yet safe to merge because model authenticity remains unenforced and the Parakeet language configuration still exposes behavior the engine does not honor.

Same-length altered model artifacts can still pass the size-only download check and reach sherpa-onnx, while users can persist non-English language selections with the English-only model even though Parakeet ignores that setting.

Files Needing Attention: src/vocalinux/speech_recognition/recognition_manager.py, src/vocalinux/utils/parakeet_model_info.py, src/vocalinux/ui/settings_dialog.py

Important Files Changed

Filename Overview
src/vocalinux/speech_recognition/recognition_manager.py Adds Parakeet download, initialization, transcription, and lifecycle dispatch paths.
src/vocalinux/utils/parakeet_model_info.py Defines the two model bundles, pinned revisions, expected sizes, paths, and deletion helpers.
src/vocalinux/ui/settings_dialog.py Integrates Parakeet into engine selection, model prompts, metadata, and local-model management.
install.sh Adds Parakeet dependency installation, initial configuration, and display metadata.
pyproject.toml Adds the optional sherpa-onnx dependency extra.
uv.lock Locks sherpa-onnx and records the new Parakeet extra.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Settings or CLI selects Parakeet] --> B[Recognition manager]
    B --> C{Model bundle present?}
    C -- No --> D[Download four model files]
    D --> E[Initialize sherpa-onnx recognizer]
    C -- Yes --> E
    E --> F[Decode 16 kHz PCM]
    F --> G[Punctuated transcript]
Loading

Reviews (5): Last reviewed commit: "fix(asr): reject a truncated Parakeet do..." | Re-trigger Greptile

Comment thread src/vocalinux/speech_recognition/recognition_manager.py
Comment thread src/vocalinux/speech_recognition/recognition_manager.py
The parakeet branch duplicated a full default config.json. ConfigManager
deep-merges DEFAULT_CONFIG on load, so every other key was redundant:
a config holding only "engine": "parakeet" still resolves
parakeet_model_size to v3-european along with the VAD, shortcut and
text-injection defaults.
Writing only the engine key left config.json without a shortcuts
section, which _migrate_shortcuts_config reads as a pre-push-to-talk
upgrade and pins back to ctrl+ctrl/toggle - contradicting the
installer's own "Hold Right Alt while you speak" message. Seed that
section too.

Point the config at parakeet with set_configured_engine rather than only
on first create, so --engine=parakeet also switches a machine that
already has a config.json, and give print_welcome_message a parakeet arm
so the summary is not blank.

The interactive picker overwrites SELECTED_ENGINE, so document the flag
combination that reaches this branch.
Pin each bundle to a Hugging Face commit instead of resolve/main, so a
file replaced upstream cannot change what an install downloads. This is
the same approach whispercpp_model_info takes with its pinned revision.

Remap each file's progress into its slice of the bundle. The four files
were reported through the single-file downloader independently, so the
fraction ran to 1.0 and restarted four times; it now advances once and
names the file being fetched.
Comment thread src/vocalinux/speech_recognition/recognition_manager.py
_stream_model_download only rejects an empty body, so a truncated but
nonempty response was renamed into the model directory and then reported
as installed, because is_model_downloaded checks existence.

Record the byte size of each file at the pinned revision and check it
before the rename, the same order whisper.cpp verifies its digest in. A
short file is a truncated transfer rather than an upstream change, since
the revision is pinned, so it raises and the temp file is removed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app Core Python application (src, packaging) dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation installer Install/uninstall scripts

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants