Paper/

Sota

Khmer and English speech recognition, pruned to a fifth of its size

One imaginary flowering herb, painted in ink on paper

Generated with Nonflowers by Lingdong Huang · MIT

Parameters
73M / 204M
CER
1.77%
License
Apache-2.0

Khmer is the national language of Cambodia, and it is spoken alongside English in much of daily life. Meta's Omnilingual ASR recognises speech in more than 1,600 languages, Khmer among them, and its 1B-parameter model is a strong starting point. But a model that has to cover 1,600 languages carries far more capacity than two languages need, and running it costs memory and time.

Sota (សោត, "the ear") keeps what Khmer and English need and removes the rest. We fine-tune Omnilingual ASR on the two languages, then let the model learn which of its attention heads and feed-forward units it can do without, and cut 80% of its encoder away. The result is two compact speech recognisers: sota-large, with 204M parameters, and sota-base, with 73M.

In brief:

  • Accuracy. On the DDD Khmer test set, sota-large gets 1.77% of characters wrong, against 2.47% for the 975M-parameter model it was pruned from. sota-base gets 2.60%, against 3.68% for its 325M-parameter teacher.
  • Size and speed. sota-large needs 12.3 GMAC per second of audio, against its teacher's 50.3, and runs 2.5 times faster on the test sets. sota-base needs 5.8 GMAC/s and runs 1.8 times faster.
  • Two languages. Both models transcribe Khmer and English. English is the weaker side: pruning costs it more, and on LibriSpeech test-clean the pruned models make 1.7–1.9 times as many word errors as their teachers.

The code, the training recipe and both models are open source under the Apache 2.0 licence.

Architecture#

Diagram of pruning. Left: the encoder of the fine-tuned omniASR CTC-1B, 975M parameters, with its CNN blocks, attention heads and FFN units; at layers 12 and 40 some heads and FFN units are marked as pruned. An arrow labelled Pruning, 80% of encoder weights removed, leads to the right: sota-large, 204M parameters, with the same CNN blocks and fewer heads and FFN units in each layer.
Figure 1 — Structured pruning removes whole attention heads (MHA) and FFN units from every transformer layer, each chosen by its own gate; the CNN front end is kept. Each cell stands for a quarter of a layer's heads or FFN units. Layer 12 of sota-large keeps 8 of 16 heads and 3,355 of 5,120 FFN units, and layer 40 keeps no heads and 228 FFN units.

Base model#

Sota starts from the CTC models of Meta's Omnilingual ASR: omniASR_CTC_1B for sota-large and omniASR_CTC_300M for sota-base. Both are wav2vec 2.0 encoders, pre-trained on unlabelled audio and then fine-tuned to transcribe:

  • a 7-layer convolutional feature extractor that turns the waveform into one frame every 20 ms;
  • a convolutional position encoder;
  • pre-LayerNorm transformer layers, 48 at width 1,280 in the 1B and 24 at width 1,024 in the 300M;
  • a linear CTC head over Omnilingual's 9,812-character vocabulary, which predicts every output position at once in a single pass.

wav2vec 2.0 learns from audio with no transcripts. Spans of the latent frames are masked, and at each masked frame the transformer's output has to pick out the true frame, in a quantized form, from distractors. To do that, it has to learn what speech around a gap sounds like.

XConvolutional feature encoderZTransformermasked frames are hidden from itCQuantizationtargets QContrastive lossat each masked frame, pick the true q from distractors
Figure 2 — wav2vec 2.0 pre-training. The convolutional encoder turns audio X into latent frames Z, and the transformer turns them into context C. Yellow marks the masked frames: the transformer can't see them, and the contrastive loss asks C at each one to identify its quantized target Q. For fine-tuning, the quantizer and the loss are dropped and a CTC head reads C.

Structured pruning#

Removing single weights makes a model sparse without making it faster, because the matrix multiplications keep their shapes. Sota removes whole structures instead: attention heads, and units of the feed-forward network (FFN). Dropping a head or an FFN unit shrinks the matrices themselves, so the smaller model runs faster on ordinary hardware. The model dimension, the convolutional front end and the CTC head are left intact.

To decide what to remove, every head and every FFN unit gets a learned gate zz, after the L0 relaxation of Louizos et al. (2018). A Hard Concrete gate is sampled in each forward pass:

