GautamKishore commited on
Commit
05b64d2
·
verified ·
1 Parent(s): 50e0acc

Initial: 5-language Indic experts + Hinglish router + all eval JSONs

Browse files
README.md ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ - hi
5
+ - ta
6
+ - te
7
+ - bn
8
+ - mr
9
+ license: mit
10
+ library_name: pytorch
11
+ pipeline_tag: automatic-speech-recognition
12
+ tags:
13
+ - whisper
14
+ - lora
15
+ - mixture-of-experts
16
+ - asr
17
+ - speech-recognition
18
+ - indic
19
+ - tamil
20
+ - telugu
21
+ - bengali
22
+ - marathi
23
+ - hindi
24
+ - hinglish
25
+ - code-switching
26
+ - low-resource
27
+ - edge-asr
28
+ - devanagari
29
+ metrics:
30
+ - wer
31
+ - cer
32
+ - fuzzy-wer
33
+ model-index:
34
+ - name: polywhisper-hinglish-router
35
+ results:
36
+ - task:
37
+ type: automatic-speech-recognition
38
+ name: Speech Recognition
39
+ dataset:
40
+ name: PolyWhisper Hinglish Test (3,129 utterances)
41
+ type: eulogik/polywhisper-hinglish
42
+ split: test
43
+ metrics:
44
+ - type: wer
45
+ value: 58.8
46
+ name: WER
47
+ - type: cer
48
+ value: 57.9
49
+ name: CER
50
+ - name: polywhisper-indic-experts
51
+ results:
52
+ - task:
53
+ type: automatic-speech-recognition
54
+ name: Speech Recognition
55
+ dataset:
56
+ name: FLEURS (hi/ta/te/bn/mr)
57
+ type: google/fleurs
58
+ metrics:
59
+ - type: wer
60
+ value: 38.5
61
+ name: WER (hi)
62
+ - type: cer
63
+ value: 14.4
64
+ name: CER (hi)
65
+ - type: wer
66
+ value: 73.9
67
+ name: WER (ta)
68
+ - type: cer
69
+ value: 25.6
70
+ name: CER (ta)
71
+ - type: wer
72
+ value: 82.7
73
+ name: WER (te)
74
+ - type: cer
75
+ value: 32.7
76
+ name: CER (te)
77
+ - type: wer
78
+ value: 84.9
79
+ name: WER (bn)
80
+ - type: cer
81
+ value: 54.3
82
+ name: CER (bn)
83
+ - type: wer
84
+ value: 65.0
85
+ name: WER (mr)
86
+ - type: cer
87
+ value: 22.9
88
+ name: CER (mr)
89
+ ---
90
+ # PolyWhisper: Per-Language LoRA Experts on Shared Whisper-Base
91
+
92
+ **5 languages · 6 experts · 1 frozen 74M encoder · 0 encoder retraining**
93
+
94
+ PolyWhisper is a family of tiny language-specific LoRA experts on a frozen Whisper-Base encoder. It tackles a problem vanilla Whisper-Base cannot even begin to solve: **producing correct-script text for Indian languages**.
95
+
96
+ ## The script-confusion finding
97
+
98
+ Vanilla Whisper-Base doesn't just perform worse on Indic languages — it emits the **wrong script entirely** (Urdu-Arabic for Telugu/Bengali/Marathi, 0–0.5% correct-script rate). The same encoder produces near-perfect Devanagari for Hindi but collapses to Arabic for the other Indic scripts.
99
+
100
+ Per-language LoRA experts on the shared frozen encoder fix this completely.
101
+
102
+ ## Architecture
103
+
104
+ ```
105
+ Audio (16kHz) → Whisper-Base Encoder [frozen, 74M]
106
+ ↓
107
+ Per-language LoRA adapter [rank-16, ~0.8M each]
108
+ ↓
109
+ Transcription (correct-script, correct language)
110
+ ```
111
+
112
+ - **Backbone**: openai/whisper-base — frozen encoder + frozen base decoder
113
+ - **Experts**: rank-16 LoRA on decoder cross-attention K/V projections
114
+ - **Router (Hinglish only)**: 33K-param MLP on decoder hidden states, per-token en/hi selection
115
+
116
+ ## Results
117
+
118
+ ### Hinglish code-switch (v5 router, 3,129 utterances)
119
+
120
+ | System | WER | FuzzyWER | CER | Hallucinations |
121
+ |---|---|---|---|---|
122
+ | **PolyWhisper v5** | **58.8%** | **57.3%** | **57.9%** | **13** |
123
+ | Vanilla Whisper-Base | 66.6% | 63.3% | 67.5% | 279 |
124
+ | Static 50/50 mix | 72.1% | 70.4% | 71.1% | 655 |
125
+
126
+ ### Indic experts (FLEURS, ortho-normalized, script-matched, 256 decode tokens)
127
+
128
+ | Lang | Vanilla script-match | Expert script-match | Pure expert WER/CER |
129
+ |---|---|---|---|
130
+ | **Hindi** | 6.2% | **99.8%** | **38.5 / 14.4** |
131
+ | **Tamil** | 96.4% | **99.3%** | 73.9 / 25.6 |
132
+ | **Telugu** | 0.0% | **92.6%** | 82.7 / 32.7 |
133
+ | **Bengali** | 0.0% | **77.1%** | 84.9 / 54.3 |
134
+ | **Marathi** | 0.5% | **99.8%** | 65.0 / 22.9 |
135
+
136
+ Vanilla scores for te/bn/mr are unreportable (0–0.5% correct-script output). Experts restore correct-script and cut CER 10–22 points. Residual WER is the 39M-parameter ceiling.
137
+
138
+ ## Files
139
+
140
+ ### Hinglish router
141
+ | File | What |
142
+ |---|---|
143
+ | `en_router_best_v5.pt` | English LoRA expert (rank-8 decoder) |
144
+ | `hi_router_best_v5.pt` | Hindi LoRA expert with encoder LoRA |
145
+ | `router_best_v5.pt` | Per-token router (33K params) |
146
+ | `hi_best_v5.pt` | Hindi pure expert (encoder + decoder LoRA) |
147
+
148
+ ### Indic experts
149
+ | File | What |
150
+ |---|---|
151
+ | `ta_best_ta.pt` | Tamil expert (rank-16 decoder) |
152
+ | `te_best_te_v2.pt` | Telugu expert (rank-16 decoder) |
153
+ | `bn_best_bn_v2.pt` | Bengali expert (rank-16 decoder) |
154
+ | `mr_best_mr.pt` | Marathi expert (rank-16 decoder) |
155
+
156
+ ### Evaluation
157
+ | File | What |
158
+ |---|---|
159
+ | `fleurs_normalized_results.json` | Ortho-normalized scores for all 5 languages |
160
+ | `eval_*_fleurs.json` | Per-sample results (rescorable) |
161
+ | `eval_*_samples.json` | Per-sample Hinglish results |
162
+
163
+ ## Usage (Indic expert example)
164
+
165
+ ```python
166
+ import torch
167
+ from transformers import WhisperProcessor, WhisperForConditionalGeneration
168
+ from peft import PeftModel
169
+
170
+ proc = WhisperProcessor.from_pretrained("openai/whisper-base")
171
+ model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-base")
172
+ model = PeftModel.from_pretrained(model, "eulogik/polywhisper", "ta_best_ta.pt")
173
+ model.eval()
174
+
175
+ audio = ... # 16kHz mono
176
+ feats = proc.feature_extractor([audio], sampling_rate=16000, return_tensors="pt").input_features
177
+ out = model.generate(feats, max_new_tokens=256, language="ta", task="transcribe")
178
+ print(proc.decode(out[0], skip_special_tokens=True))
179
+ ```
180
+
181
+ ## Training
182
+
183
+ - 3 epochs, LR 1e-4, rank-16 LoRA on decoder cross-attention K/V
184
+ - Data: IndicVoices-ST (~19–20K samples, gated) + FLEURS (test)
185
+ - Trained on M4 Mac Mini 16GB (Apple MPS, fp16)
186
+ - Training time: ~3h per language, fully automated (`train_v3.py --langs ta`)
187
+
188
+ ## Key finding for the paper
189
+
190
+ > Language-specific LoRA experts on a shared frozen encoder fix Whisper-Base's script-confusion problem for 5 Indian languages. Vanilla outputs Urdu-Arabic for Telugu/Bengali/Marathi (0% correct-script); experts restore 77–100% correct-script output. Hindi expert reaches 38.5% WER / 14.4% CER — near-usable for edge deployment.
191
+
192
+ ## License
193
+
194
+ MIT. © 2026 [Eulogik](https://huggingface.co/eulogik). Whisper is OpenAI's model. Data from IndicVoices-ST (CC-BY) and FLEURS (CC-BY 4.0).
195
+
196
+ ## Citation
197
+
198
+ ```bibtex
199
+ @misc{eulogik2026polywhisper,
200
+ title={PolyWhisper: Per-Language LoRA Experts on Shared Encoder for Indic ASR},
201
+ author={Eulogik},
202
+ year={2026},
203
+ howpublished={\url{https://huggingface.co/eulogik/polywhisper}},
204
+ note={MIT licensed; 5 Indian languages + Hinglish router; script-confusion fix}
205
+ }
206
+ ```
bn_best_bn_v2.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:94f32fed12f63ca9230edbd63729f1332e43dd2f1626a217a884508132c232b8
3
+ size 3178791
en_router_best_v5.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e88c782489a10da76e84720d2fd94c708089df3d5ec0fbffd8ee7f27d55f5730
3
+ size 3179071
eval_bn_pure_fleurs.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_hi_fleurs_samples.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_hi_pure_fleurs.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_mr_pure_fleurs.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_ta_pure_fleurs.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_te_pure_fleurs.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_vanilla_fleurs_bn.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_vanilla_fleurs_hi.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_vanilla_fleurs_mr.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_vanilla_fleurs_ta.json ADDED
The diff for this file is too large to render. See raw diff
 
eval_vanilla_fleurs_te.json ADDED
The diff for this file is too large to render. See raw diff
 
fleurs_normalized_results.json ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "ta": {
3
+ "vanilla": {
4
+ "all": {
5
+ "wer": 93.20948782535685,
6
+ "cer": 46.48130767568969
7
+ },
8
+ "script_matched": {
9
+ "rate": 96.3917525773196,
10
+ "wer": 92.00955379437629,
11
+ "cer": 41.65171562696076
12
+ },
13
+ "n": 582
14
+ },
15
+ "pure": {
16
+ "all": {
17
+ "wer": 74.16036943744753,
18
+ "cer": 26.146075460249495
19
+ },
20
+ "script_matched": {
21
+ "rate": 99.3127147766323,
22
+ "wer": 73.88508170795994,
23
+ "cer": 25.598507020546815
24
+ },
25
+ "n": 582
26
+ }
27
+ },
28
+ "te": {
29
+ "vanilla": {
30
+ "all": {
31
+ "wer": 185.61696658097685,
32
+ "cer": 170.5974629262082
33
+ },
34
+ "script_matched": {
35
+ "rate": 0.0,
36
+ "wer": 0.0,
37
+ "cer": 0.0
38
+ },
39
+ "n": 471
40
+ },
41
+ "pure": {
42
+ "all": {
43
+ "wer": 91.9280205655527,
44
+ "cer": 50.20875638661091
45
+ },
46
+ "script_matched": {
47
+ "rate": 92.56900212314225,
48
+ "wer": 82.74667405764967,
49
+ "cer": 32.72036968104166
50
+ },
51
+ "n": 471
52
+ }
53
+ },
54
+ "bn": {
55
+ "vanilla": {
56
+ "all": {
57
+ "wer": 125.41732100273367,
58
+ "cer": 145.39656266314955
59
+ },
60
+ "script_matched": {
61
+ "rate": 0.0,
62
+ "wer": 0.0,
63
+ "cer": 0.0
64
+ },
65
+ "n": 911
66
+ },
67
+ "pure": {
68
+ "all": {
69
+ "wer": 120.51997906124586,
70
+ "cer": 117.36404670352854
71
+ },
72
+ "script_matched": {
73
+ "rate": 77.05817782656422,
74
+ "wer": 84.85533453887884,
75
+ "cer": 54.268561394499855
76
+ },
77
+ "n": 911
78
+ }
79
+ },
80
+ "mr": {
81
+ "vanilla": {
82
+ "all": {
83
+ "wer": 130.37789176175025,
84
+ "cer": 137.41115173742747
85
+ },
86
+ "script_matched": {
87
+ "rate": 0.4975124378109453,
88
+ "wer": 241.11111111111111,
89
+ "cer": 133.23201308495427
90
+ },
91
+ "n": 1005
92
+ },
93
+ "pure": {
94
+ "all": {
95
+ "wer": 65.03192714330577,
96
+ "cer": 23.032706462021498
97
+ },
98
+ "script_matched": {
99
+ "rate": 99.80099502487562,
100
+ "wer": 64.94017632241814,
101
+ "cer": 22.883513931066016
102
+ },
103
+ "n": 1005
104
+ }
105
+ },
106
+ "hi": {
107
+ "vanilla": {
108
+ "all": {
109
+ "wer": 131.34519013461727,
110
+ "cer": 136.89706229908396
111
+ },
112
+ "script_matched": {
113
+ "rate": 6.235011990407674,
114
+ "wer": 118.4251968503937,
115
+ "cer": 87.55990110426639
116
+ },
117
+ "n": 417
118
+ },
119
+ "pure": {
120
+ "all": {
121
+ "wer": 38.61648815957551,
122
+ "cer": 14.58012380835516
123
+ },
124
+ "script_matched": {
125
+ "rate": 99.76019184652279,
126
+ "wer": 38.53869603697512,
127
+ "cer": 14.400916330051668
128
+ },
129
+ "n": 417
130
+ }
131
+ }
132
+ }
hi_best_v5.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ce81d66e3fcafe9d3b2404a7921c4cc2edc2813068e5d9ecf18633936c09e8b6
3
+ size 4767393
hi_router_best_v5.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3b911b7b1319b846a597566d918700e52445a6f5212aaa2e482927e56620e586
3
+ size 3179071
mr_best_mr.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:898edd58ba72981045c4ea8723b31f62ec7feaefb3c6eaa5e1a6a566adc8304b
3
+ size 3178485
router_best_v5.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:fd7194d4fe37637538127c03d6fbadf4581041b39dc40bf052a2616df0985ec7
3
+ size 134371
ta_best_ta.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5f0dab8e69b12e02b9cef06a1196bedc604f764a983b4c51ab9dc8e7ef450b2f
3
+ size 3178485
te_best_te_v2.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:999b7376829a217671b3b736b7cdd75f11f95d0b62f2254e842092c6fec2f732
3
+ size 3178791