CoolFace
Modelpublic

eulogik/polywhisper

sourceHugging Facemitupdated 6d agoView on Hugging Face
8likes402downloads
Model Card

![Model](https://huggingface.co/eulogik/polywhisper) ![GitHub](https://github.com/eulogik/PolyWhisper) ![Release](https://github.com/eulogik/PolyWhisper/releases) ![License](https://opensource.org/licenses/MIT) ![Python 3.9+](https://www.python.org/downloads/) ![PyTorch](https://pytorch.org/) ![ONNX](https://onnxruntime.ai/) Hindi Tamil Telugu Bengali Marathi

๐ŸŽ™๏ธ PolyWhisper v9 โ€” Efficient Multilingual Indic ASR

by Eulogik โ€” Frontier Edge AI ยท Vernacular Intelligence ยท eulogik.com
TL;DR: PolyWhisper v9 is a research-ready automatic speech recognition (ASR) system for Hindi, Tamil, Telugu, Bengali, and Marathi. It pairs a frozen OpenAI Whisper-Small backbone (244M params) with tiny per-language LoRA adapters (~14MB each). Bengali WER drops โˆ’28.2% and Marathi โˆ’79.6% versus the no-augmentation baseline โ€” at roughly 1% of the storage cost of full fine-tuning.

PolyWhisper architecture: frozen Whisper-Small backbone with swappable per-language LoRA adapters

โœจ Why PolyWhisper?

Full fine-tune (per language)**PolyWhisper v9**
Storage per language~1.5 GB~14 MB (100ร— smaller)
Backboneretrained each timefrozen once, shared by all 5
Bengali (bn) FLEURS WER181.3 (baseline)130.2 (โˆ’28.2%)
Marathi (mr) FLEURS WER474.9 (baseline)96.7 (โˆ’79.6%)
Telugu (te) FLEURS WER103.0 (baseline)100.1 (โˆ’2.8%)
Hindi (hi) FLEURS WER43.0 (baseline)46.3
Tamil (ta) FLEURS WER68.2 (baseline)70.1
CPU deploymentheavyONNX INT8, no GPU needed

WER = word error rate (lower is better). FLEURS test set, beam=1, punctuation-normalized scoring.

๐Ÿ“Š Benchmarks (FLEURS, beam=1, normalized WER)

LanguageCodeScriptv7 (no augment)**v9 final**ฮ” vs v7
HindihiDevanagari43.046.3+7.7%
TamiltaTamil68.270.1+2.8%
TeluguteTelugu103.0100.1โœ… โˆ’2.8%
BengalibnBengali181.3130.2โœ… โˆ’28.2%
MarathimrDevanagari474.996.7โœ… โˆ’79.6%

FLEURS WER by language for v7, v8, and v9 variants

๐Ÿงช The v9 finding: augment per language, not globally

Training with SpecAugment + speed perturbation on all languages damaged Hindi/Tamil (token-loop degeneration) while massively helping Bengali/Marathi. The v9 recipe augments only `bn`/`mr` and trains hi/ta/te clean:

LanguageAugmentationResult
Hindi, Tamil, Telugunone (clean)avoids global-augment damage; stays near the no-augment baseline
Bengali, MarathiSpecAugment + 0.9ร—/1.1ร— speed perturblarge gains on hard languages

Relative WER change from selective v9 versus global v8 augmentation

๐ŸŽฏ Decoding: per-language beam widths (measured, full FLEURS test)

Beam-5 + repetition penalty 1.3 helps every language except Telugu, where beam search collapses into repeated-token loops (0/472 perfect samples, 326/472 over 100% WER). The library/CLI defaults encode this (num_beams=None โ†’ per-language optimal):

Languagebeam-1beam-5 + rep 1.3Shipped default
Hindi46.345.0 (โˆ’2.8%)beam-5
Tamil70.168.6 (โˆ’2.2%)beam-5
Telugu100.1120.5 (+20.4% โš ๏ธ)beam-1
Bengali130.2126.4 (โˆ’2.9%)beam-5
Marathi96.791.5 (โˆ’5.4%)beam-5

๐Ÿ“ฆ Which adapter should I use?

LanguageAdapter fileBackboneWER
Hindi (hi)`polywhisper_output_hi/adapters_v3/hi_best_clean.pt`openai/whisper-small46.3
Tamil (ta)`polywhisper_output_ta/adapters_v3/ta_best_clean.pt`openai/whisper-small70.1
Telugu (te)`polywhisper_output_gpu0/adapters_v3/te_best_prod.pt`openai/whisper-small100.1
Bengali (bn)`polywhisper_output_gpu0/adapters_v3/bn_best_prod.pt`openai/whisper-small130.2
Marathi (mr)`polywhisper_output_gpu1/adapters_v3/mr_best_prod.pt`openai/whisper-small96.7

All adapters are rank-16 LoRA (decoder + encoder attention), ~14MB each. Backbone weights are not included โ€” they load from openai/whisper-small at runtime. The _prod suffix is the v9 production-run tag, not an augmentation marker: Telugu was trained clean in the selective v9 recipe.

๐Ÿš€ Quickstart

bash
pip install -e .
bash
# Hindi speech to text
polywhisper transcribe audio.wav --lang hi

# Tamil with JSON output
polywhisper transcribe audio.wav --lang ta --format json

# Auto-detect language, SRT subtitles
polywhisper transcribe audio.wav --format srt > subs.srt

# Batch a folder
polywhisper batch ./audio_folder/ --lang bn --output results.json
python
from polywhisper import transcribe

result = transcribe("audio.wav", lang="mr")
print(result.text)
print(result.segments)  # timestamped segments

๐Ÿ–ฅ๏ธ CPU-only inference (ONNX Runtime)

Export INT8-quantized ONNX graphs (no PyTorch, no GPU needed at inference):

bash
polywhisper export --lang hi --variant prod --int8

Pre-exported v9 graphs live under export/onnx/ on the Hub โ€” per language, fp32 + INT8:

LangEncoder (fp32 / INT8)Decoder (fp32 / INT8)
hi358MB / 97MB784MB / 204MB
ta358MB / 97MB784MB / 204MB
te358MB / 97MB784MB / 204MB
bn358MB / 97MB784MB / 204MB
mr358MB / 97MB784MB / 204MB

Files are named {lang}_{lang}_best_prod_{encoder,decoder}{,_int8}.onnx. INT8 is ~4ร— smaller.

ONNX encoder/decoder sizes for fp32 versus INT8

Verification: fp32 ONNX vs PyTorch max diff < 1e-3 on all five languages (encoder + decoder). End-to-end greedy spot-checks (FLEURS audio, beam=1):

Langtorch WERONNX INT8 WER
hi (10 samples)43.4%48.3%
ta (5 samples)100.0%100.0%
te (5 samples)100.0%101.6%
bn (5 samples)104.9%118.7%
mr (5 samples)82.9%89.4%

Spot-checks are tiny (5โ€“10 utterances) so single-sentence flips move the numbers; fp32 ONNX is at parity with torch. INT8 trades a few points for 4ร— smaller files.

๐Ÿ‹๏ธ Training recipe (reproducible)

  • โ€”Data: IndicVoices-ST (~19โ€“20k clips/language) ยท Eval: FLEURS
  • โ€”Backbone: openai/whisper-small, frozen ยท Adapters: LoRA rank-16, encoder + decoder attention
  • โ€”Schedule: 3โ€“5 epochs/language, batch 4, AdamW, cosine LR (peak 1e-4), 2ร— NVIDIA T4
  • โ€”Augmentation (v9): SpecAugment + speed perturb for bn/mr only; hi/ta/te clean
  • โ€”Selection: WER-gated checkpoints (*_best_*.pt) on FLEURS dev slices
  • โ€”Code: `train_v3.py` ยท orchestrator `kaggle_train_resumable.py` ยท scoring `normalize_ortho.py`

โ“ FAQ

What is PolyWhisper? PolyWhisper is an open-source Indic ASR toolkit: one frozen Whisper-Small backbone plus five small per-language LoRA adapters covering Hindi, Tamil, Telugu, Bengali, and Marathi.

How is it different from fine-tuning Whisper? Full fine-tuning rewrites ~244Mโ€“1.5B weights per language. PolyWhisper freezes the backbone and trains ~3.5M LoRA parameters per language (~14MB), so five languages ship for the storage cost of a rounding error.

Which languages are usable? All five ship working adapters. Hindi (46.3 WER) and Tamil (70.1) are strongest; Telugu, Bengali, and Marathi remain high-WER research adapters, useful for assistive/search/subtitle-draft workflows rather than verbatim transcription.

Can I run it on CPU? Yes โ€” export to ONNX INT8 and run with ONNX Runtime, no GPU required.

Can I run it on a Mac? Yes โ€” PyTorch MPS is supported (Device: mps), plus CPU via ONNX.

What data was it trained/evaluated on? Trained on IndicVoices-ST conversational speech, evaluated on FLEURS read speech with punctuation-normalized, script-aware scoring.

โš ๏ธ Limitations

  • โ€”Absolute WER on Telugu/Bengali/Marathi is still high โ€” usable for assistive/search/subtitle-draft workflows, not verbatim legal/medical transcription.
  • โ€”Evaluated on read speech (FLEURS); spontaneous conversational accuracy will differ.
  • โ€”Beam=1 numbers in the benchmark table above (paper parity); shipped defaults use beam-5 + repetition penalty 1.3 except Telugu (beam-1), see decoding table.

๐Ÿ“„ License & citation

MIT. Whisper weights ยฉ OpenAI. Training data: IndicVoices-ST (CC-BY) ยท Eval: FLEURS (CC-BY).

bibtex
@misc{polywhisper2026,
  title  = {PolyWhisper: Efficient Multilingual Indic ASR via Frozen Backbone and Per-Language LoRA Adapters},
  author = {Kishore, Gautam},
  year   = {2026},
  publisher = {HuggingFace},
  url    = {https://huggingface.co/eulogik/polywhisper}
}

๐Ÿ”— Links