s=σ ⁣(log⁡u−log⁡(1−u)+log⁡αβ),z=min⁡ ⁣(1,max⁡(0,  s(ζ−γ)+γ))s = \sigma\!\left(\frac{\log u - \log(1-u) + \log\alpha}{\beta}\right), \qquad z = \min\!\big(1, \max(0,\; s(\zeta - \gamma) + \gamma)\big)

Here uu is drawn uniformly from (0,1)(0, 1), log⁡α\log\alpha is the gate's learned parameter, β\beta is a temperature, and γ<0\gamma < 0 and ζ>1\zeta > 1 stretch ss so that the clipped zz is exactly 0 or exactly 1 with non-zero probability. The output of each head or unit is multiplied by its zz. The gates can be trained by gradient descent, and the expected number of open gates is a smooth function of log⁡α\log\alpha.

Sparsity constraint#

The expected share of the encoder that the gates remove, ρ\rho, is pushed towards a target tt by an augmented Lagrangian term added to the loss:

λ1(ρ−t)+λ2(ρ−t)2\lambda_1 (\rho - t) + \lambda_2 (\rho - t)^2

The multipliers λ1\lambda_1 and λ2\lambda_2 are trained by gradient ascent, so the penalty grows for as long as ρ\rho misses tt. The target tt ramps linearly from 0 to 80% over the first quarter of the pruning run and then holds, which lets the model give up units gradually.

Distillation#

While the gates learn, the pruned model is taught to match the fine-tuned model it started from, which is kept frozen as a teacher. The loss compares the two models' hidden states at five layers:

Ldistil=∑k∈K[L1⁡(hk,hkT)−cos⁡(hk,hkT)]\mathcal{L}_{\text{distil}} = \sum_{k \in K} \Big[\operatorname{L1}\big(h_k, h_k^{T}\big) - \cos\big(h_k, h_k^{T}\big)\Big]

Here hkh_k and hkTh_k^{T} are the student's and the teacher's hidden states after layer kk, L1⁡\operatorname{L1} is their mean absolute difference and cos⁡\cos their cosine similarity. KK is layers 0, 12, 24, 36 and 48 in the 1B and 0, 6, 12, 18 and 24 in the 300M. The last target is taken after the final LayerNorm, where the CTC head reads, because the raw residual stream of a pre-LayerNorm model has an arbitrary scale at the top.

The recipe follows Fine-tune Before Structured Pruning (Han et al., 2025), which pruned WavLM for speaker diarization and itself builds on DPHuBERT. Its key step is the first one: fine-tune the full model on the target task before pruning, so that the teacher, and the starting point, already know the task.

Training runs in five steps.

  1. 1. Fine-tune

    omniASR 1BCTC headfrozen copyTeacherCTC headCTC on transcripts
  2. 2. Prune

    Teacher, frozenCTC headmatch hiddenstatesStudent + gatesCTC headsparsity → 80%
  3. 3. Cut

    Student, 975MCTC headdelete closedStudent, 204MCTC head
  4. 4. Distil

    Teacher, frozenCTC headmatch hiddenstatesStudent, 204MCTC head
  5. 5. Recover

    Teacher, frozenCTC headKL on outputssota-largeCTC head+ CTC on transcripts
Figure 3 — The five training steps for sota-large, with each model drawn in the cells of Figure 1: the maroon CNN front end, four rows standing for the encoder's four blocks of 12 layers, each with orange attention heads and yellow FFN units, and the CTC head. Dashed arrows show what the student learns from the frozen teacher: its hidden states at the end of each block in steps 2 and 4, and its output distribution in step 5. Pale, dashed cells are heads and units whose gates are closing; the cut deletes them, so each layer ends up with its own width, while the CNN and the CTC head keep theirs.
  1. Fine-tune. The full model is trained with CTC on Khmer and English. It becomes both the starting point for pruning and the frozen teacher.
  2. Prune. The gates and the model train together, under the distillation loss and the sparsity constraint, until 80% of the encoder is gated off.
  3. Cut. The gates are fixed and folded into the weights, and the closed heads and units are deleted. Each layer now has its own width.
  4. Distil with the mask frozen. The smaller model keeps learning to match the teacher's hidden states, with nothing left to prune.
  5. Recover. The model is trained with CTC again, plus a frame-level KL divergence to the teacher's output distribution.

Pruning costs accuracy, and the last two steps win it back. On the DDD dev set, sota-large's error rate goes from 3.40% after fine-tuning to 7.06% after pruning, 5.60% after distillation and 2.40% after recovery, below the teacher's. English recovers less: on LibriSpeech dev-clean the same steps take it from 3.95% to 12.97%, 8.46% and 6.60%.

