Sanskrit speech recognition tuned for śāstric / recitational Sanskrit, plus Vāgbodhinī, an interactive chant-practice tool built on it. This repository documents the full set of experiments — including the ones that did not work, which were as instructive as the ones that did.
Headline result (§5b): the model looked saturated on studio audio (~6% CER) — but on real, in-the-wild user audio it had large headroom, and a consented data flywheel closed most of it. On a 327-clip leakage-free in-the-wild held-out, the deployed model cuts CER 7.7% → 4.4% (−43%) and WER 45% → 30% vs the studio-only base, with no loss on studio/chant/prose benchmarks. The flywheel now spans ~13,100 consented clips from ~1,500 users across 11 scripts.
Off-the-shelf Sanskrit ASR is trained on conversational IndicVoices-style data and degrades badly on recitation and śāstra — dense compounds, sandhi, retroflex/aspirate contrasts, pitch, and long metrical utterances. The goal here was a model and tooling good enough for scholars: accurate on chant and prose, and useful as a practice aid rather than a transcription toy.
Two things shaped everything:
lo..hi.Representative v5 numbers (held-out):
| domain | CER | WER | SN-WER |
|---|---|---|---|
| e-PG lecture (gold) | 3.6% | 13.0% | ~9–10% |
| Bhāgavata chant | 6.0% | 46.4% | ~22–26% |
| Vedānta prose | 7.3% | 30.8% | ~15–19% |
The gap between WER and SN-WER quantifies point (1): roughly half of Sanskrit "WER" is spacing.
EncDecHybridRNNTCTCBPEModel (IndicConformer, ~129 M params). We use the CTC
head on the Sanskrit token slice (cols = [BLANK] + range(4096,4352), re-log_softmax), greedy
decode.A compressed log of the campaign. Bold = shipped / kept.
| # | Experiment | Idea | Outcome |
|---|---|---|---|
| 1 | v5 finetune (CTC) | finetune IndicConformer on recitation+prose+TTS | shipped; chant CER 6.0% |
| 2 | SN-WER metric | strip sandhi/spacing before scoring | adopted; showed ½ of WER is spacing |
| 3 | v8 pseudo-labels | self-train on high-confidence v5 outputs | ✗ confidence doesn't separate right/wrong (wrong words median conf 0.93); label noise → no gain |
| 4 | Hard-negative annotation | pick hardest clips by v5-vs-Whisper disagreement for scholars to label | adopted for the annotation drive |
| 5 | Multi-scholar portal | concurrency-safe claim-queue annotation web tool | shipped; used to collect clean labels |
| 6 | SSL pretraining | wav2vec2-style contrastive on 38 h of Sanskrit śāstric audio; freeze frontend+lower layers | ✗ SSL-init finetune (v9b) < clean-label finetune (v9a) |
| 7 | Semi-supervised pseudo-labels | v5/v9 teacher → confidence-gated pseudo-labels | ✗ confirmed to hurt (3 independent tests) |
| 8 | v9 finetunes (v9a / v9-v2 / v9-v3) | add 846 clean scholar labels (47 speakers) + gold, honest held-out split | ✗ CER flat vs v5; gold WER worse (segmentation drift). First "−28%" was a favorable-split artifact |
| 9 | Rule-based sandhi segmenter | DP split of merged tokens to fix WER | ✗ over-shatters (Sanskrit tiles into everything); WER worse |
| 10 | ByT5-Sanskrit post-corrector | byte-level seq2seq to fix ASR output | ✗ over-corrects rare terms (prose CER 7→22); segmentation concept helped chant WER 46→42 only |
| 11 | Blank-penalty / r-recall sweep | penalize CTC blank to recover dropped onsets/repha | partial; diagnostic — CTC blank bias explains onset/short-phone deletions |
| 12 | Onset & CER-distribution analysis | per-position and per-clip error structure | diagnostic — first 2–3 words dropped (encoder ramp-up); e-PG tail is speaker-driven & bimodal |
| 13 | Baselines | Whisper-sa, wav2vec2 finetunes | v5 (IndicConformer-CTC) remained the best on chant/prose |
| 14 | GOP forced alignment | Goodness-of-Pronunciation for chant scoring | validated (AUC 0.97–0.99) but too false-positive-prone for a tutor → superseded |
| 15 | Vāgbodhinī chant tool | exploit the known reference text: verify, don't transcribe | shipped (see §6) |
| 16 | Consented data flywheel | collect real user audio + labels from the live tools, tiered by trust | shipped; grew to ~13.1k clips / ~1,500 users / 11 scripts |
| 17 | v10 flywheel retrain (wholesale) | finetune v5-recipe + flywheel from base, 20 ep | in-the-wild CER 24→16 (big), but gold regressed 3.6→6.1 (distribution shift) |
| 18 | v11 flywheel retrain (domain-balanced) | continue from v5, low LR, few epochs, flywheel upsampled | first balanced retrain; superseded by v12/v13b as the flywheel grew |
| 19 | v12 / v13 / v13b retrains | same balanced recipe on the grown flywheel; validated on a 327-clip leakage-free held-out | shipped as v13b-ep3 — in-the-wild CER 4.36 (beats v5 7.70 and v12-ep9 5.19); studio/chant/prose flat |
| 20 | Review-tier rescue audit | re-decode quarantined review clips with the current model; promote only perfect re-matches | only 4.3% recoverable → auto-grader validated: the pile is genuine reader deviations, not model error |
Once the live tools were public, every consented recording was logged with its label, tiered by
trustworthiness (pass ≥90% match · override/corrected = human-verified · review ·
low/unclear = archived). It has since grown to ~13,100 clips from ~1,500 users across 11
scripts (a third non-Devanāgarī), including ~420 human corrections.
We hold out flywheel data by session (no speaker leakage) as an in-the-wild eval set — the real deployment distribution — and retrain periodically.
v5 vs the deployed v13b-ep3 (CER / WER):
| eval set | v5 (studio-only) | v13b-ep3 (current, shipped) |
|---|---|---|
| gold — studio lecture † | 3.61 / 13.0 | 4.40 / 20.2 |
| Bhāgavata chant | 6.00 / 46.4 | 5.99 / 46.3 |
| Vedānta prose | 7.27 / 30.8 | 7.23 / 30.4 |
| in-the-wild (327-clip leakage-free held-out) | 7.70 / 45.4 | 4.36 / 30.4 |
† The gold studio set was transcribed by correcting v5's own drafts, so v5 is flattered there —
it is not a fair cross-model set. The unanchored comparisons are chant/prose (independent
forced-align references) and the in-the-wild held-out.
Findings:
review clip with the current
model recovered only 4.3% as model error — the other ~96% are genuine reader deviations, so
the tiering hides no reservoir of usable data. The next lever is new/diverse data, not more of
the same. Scripts: scripts/v11_prep.py, scripts/v13b_prep.py, scripts/rescue.py,
scripts/flywheel_clean.py, scripts/harvest_flywheel.py.The loop, closed and self-improving: better model → better live scoring → cleaner tiered data →
a better next model. Both tools feed one shared core ASR (ft_ctc_current), so they always update
together.
vagbodhini/ — a standalone web app.
See docs/ for the full system spec (services, ports, endpoints, data format).
The Sanskrit ASR weights (IndicConformer-CTC) are on Hugging Face:
prathoshap/sushrota-sanskrit-asr—sushrota_sanskrit_asr_v13b.nemois the deployed model (v13b-ep3: v5 continued on consented user data, §5b);sushrota_sanskrit_asr_v5.nemois the studio-only base. (See the model card for usage.)
The training data (17.4 h / 6,438 utterances + a 327-clip in-the-wild benchmark) is released as a dataset:
The metre-aware TTS for reference chants, Vāgdhenu, is separately at
prathoshap/vagdhenu.
vagbodhini/ the chant-practice app (FastAPI backend + single-file UI + TTS microservice)
scripts/ all experiment / training / evaluation / analysis scripts (§4)
docs/ system documentation
README.md this report
Notes:
If you use this work, please cite:
Prathosh A P, Su-śrotā: Scholar-grade Sanskrit ASR and metre-aware chant practice, Indian Institute of Science, Bengaluru, 2026.
3 commits
Hacker News (1)
Python
82.2%
HTML
15.0%
Shell
2.8%
Sanskrit speech recognition tuned for śāstric / recitational Sanskrit, plus Vāgbodhinī, an interactive chant-practice tool built on it. This repository documents the full set of experiments — including the ones that did not work, which were as instructive as the ones that did.
Headline result (§5b): the model looked saturated on studio audio (~6% CER) — but on real, in-the-wild user audio it had large headroom, and a consented data flywheel closed most of it. On a 327-clip leakage-free in-the-wild held-out, the deployed model cuts CER 7.7% → 4.4% (−43%) and WER 45% → 30% vs the studio-only base, with no loss on studio/chant/prose benchmarks. The flywheel now spans ~13,100 consented clips from ~1,500 users across 11 scripts.
Off-the-shelf Sanskrit ASR is trained on conversational IndicVoices-style data and degrades badly on recitation and śāstra — dense compounds, sandhi, retroflex/aspirate contrasts, pitch, and long metrical utterances. The goal here was a model and tooling good enough for scholars: accurate on chant and prose, and useful as a practice aid rather than a transcription toy.
Two things shaped everything:
lo..hi.Representative v5 numbers (held-out):
| domain | CER | WER | SN-WER |
|---|---|---|---|
| e-PG lecture (gold) | 3.6% | 13.0% | ~9–10% |
| Bhāgavata chant | 6.0% | 46.4% | ~22–26% |
| Vedānta prose | 7.3% | 30.8% | ~15–19% |
The gap between WER and SN-WER quantifies point (1): roughly half of Sanskrit "WER" is spacing.
EncDecHybridRNNTCTCBPEModel (IndicConformer, ~129 M params). We use the CTC
head on the Sanskrit token slice (cols = [BLANK] + range(4096,4352), re-log_softmax), greedy
decode.A compressed log of the campaign. Bold = shipped / kept.
| # | Experiment | Idea | Outcome |
|---|---|---|---|
| 1 | v5 finetune (CTC) | finetune IndicConformer on recitation+prose+TTS | shipped; chant CER 6.0% |
| 2 | SN-WER metric | strip sandhi/spacing before scoring | adopted; showed ½ of WER is spacing |
| 3 | v8 pseudo-labels | self-train on high-confidence v5 outputs | ✗ confidence doesn't separate right/wrong (wrong words median conf 0.93); label noise → no gain |
| 4 | Hard-negative annotation | pick hardest clips by v5-vs-Whisper disagreement for scholars to label | adopted for the annotation drive |
| 5 | Multi-scholar portal | concurrency-safe claim-queue annotation web tool | shipped; used to collect clean labels |
| 6 | SSL pretraining | wav2vec2-style contrastive on 38 h of Sanskrit śāstric audio; freeze frontend+lower layers | ✗ SSL-init finetune (v9b) < clean-label finetune (v9a) |
| 7 | Semi-supervised pseudo-labels | v5/v9 teacher → confidence-gated pseudo-labels | ✗ confirmed to hurt (3 independent tests) |
| 8 | v9 finetunes (v9a / v9-v2 / v9-v3) | add 846 clean scholar labels (47 speakers) + gold, honest held-out split | ✗ CER flat vs v5; gold WER worse (segmentation drift). First "−28%" was a favorable-split artifact |
| 9 | Rule-based sandhi segmenter | DP split of merged tokens to fix WER | ✗ over-shatters (Sanskrit tiles into everything); WER worse |
| 10 | ByT5-Sanskrit post-corrector | byte-level seq2seq to fix ASR output | ✗ over-corrects rare terms (prose CER 7→22); segmentation concept helped chant WER 46→42 only |
| 11 | Blank-penalty / r-recall sweep | penalize CTC blank to recover dropped onsets/repha | partial; diagnostic — CTC blank bias explains onset/short-phone deletions |
| 12 | Onset & CER-distribution analysis | per-position and per-clip error structure | diagnostic — first 2–3 words dropped (encoder ramp-up); e-PG tail is speaker-driven & bimodal |
| 13 | Baselines | Whisper-sa, wav2vec2 finetunes | v5 (IndicConformer-CTC) remained the best on chant/prose |
| 14 | GOP forced alignment | Goodness-of-Pronunciation for chant scoring | validated (AUC 0.97–0.99) but too false-positive-prone for a tutor → superseded |
| 15 | Vāgbodhinī chant tool | exploit the known reference text: verify, don't transcribe | shipped (see §6) |
| 16 | Consented data flywheel | collect real user audio + labels from the live tools, tiered by trust | shipped; grew to ~13.1k clips / ~1,500 users / 11 scripts |
| 17 | v10 flywheel retrain (wholesale) | finetune v5-recipe + flywheel from base, 20 ep | in-the-wild CER 24→16 (big), but gold regressed 3.6→6.1 (distribution shift) |
| 18 | v11 flywheel retrain (domain-balanced) | continue from v5, low LR, few epochs, flywheel upsampled | first balanced retrain; superseded by v12/v13b as the flywheel grew |
| 19 | v12 / v13 / v13b retrains | same balanced recipe on the grown flywheel; validated on a 327-clip leakage-free held-out | shipped as v13b-ep3 — in-the-wild CER 4.36 (beats v5 7.70 and v12-ep9 5.19); studio/chant/prose flat |
| 20 | Review-tier rescue audit | re-decode quarantined review clips with the current model; promote only perfect re-matches | only 4.3% recoverable → auto-grader validated: the pile is genuine reader deviations, not model error |
Once the live tools were public, every consented recording was logged with its label, tiered by
trustworthiness (pass ≥90% match · override/corrected = human-verified · review ·
low/unclear = archived). It has since grown to ~13,100 clips from ~1,500 users across 11
scripts (a third non-Devanāgarī), including ~420 human corrections.
We hold out flywheel data by session (no speaker leakage) as an in-the-wild eval set — the real deployment distribution — and retrain periodically.
v5 vs the deployed v13b-ep3 (CER / WER):
| eval set | v5 (studio-only) | v13b-ep3 (current, shipped) |
|---|---|---|
| gold — studio lecture † | 3.61 / 13.0 | 4.40 / 20.2 |
| Bhāgavata chant | 6.00 / 46.4 | 5.99 / 46.3 |
| Vedānta prose | 7.27 / 30.8 | 7.23 / 30.4 |
| in-the-wild (327-clip leakage-free held-out) | 7.70 / 45.4 | 4.36 / 30.4 |
† The gold studio set was transcribed by correcting v5's own drafts, so v5 is flattered there —
it is not a fair cross-model set. The unanchored comparisons are chant/prose (independent
forced-align references) and the in-the-wild held-out.
Findings:
review clip with the current
model recovered only 4.3% as model error — the other ~96% are genuine reader deviations, so
the tiering hides no reservoir of usable data. The next lever is new/diverse data, not more of
the same. Scripts: scripts/v11_prep.py, scripts/v13b_prep.py, scripts/rescue.py,
scripts/flywheel_clean.py, scripts/harvest_flywheel.py.The loop, closed and self-improving: better model → better live scoring → cleaner tiered data →
a better next model. Both tools feed one shared core ASR (ft_ctc_current), so they always update
together.
vagbodhini/ — a standalone web app.
See docs/ for the full system spec (services, ports, endpoints, data format).
The Sanskrit ASR weights (IndicConformer-CTC) are on Hugging Face:
prathoshap/sushrota-sanskrit-asr—sushrota_sanskrit_asr_v13b.nemois the deployed model (v13b-ep3: v5 continued on consented user data, §5b);sushrota_sanskrit_asr_v5.nemois the studio-only base. (See the model card for usage.)
The training data (17.4 h / 6,438 utterances + a 327-clip in-the-wild benchmark) is released as a dataset:
The metre-aware TTS for reference chants, Vāgdhenu, is separately at
prathoshap/vagdhenu.
vagbodhini/ the chant-practice app (FastAPI backend + single-file UI + TTS microservice)
scripts/ all experiment / training / evaluation / analysis scripts (§4)
docs/ system documentation
README.md this report
Notes:
If you use this work, please cite:
Prathosh A P, Su-śrotā: Scholar-grade Sanskrit ASR and metre-aware chant practice, Indian Institute of Science, Bengaluru, 2026.
Hacker News (1)
3 commits
Python
82.2%
HTML
15.0%
Shell
2.8%