Repository navigation
feat(local): add Canary 180M Flash as a second speech model - #2273
Merged
AnishSarkar22 merged 2 commits intoOct 15, 2026
Merged
Conversation
A light recogniser for English, German and French: 249.5 MB and a 783 MiB peak on its first request (Apple M2), against Nemotron's 931 MB and 1,776 MiB. - Build canary_asr into audio.cpp and curate it in the manifest, with cc-by-4.0 on the licence allowlist. - A model that cannot detect the language is always told one: Canary told nothing translates into English. Its intent starts on English and auto is refused. - The cleanup joins a comma or full stop written apart from its word, as Canary writes German. - Spanish is not listed: audio.cpp v0.8.2 drops every "ñ" Canary writes. - Settings' speech rows no longer show the memory while transcribing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The card shows the download size and where the model works well. The memory figure is gone from the UI; admission still reads peak_mb. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@AnishSarkar22 is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configuration
📒 Files selected for processing: 42
✨ Finishing Touches
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. Comment |
This was referenced Oct 15, 2026
AnishSarkar22
pushed a commit
to AnishSarkar22/SurfSense
that referenced
this pull request
Oct 16, 2026
The 2.2.2 entry for the website's changelog: sources ready in seconds (MODSetter#2289), speech recognition for recordings and voice input (MODSetter#2264, MODSetter#2273), plugin search, permissions, licensing and speed (MODSetter#2256, MODSetter#2260, MODSetter#2261, MODSetter#2262, MODSetter#2270, MODSetter#2291), ChatGPT plan sign-in (MODSetter#2259), MP3 podcasts (MODSetter#2183), and the fixes, known issues and developer notes since v2.2.1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds Canary 180M Flash as a second curated speech recognition model, next to Nemotron 3.5 ASR Streaming 0.6B. It is the light one, for English (also German and French).
Q8_0)Changes:
canary_asrjoinsFAMILIESinscripts/audiocpp/pins.mjs. It is in the pinned audio.cpp v0.8.2 and already in upstream's macOS archive; Windows and Linux compile it.refresh_local_manifest.py --only canary-180m-flash(sha256-pinned,validated: v0.8.2), its family's locales and request options, the classifier, andcc-by-4.0on the licence allowlist.auto, so a request always names one. Settings already hid "Detect automatically" for such a model.zeigt , dass→zeigt, dass), as Canary writes German.peak_mb.catalog.md,selection.md,admission.md,packaging.md, and the speech proposal (Which model, Order of work, Measurements, and a note that naming a lighter model in the memory refusal is not built yet).Spanish is in Canary's family but not listed: audio.cpp v0.8.2 drops every "ñ" it writes ("Mañana el niño" → "Ma ana el ni o").
Why
Nemotron needs about 2.9 GB free before it loads (its peak plus 1 GiB), which an 8 GB Mac in everyday use rarely has. Canary is the lightest recogniser in the pin with near state-of-the-art English, at a quarter of Nemotron's file and under half its peak.
On its own this does not make dictation work on a tight 8 GB Mac: with 1.07 GiB free, both the app's check (783 MiB plus 1 GiB) and audio.cpp's
--min-free-memory-mb 1024guard still refuse Canary. That needs a separate fix to the memory check on macOS.Fixes # (no issue)
How to test
Automated:
Run locally: backend unit 4,416 passed; LLM and worker integration 411 passed; audio.cpp script tests 19 passed; frontend speech tests 19 passed;
translations:verifyandcheck_docs.pyclean.On the staged server, with the model file:
This needs about 1.5 GiB free for audio.cpp's own guard; on the M2 with 1.07 GiB free it was refused with
insufficient_memory.In the app:
electron/audiocpp/once so staging picks upcanary_asr, thenpnpm dev.Not run: the Windows and Linux audio.cpp builds, which compile the new family in CI.
🤖 Generated with Claude Code
High-level PR Summary
This PR adds Canary 180M Flash as a second speech recognition model alongside the existing Nemotron model. Canary is significantly lighter (249 MB vs 931 MB) and uses less memory during operation (783 MiB vs 1,776 MiB), making it more suitable for systems with limited RAM. It supports English, German, and French, but cannot auto-detect languages and must be explicitly told which language to transcribe. The PR includes catalog updates, language handling changes for non-detecting models, text cleanup for German punctuation spacing, UI simplifications removing memory display during transcription, and comprehensive documentation updates.
⏱️ Estimated Review Time: 15-30 minutes
💡 Review Order Suggestion
docs/proposals/local-speech-to-text.mddocs/architecture/local-models/catalog.mddocs/architecture/local-models/selection.mddocs/architecture/local-models/admission.mddocs/architecture/packaging.mdsurfsense_local/backend/scripts/local_manifest/entries.pysurfsense_local/backend/modules/llm/catalog/local/manifest/models.jsonsurfsense_local/backend/modules/llm/catalog/local/engines/audiocpp/manifest_fields.pysurfsense_local/backend/modules/llm/catalog/local/classifier.pysurfsense_local/electron/scripts/audiocpp/pins.mjssurfsense_local/backend/modules/llm/transcription/language_intent.pysurfsense_local/backend/modules/llm/transcription/language_router.pysurfsense_local/backend/modules/llm/transcription/cleanup.pysurfsense_local/frontend/src/features/models/local/transcription/describe-speech-model.tssurfsense_local/frontend/src/features/speech-setup/speech-model-card.tsxsurfsense_local/frontend/src/features/settings/models/speech-models-settings.test.tsxsurfsense_local/frontend/translations/en.jsonsurfsense_local/backend/scripts/local_manifest/audiocpp/refresh.pysurfsense_local/backend/scripts/local_manifest/licence.pysurfsense_local/backend/tests/integration/llm/test_audio_catalog_routes.pysurfsense_local/backend/tests/integration/llm/test_speech_language_routes.pysurfsense_local/backend/tests/integration/llm/test_transcription_routes.pysurfsense_local/backend/tests/packaging/test_audiocpp_transcription.pysurfsense_local/backend/tests/packaging/test_audiocpp_transcription_config.pysurfsense_local/backend/tests/packaging/test_recording_transcription.pysurfsense_local/backend/tests/unit/llm/catalog/local/engines/audiocpp/rows/test_catalog.pysurfsense_local/backend/tests/unit/llm/catalog/local/test_classifier.pysurfsense_local/backend/tests/unit/llm/transcription/test_cleanup.pysurfsense_local/backend/tests/unit/llm/transcription/test_languages.pysurfsense_local/backend/tests/unit/scripts/test_local_manifest.pysurfsense_local/electron/scripts/audiocpp/recipe.test.mjssurfsense_local/electron/scripts/audiocpp/server-files.test.mjssurfsense_local/frontend/src/features/speech-setup/speech-setup-popover.test.tsxsurfsense_local/frontend/translations/de.jsonsurfsense_local/frontend/translations/es.jsonsurfsense_local/frontend/translations/fr.jsonsurfsense_local/frontend/translations/hi.jsonsurfsense_local/frontend/translations/ja.jsonsurfsense_local/frontend/translations/ko.jsonsurfsense_local/frontend/translations/pt-BR.jsonsurfsense_local/frontend/translations/ru.jsonsurfsense_local/frontend/translations/zh-CN.json