- Python 99.2%
- Shell 0.6%
- Nix 0.2%
| .woodpecker | ||
| docs | ||
| examples | ||
| mega_asr_loop | ||
| recipes/funasr-nano | ||
| tests | ||
| .gitignore | ||
| .pubmirror.toml | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
mega-asr-loop
A personal speech-recognition improvement loop. Point it at your own recordings and it tells you how well each recognizer hears you, where it goes wrong and why, and which fix is worth making. Then it measures that fix against a prediction you wrote down before it ran.
inventory → segment → references and backing → errors → selection → prediction → tune or train → verify
It grew out of improving megavoice, a dictation app, for one speaker who mixes Mandarin and English in a sentence. Every step is one that was run by hand first; the repo makes it repeatable for anyone's voice. It runs without megavoice, and reads or drives it where it is installed.
Start
nix develop # or: Python >= 3.11, uv and ffmpeg
uv run pytest # offline, on synthetic data
examples/public-demo.sh # the whole loop on public speech, under its own profile
Then docs/day-one.md: from a fresh machine to your first verified improvement.
The steps
| step | command | what it gives you |
|---|---|---|
| inventory | inventory |
every recording from every source in one store; quality (level, clipping, SNR, bandwidth, reverberation), language, device; reports/inventory.md, quality.md |
| segment | segment |
each take cut as the runtime decodes it (mega-asr's asrbench split -whole at your take.* constants): whole windows and chunks, each edge's reason, the category whole, chunk-pause, chunk-forced or tail |
| references | calibrate sample|packets|annotate|agree|collect, labels resolve|consensus |
what you actually said, for a stratified sample, from every engine's output and your context, with a blind second reader; every label in labels.jsonl with its tier and provenance |
| backing | backing, calibrate audit |
which independent families heard each reference token, and the references' distance from a second, independent reference: how far a number can be trusted |
| measure | engines run, score |
each recognizer's error rate per language and split, with bootstrap CIs, charged and backed-only; local engines and opt-in cloud ones |
| errors | errors packets|annotate|collect |
every error as a span, classified, each class with its fix routes, reconciled with the score |
| selection | select, split, export |
takes excluded only where the engines disagree past repair; dev and held-out by day; training labels with their convention |
| predict | predict new|seal|status |
what a change should move, by how much and why, sealed with its gate before any number exists |
| tune | tune corrections|hotwords|settings|lora-funasr-nano |
a candidate, chosen on dev: cheapest fix first, a LoRA fine-tune last |
| verify | verify |
base against candidate on held-out, the gate with its sensitivity verdict (worse, better or tie), and every prediction against its measurement |
| train | labels ingest-recipe |
a recipe's cleaned texts and drops back in the store as derived labels and decisions, so the next model reuses them |
Docs
| page | for |
|---|---|
| docs/day-one.md | the first run, cold |
| docs/evaluation.md | the evaluation SOP: what a reference is worth, which scorer hides what, segment categories, families and backing, reading result.md, the check before a training run |
| docs/record.md | the store: one row per recording, and what each field means |
| docs/dataset.md | the dataset: its four stores, labels and their tiers, merge and resolve rules, migrate |
| docs/engines.md | the engines, the cache and the local runtimes |
| docs/calibration.md | building references |
| docs/predict.md | predictions, gates, verify and the tune steps |
| docs/privacy.md | what may leave your machine, and when |
| docs/megavoice.md | the five contracts with megavoice |
| recipes/funasr-nano/README.md | the LoRA fine-tune of Fun-ASR-Nano |
examples/ holds a full profile for a fictional user (config.toml, profile/), a worked gate and prediction,
and the public demo.
Privacy
Your audio, labels, references, runs, vocabulary files and keys live under the profile's data root (mode 700),
never in this repo. Audio leaves the machine only for a cloud engine your profile names and opts in, after the
loop prints the hours it will send. mega-asr-loop check private refuses home paths, keys and your private tokens
in the tree and the staged diff; gate every commit on it.
Contributing to this repo: its commits are published as they are, so each clone runs pubmirror install once
(pubmirror, on PATH); its hooks scan every commit against .pubmirror.toml.
License
Apache-2.0 (LICENSE).
The loop redistributes no model and no dataset: each is downloaded by the step that uses it, under its own license.
- The LoRA recipe (
recipes/funasr-nano/) drives FunASR's trainer (funasr 1.4.16) and its encoder exporter, code under the MIT License. FunASR's models are under the FunASR Model Open Source License v1.1, which lets you use, modify and share them and their fine-tuned derivatives, provided you attribute the source and keep the model names. - Fun-ASR-Nano-2512 (FunAudioLLM), the model it fine-tunes, is Apache-2.0 on its model card at the pinned
revision
272c57b; its language model is Qwen3-0.6B, Apache-2.0. A tunedqwen3-0.6b-q8_0.ggufis a derivative of both: keep their names and attribution with it. - llama.cpp (MIT) converts and quantizes the exported weights.
- The demo's engines, sherpa-onnx exports: SenseVoice-Small under the FunASR Model License, Whisper tiny (OpenAI) under MIT, X-ASR's Zipformer transducer under Apache-2.0. The speakers step uses pyannote segmentation-3.0 (MIT) and 3D-Speaker CAM++ (Apache-2.0).
- Public speech: ASCEND (CC BY-SA 4.0), LibriSpeech (CC BY 4.0), AISHELL-1 (Apache-2.0).