Data#

Sota was trained on about 1,537 hours of speech, mixed 50/50 between Khmer and English by audio seconds.

DatasetLanguageTypeSizeLicence
DDD Khmer SpeechKhmerNative speakers, 61 cultural topics1,058 hCC BY-SA 4.0
FLEURS km_kh trainKhmerRead Wikipedia sentences7.1 hCC BY 4.0
LibriSpeech train-clean-100 + 360EnglishAudiobooks464 hCC BY 4.0
FLEURS en_us trainEnglishRead Wikipedia sentences7.5 hCC BY 4.0

FLEURS share. At its natural share FLEURS would be only 1–2% of the audio. In early tests, FLEURS-km dev error rose from 10.7% to 13.1% in the first thousand steps of fine-tuning, as the model drifted towards DDD's style. We therefore fix FLEURS at 20% of each language's audio and repeat its clips as needed.

Preprocessing.

  • The DDD test set, a DDD dev pool and an exclude list are removed from the training data.
  • Utterances shorter than 1 s or longer than 25 s are dropped, and all audio is resampled to 16 kHz mono.
  • Text is normalised to NFC, zero-width characters are removed and whitespace is collapsed. English is lowercased.
  • Text is filtered to the Omnilingual character vocabulary, which has no Khmer punctuation such as ។. This drops 1.2% of DDD characters.
  • Each utterance is normalised to zero mean and unit variance, as in Omnilingual ASR.

Training#

Both sizes use the same five steps and the same schedule.

sota-basesota-large
Pruned fromomniASR CTC-300MomniASR CTC-1B
Encoder layers × model width24 × 1,02448 × 1,280
Attention heads kept98 of 384203 of 768
FFN units kept11,663 of 98,30434,939 of 245,760
Steps: fine-tune / prune / distil / recover6k / 12k / 5k / 16k6k / 12k / 5k / 16k
Compute (GMAC per second of audio)5.812.3
Parameters73M204M

Fine-tuning uses a learning rate of 10⁻⁵ for the encoder and 10⁻⁴ for the CTC head. Pruning uses 2 × 10⁻⁴ for the model and 2 × 10⁻² for the gates and the multipliers, and recovery 5 × 10⁻⁵. Batches are filled by audio length, up to 160 seconds of audio each. To fit the 1B model's training in GPU memory, its fp32 master weights and AdamW moments are kept in CPU memory while the GPU computes in bf16. The full configuration is in training/configs/.

Results#

We measure character error rate (CER) on Khmer and word error rate (WER) on English: the share of characters, or words, that are substituted, dropped or inserted, against the reference. Khmer is written without spaces between words, so where one word ends and the next begins is a choice made by a segmenter, and word error rate would depend on that choice. All scores use greedy CTC decoding with no language model, on the full test sets: 1,993 utterances of DDD, 771 of FLEURS-km, 647 of FLEURS-en, 2,620 of LibriSpeech test-clean and 2,939 of test-other.

DDD (CER)1.77 (best in this row)2.47 (second best in this row)5.95
FLEURS-km (CER)11.409.44 (best in this row)11.26 (second best in this row)
FLEURS-en (WER)19.2511.94 (best in this row)12.38 (second best in this row)
LibriSpeech test-clean (WER)6.073.61 (best in this row)4.40 (second best in this row)
LibriSpeech test-other (WER)16.738.21 (best in this row)8.87 (second best in this row)
GMAC per second of audio12.3 (best in this row)50.3 (second best in this row)50.3 (second best in this row)
Table 1 — sota-large against the stock omniASR CTC-1B and our fine-tuned 1B, the teacher it was pruned from. Error rates in %, CER for Khmer and WER for English. Lower is better throughout. The best score in each row is bold and the second best is in italics. FLEURS train is in the training mix, so both FLEURS test sets are in-domain.
DDD (CER)2.60 (best in this row)3.68 (second best in this row)9.65
FLEURS-km (CER)16.3912.64 (best in this row)16.26 (second best in this row)
FLEURS-en (WER)30.24 (second best in this row)19.51 (best in this row)–
LibriSpeech test-clean (WER)11.155.89 (best in this row)6.53 (second best in this row)
LibriSpeech test-other (WER)27.3613.86 (best in this row)14.45 (second best in this row)
GMAC per second of audio5.8 (best in this row)18.3 (second best in this row)18.3 (second best in this row)
Table 2 — sota-base against the stock omniASR CTC-300M and our fine-tuned 300M, its teacher. Error rates in %, lower is better. The best score in each row is bold and the second best is in italics. The stock 300M was not scored on FLEURS-en.

On DDD, both pruned models beat both larger models. sota-large's error rate is 0.7 points below its teacher's and less than a third of the stock 1B's. DDD is 80% of the Khmer training audio, so it is also the set the models know best.

On FLEURS-km, pruning gives back what fine-tuning gained. The pruned models end close to the stock models, 0.1 points behind them, and 2–4 points behind their teachers.

English pays the most. On LibriSpeech test-clean the pruned models make 1.7–1.9 times as many word errors as their teachers, and on FLEURS-en 1.5–1.6 times as many. The capacity that survives the cut is spent mostly on Khmer.

Base: 325M → 73M249 ms153 ms (best in this row)1.6×
Large: 975M → 204M543 ms245 ms (best in this row)2.2×
Table 3 — Time to transcribe one 60-second utterance, at batch size 1 in bf16, median of 20 runs on one machine. Lower is better.

Speed. A fifth of the parameters does not give five times the speed: on a single long utterance the pruned models are 1.6× and 2.2× faster. Measured as the real-time factor over the batched test sets, the speed-ups are 1.8× for sota-base and 2.5× for sota-large.

Ablation#

To see which parts of the recipe matter, we trained sota-large four times, adding one change at a time. Each run keeps everything from the one before it:

  1. Prune the stock model. Skip fine-tuning: prune Omnilingual's 1B as released, with the stock model as the teacher and no FLEURS in the data. Recover with CTC alone for 8,000 steps.
  2. + Fine-tune first. Fine-tune the 1B on Khmer and English before pruning, and use that fine-tuned model as the teacher. FLEURS joins the data at the same time.
  3. + Output distillation. During recovery, also match the teacher's output distribution, not just the transcripts.
  4. + Longer recovery. Recover for 16,000 steps instead of 8,000. This is the released sota-large.
DDD (CER)2.202.142.09 (second best in this row)1.77 (best in this row)
FLEURS-km (CER)16.3612.5111.90 (second best in this row)11.40 (best in this row)
FLEURS-en (WER)28.0721.1619.62 (second best in this row)19.25 (best in this row)
LibriSpeech test-clean (WER)6.567.076.47 (second best in this row)6.07 (best in this row)
LibriSpeech test-other (WER)18.2618.5117.42 (second best in this row)16.73 (best in this row)
Table 4 — sota-large trained four ways, each column adding one change to the one before it. Error rates in %, lower is better. The best score in each row is bold and the second best is in italics.

Fine-tuning first matters most for the sets that are not DDD. Pruning the stock model already gives a good DDD score, 2.20%, but FLEURS is far worse: 16.36% on Khmer against 12.51% when we fine-tune first, and 28.07% on English against 21.16%. This step changes two things at once, the teacher and FLEURS in the data, and we haven't separated their effects.

Output distillation improves every test set. With transcripts alone, LibriSpeech error crept upwards as recovery went on. Also matching the teacher's outputs stopped that drift, because the teacher still knows the English the small model is losing.

Longer recovery helps again on every set, most of all on DDD, which falls from 2.09% to 1.77%. The smaller sota-base was still improving when its recovery ended, so longer runs may help further.

What pruning keeps#

The gates do not prune every layer evenly. Figure 4 shows what each of sota-large's 48 layers kept.

sota-large: attention heads and FFN units kept in each encoder layer. Layers 12, 24, 36 and 48 are matched to the teacher.
LayerHeads kept (of 16)FFN units kept (of 5,120)
17924
24548
35500
46469
55486
65437
76517
89647
97940
1061414
1192272
1283355
133146
140196
153341
165468
172522
185555
199647
208885
2191270
2261265
2351972
24103081
25187
264134
272190
284333
297267
306419
312392
323416
336774
3471033
3551244
36102685
37281
38069
39080
400228
410351
420477
430541
440347
450228
460170
470256
482280
Figure 4 — What each encoder layer of sota-large kept after pruning, from the input at the top to the output at the bottom. Each row is one layer: its 16 attention heads, filled orange if kept and outlined if pruned, and a yellow bar for the FFN units it kept, out of 5,120. Shaded rows are the four layers whose output is matched to the teacher's during distillation, with their FFN count at the right.
  • Width follows the distillation targets. FFN width climbs towards each layer matched to the teacher and collapses right after it. Layer 12 keeps 3,355 of its 5,120 FFN units; layer 13 keeps 146.
  • The deepest layers lose their attention. Layers 38–47 keep no attention heads at all, so they only transform each frame on its own, through their FFN units.
  • The same at both sizes. sota-base shows the same pattern: FFN width peaks at its matched layers 6, 12, 18 and 24, and layers 21–24 keep no heads.

Limitations#

  • English is the weak side. Pruning costs English far more than Khmer. Use sota-large, or a fine-tuned teacher, when English accuracy matters.
  • No punctuation or casing. Output is lowercase with no punctuation, because the Omnilingual character vocabulary has no Khmer punctuation.
  • Greedy decoding only. There is no language model or beam search.
  • One pass per file. Each file is decoded in a single pass, so long recordings should be split into utterances first. Training used clips of 1–25 s.
  • Two languages only. The models were trained and tested on Khmer and English. The other languages Omnilingual supports will have degraded.
  • Prepared speech. DDD is curated recordings on set topics, and FLEURS and LibriSpeech are read aloud. Conversational speech, noisy recordings and Khmer–English code-switching within a sentence are untested.

Usage#

Install the package from GitHub:

pip install git+https://github.com/netra-ai-lab/SOTA

The first run downloads the weights from Hugging Face (sota-base, 292 MB; sota-large, 814 MB). A CPU is enough, and CUDA is used when available.

import sota

asr = sota.load_model("sota-base")              # or "sota-large"
print(asr.transcribe("speech.wav"))             # one file -> one string
print(asr.transcribe(["a.wav", "b.flac"]))      # a list -> a list, batched

From the command line, each file prints as one line, the path and then the text:

sota transcribe speech.wav other.flac --model sota-large

The repository also holds the whole training recipe, from data preparation to export, in one resumable script, along with the fine-tuned teachers (1B, 300M).

Future work#

Sota is the speech recognition half of a planned joint model for transcription and speaker diarization, in the spirit of DiariZen's pruned WavLM. Fine-tuning for CTC removes speaker information from the top layers, so the next step is to re-adapt the pruned encoder, or re-prune from a diarization-tuned teacher. We also want to close the English gap, test on conversational and code-switched speech, and put Sota in the playground so anyone can try it.

References#

  1. Omnilingual ASR: Open-Source Multilingual Speech Recognition for 1600+ Languages
    Omnilingual ASR Team, Meta AI.
    2025.
    arXiv:2511.09690

  2. wav2vec 2.0: A Framework for Self-Supervised Learning of Speech Representations
    Alexei Baevski, Henry Zhou, Abdelrahman Mohamed, and Michael Auli.
    NeurIPS 2020.
    arXiv:2006.11477

  3. Fine-tune Before Structured Pruning: Towards Compact and Accurate Self-Supervised Models for Speaker Diarization
    Jiangyu Han et al.
    Interspeech 2025.
    arXiv:2505.24111

  4. Efficient and Generalizable Speaker Diarization via Structured Pruning of Self-Supervised Models
    Jiangyu Han et al.
    2025.
    arXiv:2506.18623

  5. DPHuBERT: Joint Distillation and Pruning of Self-Supervised Speech Models
    Yifan Peng, Yui Sudo, Shakeel Muhammad, and Shinji Watanabe.
    Interspeech 2023.
    arXiv:2305.17651

  6. Learning Sparse Neural Networks through L0 Regularization
    Christos Louizos, Max Welling, and Diederik P. Kingma.
    ICLR 2018.
    arXiv:1712.01312

  7. FLEURS: Few-Shot Learning Evaluation of Universal Representations of Speech
    Alexis Conneau et al.
    IEEE SLT 2022.
    arXiv:2205.12446

  8. LibriSpeech: An ASR Corpus Based on Public Domain Audio Books
    Vassil Panayotov, Guoguo Chen, Daniel Povey, and Sanjeev Khudanpur.
    ICASSP 2015.
    OpenSLR 12

  9. Khmer ASR Cultural Dataset
    Digital Divide Data.
    Hugging Face Datasets.
    Digital-Divide-Data/khmer-speech-dataset

Cite this paper

@misc{netralab2026sota,
  title  = {{Sota: Khmer and English speech recognition, pruned to a fifth of its size}},
  author = {{Netra Lab}},
  year   = {2026},
  url    = {https://netra-lab.example/research/sota}
}

More research