before the first word
One voice in, twenty-three languages out A code-mixed waveform — stretches of Hindi, English, Bengali, Tamil, Santali, Bodo, Marathi and Telugu, each coloured by its language family — runs into a small isometric model: a gold slab of audio features, a blue encoder stack, a stone head. From the model 23 threads fan out, blue where they leave it and coloured by family where they part, one thread per language: Indo-Aryan, Assamese, Bengali, Dogri, Gujarati, Hindi, Kashmiri, Konkani, Maithili, Marathi, Nepali, Odia, Punjabi, Sanskrit, Sindhi, Urdu; Dravidian, Kannada, Malayalam, Tamil, Telugu; Tibeto-Burman, Bodo, Manipuri; Austroasiatic, Santali; Germanic, English. the audio, as features the encoder the head Indo-Aryan · 15 Assamese Bengali Dogri Gujarati Hindi Kashmiri Konkani Maithili Marathi Nepali Odia Punjabi Sanskrit Sindhi Urdu Dravidian · 4 Kannada Malayalam Tamil Telugu Tibeto-Burman · 2 Bodo Manipuri Austroasiatic · 1 Santali Germanic · 1 English One voice in, twenty-three languages out A code-mixed waveform — stretches of Hindi, English, Bengali, Tamil, Santali, Bodo, Marathi and Telugu, each coloured by its language family — runs into a small isometric model: a gold slab of audio features, a blue encoder stack, a stone head. From the model 23 threads fan out, blue where they leave it and coloured by family where they part, one thread per language: Indo-Aryan, Assamese, Bengali, Dogri, Gujarati, Hindi, Kashmiri, Konkani, Maithili, Marathi, Nepali, Odia, Punjabi, Sanskrit, Sindhi, Urdu; Dravidian, Kannada, Malayalam, Tamil, Telugu; Tibeto-Burman, Bodo, Manipuri; Austroasiatic, Santali; Germanic, English. the audio, as features the encoder the head Indo-Aryan Assamese Bengali Dogri Gujarati Hindi Kashmiri Konkani Maithili Marathi Nepali Odia Punjabi Sanskrit Sindhi Urdu Dravidian Kannada Malayalam Tamil Telugu Tibeto-Burman Bodo Manipuri Austroasiatic Santali Germanic English

introducing:

Anuvani-LID

State of the art where the audio gets hard.

Macro-F1 against a panel of frontier APIs and open-weight models — Gemini 3.5 Flash, Sarvam Saaras v3, GPT-audio, Azure Speech LID, the six MMS-LID models, Whisper-large-v3 and the rest — on identical clips over the ten languages every system supports, and again on all 23 languages. The margin is widest on the shortest clips, where the field falls apart.

0.914

Mean Macro-F1 over 37 core conditions — best of 16

Gemini 3.5 Flash follows at 0.863

Over Gemini 3.5 Flash on the same 37 conditions, paired 95% interval 4.8 to 5.5 pp
+5.2 pp
On all 23 languages, where no other system exceeds 0.713
0.897
Checkpoint campaign, SUITE-102 mean 0.8453 over 102 conditions
Rank 1 of 31

One number, on the only fair footing

Every system’s mean Macro-F1 over the 37 core conditions of SUITE-42 — identical clips, in the ten languages all of them can emit. Anuvani-LID finishes 5.2 points ahead of Gemini 3.5 Flash.

16 systems · 37 conditions · higher is better

1 Anuvani-LID 0.914
2 Gemini 3.5 Flash 0.863
3 Sarvam Saaras v3 0.847
4 MMS-LID-126 0.826
5 MMS-LID-256 0.816
6 MMS-LID-2048 0.812
7 MMS-LID-512 0.808
8 MMS-LID-4017 0.807
9 MMS-LID-1024 0.801
10 NeMo AmberNet 0.793
11 Voxlect Indic-Whisper 0.779
12 VoxLingua107 ECAPA 0.771
13 GPT-audio 0.735
14 Whisper-large-v3 0.719
15 Azure Speech LID 0.687
16 GPT-audio-mini 0.659
Mean Macro-F1 over the 37 core conditions, by system
SystemRankCore-37 mean Macro-F1
Anuvani-LID10.914
Gemini 3.5 Flash20.863
Sarvam Saaras v330.847
MMS-LID-12640.826
MMS-LID-25650.816
MMS-LID-204860.812
MMS-LID-51270.808
MMS-LID-401780.807
MMS-LID-102490.801
NeMo AmberNet100.793
Voxlect Indic-Whisper110.779
VoxLingua107 ECAPA120.771
GPT-audio130.735
Whisper-large-v3140.719
Azure Speech LID150.687
GPT-audio-mini160.659

Plain mean over the 37 core conditions of SUITE-42, 47,730 identical clips — the ten languages every system here can emit, the only footing on which all 16 are comparable. The prompted APIs and Azure were given the ten candidates; Anuvani-LID chose among all 23, and restricted to the same ten it scores 0.923. Bars start at zero.

Every category, on its own panel

One panel per evaluation category, grouped by what it tests. Bars are zero-based and share one scale, so panels are directly comparable; the value above each bar carries the precision the geometry cannot.

9 categories · 3 families · 6 led by Anuvani-LID

Generalization

Conditions the model was not fitted to: very short audio, and the held-out split of SPRING-INX; the open-set slice holds only in-set FLEURS clips, so it repeats FLEURS clean.

Short utterance

n=8

1st

+10.7 pp over Sarvam Saaras v3

Short utterance (n=8) — Macro-F1 by system
SystemMacro-F1Rank
Anuvani-LID0.8421
Sarvam Saaras v30.7362
Gemini 3.5 Flash0.6583
MMS-LID-1260.6414
Azure Speech LID0.5795
Voxlect Indic-Whisper0.5546
Whisper-large-v30.4337
GPT-audio0.3648

Cross-corpus

n=1 · springinx

2nd

−0.2 pp behind Sarvam Saaras v3

Cross-corpus (n=1) — Macro-F1 by system
SystemMacro-F1Rank
Sarvam Saaras v30.9561
Anuvani-LID0.9532
Gemini 3.5 Flash0.8653
Voxlect Indic-Whisper0.8044
MMS-LID-1260.7925
GPT-audio0.7006
Azure Speech LID0.6867
Whisper-large-v30.6818

Open set

n=1 · fleurs

2nd

−1.6 pp behind Gemini 3.5 Flash

Open set (n=1) — Macro-F1 by system
SystemMacro-F1Rank
Gemini 3.5 Flash0.9771
Anuvani-LID0.9612
Voxlect Indic-Whisper0.9353
MMS-LID-1260.9344
GPT-audio0.9325
Whisper-large-v30.8736
Sarvam Saaras v30.8647
Azure Speech LID0.7738

Acoustic degradation

Clean speech pushed through interference, additive noise, room acoustics and codec loss.

Babble

n=2

1st

+7.0 pp over Gemini 3.5 Flash

Babble (n=2) — Macro-F1 by system
SystemMacro-F1Rank
Anuvani-LID0.9101
Gemini 3.5 Flash0.8402
MMS-LID-1260.7993
Sarvam Saaras v30.7944
Voxlect Indic-Whisper0.7815
GPT-audio0.7336
Whisper-large-v30.7257
Azure Speech LID0.6608

Noise

n=4

1st

+6.0 pp over Gemini 3.5 Flash

Noise (n=4) — Macro-F1 by system
SystemMacro-F1Rank
Anuvani-LID0.9441
Gemini 3.5 Flash0.8842
Sarvam Saaras v30.8673
Voxlect Indic-Whisper0.8494
MMS-LID-1260.8355
GPT-audio0.7586
Whisper-large-v30.7477
Azure Speech LID0.6858

Reverb

n=4

1st

+4.3 pp over Gemini 3.5 Flash

Reverb (n=4) — Macro-F1 by system
SystemMacro-F1Rank
Anuvani-LID0.9481
Gemini 3.5 Flash0.9052
Sarvam Saaras v30.8763
Voxlect Indic-Whisper0.8744
MMS-LID-1260.8465
GPT-audio0.8066
Whisper-large-v30.7747
Azure Speech LID0.6868

Telephony

n=4

1st

+1.8 pp over Gemini 3.5 Flash

Telephony (n=4) — Macro-F1 by system
SystemMacro-F1Rank
Anuvani-LID0.9341
Gemini 3.5 Flash0.9152
Voxlect Indic-Whisper0.8883
Sarvam Saaras v30.8824
MMS-LID-1260.8705
GPT-audio0.8126
Whisper-large-v30.8007
Azure Speech LID0.7388

Ceiling conditions

Where every system scores high, so the margins are thin and the ranking is tight.

Clean

n=5

2nd

−0.3 pp behind Gemini 3.5 Flash

Clean (n=5) — Macro-F1 by system
SystemMacro-F1Rank
Gemini 3.5 Flash0.9671
Anuvani-LID0.9642
MMS-LID-1260.9413
GPT-audio0.9024
Sarvam Saaras v30.9015
Voxlect Indic-Whisper0.8716
Whisper-large-v30.8277
Azure Speech LID0.7928

Confusable

n=3

1st

+2.0 pp over Gemini 3.5 Flash

Confusable (n=3) — Macro-F1 by system
SystemMacro-F1Rank
Anuvani-LID0.9751
Gemini 3.5 Flash0.9552
MMS-LID-1260.9253
Voxlect Indic-Whisper0.9134
GPT-audio0.8975
Whisper-large-v30.8836
Sarvam Saaras v30.8497
Azure Speech LID0.8088

In the ceiling conditions every system scores above 0.78, so those bars look alike by design — that is the finding, not a rendering artefact. The next section plots those differences directly.

The margin in each family

The 37-condition CORE-10 analysis folded to its nine degradation families: Anuvani-LID’s mean margin over the strongest rival on each condition. Bars right of the zero rule are wins; the two to the left are named.

7 families ahead · 2 behind · widest +9.03 pp on short utterances

Short utterances
9 conditions
+9.03 pp
unbeaten across the panel
VAD-anchored duration
1 condition
+7.28 pp
unbeaten across the panel
Babble
2 conditions
+6.63 pp
unbeaten across the panel
Noise · SNR 0
5 conditions
+3.56 pp
edged only by Gemini 3.5 Flash
Clean
7 conditions
+2.00 pp
edged only by Sarvam Saaras v3
Confusable pairs
3 conditions
+1.86 pp
edged only by Gemini 3.5 Flash
Reverb
4 conditions
+0.49 pp
edged only by Gemini 3.5 Flash
Open set
1 condition
−0.38 pp
behind Gemini 3.5 Flash
Telephony
5 conditions
−1.95 pp
behind Gemini 3.5 Flash
Mean margin over the strongest rival per condition, by degradation family
FamilyConditionsMean margin vs best rivalWhere we trail
Short utterances9+9.03 pp—
VAD-anchored duration1+7.28 pp—
Babble2+6.63 pp—
Noise · SNR 05+3.56 pp—
Clean7+2.00 pp—
Confusable pairs3+1.86 pp—
Reverb4+0.49 pp—
Open set1−0.38 ppGemini 3.5 Flash
Telephony5−1.95 ppGemini 3.5 Flash

Each bar is the mean, across that family’s conditions, of our margin over whichever single system is strongest on each condition — a rotating best-of-{21-runs} panel, not one fixed rival. Over all 37 conditions the mean margin is +3.54 pp against the best rival and +13.66 pp against the median.

What happens as conditions get worse

Every system starts high on clean speech. The question is how steeply it falls — and Anuvani-LID gives up 0.122 between clean speech and short utterances where the weakest baseline gives up 0.538.

Ordered clean to hardest · radial axis truncated at 0.30

0.4 0.5 0.6 0.7 0.8 0.9 1.0 Clean Confusable Open set Telephony Reverb Cross-corpus Noise Babble Short utterance Anuvani-LID Sarvam Saaras v3 Gemini 3.5 Flash MMS-LID-126 Azure Speech LID Voxlect Indic-Whisper Whisper-large-v3 GPT-audio
Macro-F1 by system across conditions, clean to short utterance
SystemCleanConfusableOpen setTelephonyReverbCross-corpusNoiseBabbleShort utterance
Anuvani-LID0.9640.9750.9610.9340.9480.9530.9440.9100.842
Gemini 3.5 Flash0.9670.9550.9770.9150.9050.8650.8840.8400.658
Sarvam Saaras v30.9010.8490.8640.8820.8760.9560.8670.7940.736
MMS-LID-1260.9410.9250.9340.8700.8460.7920.8350.7990.641
Voxlect Indic-Whisper0.8710.9130.9350.8880.8740.8040.8490.7810.554
GPT-audio0.9020.8970.9320.8120.8060.7000.7580.7330.364
Whisper-large-v30.8270.8830.8730.8000.7740.6810.7470.7250.433
Azure Speech LID0.7920.8080.7730.7380.6860.6860.6850.6600.579

Conditions run left to right from clean to hardest. The axis starts at 0.30 — this chart compares slopes, not magnitudes, and no mark is a bar. Hover a system to isolate its line. Anuvani-LID gives up 0.122 from clean to short utterance; GPT-audio gives up 0.538.

The shape of every system at once

All 8 systems across all 9 categories, each in its own colour. Anuvani-LID is the filled shape; hover any row to bring that system forward and push the rest back.

The one chart here where colour means system identity, not standing

Short utterance Cross-corpus Open set Babble Noise Reverb Telephony Clean Confusable 0.40 0.70 1.00

All 8 systems. Hover a row to bring its profile forward, click to keep it there.

The radial axis starts at 0.30 rather than zero so the profiles stay legible; the value beside each system is its mean Macro-F1 over the 37 core conditions, as in the paper’s Figure 1. This is the one chart on the page where every system gets its own colour — elsewhere the accent means Anuvani-LID alone.

Macro-F1 per category for all 8 systems
SystemShort utteranceCross-corpusOpen setBabbleNoiseReverbTelephonyCleanConfusable
Anuvani-LID0.8420.9530.9610.9100.9440.9480.9340.9640.975
Gemini 3.5 Flash0.6580.8650.9770.8400.8840.9050.9150.9670.955
Sarvam Saaras v30.7360.9560.8640.7940.8670.8760.8820.9010.849
MMS-LID-1260.6410.7920.9340.7990.8350.8460.8700.9410.925
Voxlect Indic-Whisper0.5540.8040.9350.7810.8490.8740.8880.8710.913
GPT-audio0.3640.7000.9320.7330.7580.8060.8120.9020.897
Whisper-large-v30.4330.6810.8730.7250.7470.7740.8000.8270.883
Azure Speech LID0.5790.6860.7730.6600.6850.6860.7380.7920.808

The table everything is computed from

The paper’s Figure 9: each system’s mean Macro-F1 in the nine condition domains of the 37 core conditions, its core mean, and its mean on the all-23 panel for the 6 systems that can output all 23 languages. “—” means a system cannot, never zero.

Full Macro-F1 results. Best score in each row is emphasised.
Clean readCORE-37 7 0.9650.9460.9030.9180.8660.8650.8900.8690.7910.8080.781
Short (≤5 s)CORE-37 8 0.8420.6580.7360.6410.5540.3640.6570.6260.2840.4330.579
TelephonyCORE-37 4 0.9340.9150.8820.8700.8880.8120.7910.7850.7320.8000.738
Noise 0 dBCORE-37 4 0.9440.8840.8670.8350.8490.7580.8230.7880.6680.7470.685
ReverbCORE-37 4 0.9480.9050.8760.8460.8740.8060.7910.7880.7190.7740.686
BabbleCORE-37 2 0.9100.8400.7940.7990.7810.7330.7720.6890.6490.7250.660
ConfusableCORE-37 3 0.9750.9550.8490.9250.9130.8970.9010.8870.8150.8830.808
Hindi varietiesCORE-37 3 0.7790.9120.9180.8570.5760.9070.7250.7270.9080.7930.540
Hard subsetCORE-37 1 0.9840.9540.8650.9250.9170.8920.8720.8710.7870.8380.762
All-23 panelALL-23 5 0.8970.7100.346—0.7130.384——0.285——
Core-37 mean 37 0.9140.8630.8470.8260.7790.7350.7930.7710.6590.7190.687

Best score per row in bold, in blue where it is Anuvani-LID; “—” means the system cannot output all 23 classes. Column headers sort.

At scale, on NVIDIA GPUs

The production port serves the released model through NVIDIA Triton Inference Server, with TensorRT engines built on your own GPU. On six RTX A6000 GPUs it answers 2,522 requests a second, 20,861 seconds of audio every second, with 99% of answers back within 220 ms, and its decisions match the fp32 model on 99.97% of 9,996 benchmark clips.

measured on NVIDIA RTX A6000 · Triton 24.10 and 25.06 · TensorRT 10.5 and 10.11

requests per second on six GPUs, 99% of them answered within 220 ms
2,522
seconds of audio identified every second: 5.8 hours of speech each second
20,861
of 9,996 benchmark clips get the fp32 model’s decision; macro-F1 0.8373 served against 0.8372
99.97%
per request (a 4 s clip at batch 1), against 17 ms in PyTorch
4.6 ms

Measured on NVIDIA RTX A6000 GPUs (48 GB, 300 W) with Triton 24.10 and 25.06; no other GPU has been measured, and ./lid tune finds any NVIDIA GPU’s own limit in about ten minutes. The PyTorch figure is an eager fp32 forward of the same architecture on the same GPU, measured on an earlier checkpoint of the model.

How the client and the server split the work

The client tier does everything that is cheap on a CPU and cuts the audio into pieces of known length; Triton does the arithmetic, and batches pieces from every user together. Splitting it this way is what lets one GPU serve hundreds of requests a second.

upload A upload B upload C Client tier · CPU FastAPI · stateless · scales on CPU hosts decode find the speech cut into pieces pad to a bucket upload A · schematic recording, 24 s 1.6 s 5.6 s 11.4 s 2 s bucket 8 s bucket 15 s bucket filled: speech · hatched: zeros the true length is sent with it one gRPC request per piece, to the least busy Triton Triton · GPU 0 Triton · GPU 1 Triton · GPU N−1 … inside each Triton Inference Server · GPU one model per bucket, each with its own dynamic batcher 2 s A B C B 14.0% of pieces waits ≤ 2 ms batch ≤ 64 log-Mel · fp32 encoder · fp16 4 s A B B C A 16.5% of pieces waits ≤ 4 ms batch ≤ 64 log-Mel · fp32 encoder · fp16 8 s B C A B A C B B C A C A B 42.4% of pieces waits ≤ 8 ms batch ≤ 64 log-Mel · fp32 encoder · fp16 15 s B C A C A B 19.4% of pieces waits ≤ 15 ms batch ≤ 32 log-Mel · fp32 encoder · fp16 30 s A B 7.7% of pieces waits ≤ 30 ms batch ≤ 16 log-Mel · fp32 encoder · fp16 23 logits per piece Client tier · CPU log-softmax per piece, mean weighted by true length returns JSON: overall dominant_by_time language_time_share segments[] upload A upload B upload C Client tier · CPU upload A · schematic 1.6 s 5.6 s 11.4 s 2 s 8 s 15 s filled: speech · hatched: zeros the true length is sent with it one request per piece Triton GPU 0 Triton GPU 1 Triton GPU N−1 Inside each Triton A B C a piece, by its user log-Mel front end, TensorRT fp32 encoder, TensorRT fp16 under each queue: share · waits at most · cap 2 s A B C B 14.0% 2 ms ≤ 64 4 s A B B C A 16.5% 4 ms ≤ 64 8 s B C A B A C B B C A C A B 42.4% 8 ms ≤ 64 15 s B C A C A B 19.4% 15 ms ≤ 32 30 s A B 7.7% 30 ms ≤ 16 23 logits per piece Client tier · CPU log-softmax per piece, mean weighted by true length overall dominant_by_time language_time_share segments[]

The recording is a schematic. The queues are drawn to scale with where real pieces fall: of 2,635 pieces cut from 37 recordings, 14.0% go to the 2 s bucket, 16.5% go to the 4 s bucket, 42.4% go to the 8 s bucket, 19.4% go to the 15 s bucket and 7.7% go to the 30 s bucket. Each user has a colour and a letter: the recording is upload A’s, and every queue mixes all three. Delays and batch caps are the served configuration’s.

  1. Client tier · CPU

    Decode

    Every upload becomes 16 kHz mono audio: libsndfile for WAV, PyAV with soxr for anything else.

  2. Client tier · CPU

    Find the speech

    Silero VAD marks the phrases (threshold 0.5, minimum speech 250 ms, minimum silence 300 ms), so silence, music and noise never reach the GPU.

  3. Client tier · CPU

    Cut into pieces

    Phrases a short pause apart (up to 0.6 s) are merged into pieces of at most 30 s; pieces under 0.3 s are dropped.

  4. Client tier · CPU

    Pad to a bucket

    Each piece is zero-padded to the smallest of the 2, 4, 8, 15 and 30 s buckets and sent with its true length: 1.8% of decisions change, against 2.7% for repeating the audio to fill the bucket.

  5. Client tier · CPU

    Fan out

    One gRPC request per piece, at most 64 in flight per file, to the Triton with the fewest requests in flight. The client never assembles a batch.

  6. Triton · GPU

    Batch across users

    One queue per bucket waits 2, 4, 8, 15 or 30 ms and batches pieces from every user, up to 64, 64, 64, 32 and 16 at a time.

  7. Triton · GPU

    Two TensorRT engines

    The log-Mel front end runs in fp32, the 17 Conformer blocks, layer mix, pooling and head in fp16: 0.73 ms of engine time per 4-second piece at batch 32, against 2.07 ms in fp32. Triton returns 23 logits.

  8. Client tier · CPU

    Decide

    A log-softmax per piece, then a mean weighted by each piece’s true length: the overall language, the language with the most speech time, every language’s share of the time, and the timeline of pieces, as JSON.

  • Triton’s batcher forms batches across users; a client that batched its own pieces would forfeit them.
  • Fixed lengths let TensorRT tune its kernels for one exact shape and give each length its own queue.
  • Each bucket waits in proportion to its compute: at 400 requests/s on one GPU, p99 fell from 669.8 ms with one flat 2 ms delay to 201.4 ms, and to 165.0 ms with the graph rewrites.

5.5 s

  1. 2 s

    waits at most
    2 ms
    batches up to
    64
    engine time per piece
    0.358 ms
  2. 4 s

    waits at most
    4 ms
    batches up to
    64
    engine time per piece
    0.661 ms
  3. 8 s

    waits at most
    8 ms
    batches up to
    64
    engine time per piece
    1.279 ms
  4. 15 s

    waits at most
    15 ms
    batches up to
    32
    engine time per piece
    2.580 ms
  5. 30 s

    waits at most
    30 ms
    batches up to
    16
    engine time per piece
    5.968 ms
The five buckets: queue delay, batch cap and engine time per piece
BucketQueue delayBatch capEngine ms per piece, TensorRT 10.11Engine ms per piece, TensorRT 10.5
2 s2 ms640.3580.385
4 s4 ms640.6610.680
8 s8 ms641.2791.329
15 s15 ms322.5802.574
30 s30 ms165.9685.856

Engine time is TensorRT 10.11 (Triton 25.06), encoder and front end, at batch 16 on one RTX A6000. A long bucket waits longer to fill and caps its batch lower, so short pieces stay fast while long ones still batch. The slider starts at 5.54 s, the median piece of 37 real recordings cut this way.

Latency as the load rises, one GPU

0 250 500 750 1000 360 400 440 480 offered load, items per second latency, ms p99 target, 250 ms Triton 25.06, p99 at 360 items/s: 132.7 ms Triton 25.06, p99 at 400 items/s: 157.3 ms Triton 25.06, p99 at 440 items/s: 256.2 ms Triton 25.06, p99 at 480 items/s: 1134.3 ms Triton 25.06, p50 at 360 items/s: 47.3 ms Triton 25.06, p50 at 400 items/s: 62.7 ms Triton 25.06, p50 at 440 items/s: 120.3 ms Triton 25.06, p50 at 480 items/s: 521.5 ms Triton 24.10, p99 at 360 items/s: 154.6 ms Triton 24.10, p99 at 400 items/s: 219.2 ms Triton 24.10, p99 at 440 items/s: 346.6 ms Triton 24.10, p99 at 480 items/s: 638.8 ms Triton 24.10, p50 at 360 items/s: 76.6 ms Triton 24.10, p50 at 400 items/s: 138.4 ms Triton 24.10, p50 at 440 items/s: 221.8 ms Triton 24.10, p50 at 480 items/s: 447.7 ms Triton 25.06, p99 Triton 24.10, p99 Triton 25.06, p50 Triton 24.10, p50
Latency against offered load on one RTX A6000, the two Triton lines side by side
LineItems/s offeredRequests/sp50, msp99, msAudio-seconds/sMFUWatts
Triton 24.1036038276.6154.63,10818.6%287
Triton 24.10400424138.4219.23,45620.6%290
Triton 24.10440466221.8346.63,80722.7%293
Triton 24.10480508447.7638.84,15824.8%294
Triton 25.0636038247.3132.73,10818.6%287
Triton 25.0640042462.7157.33,45620.6%290
Triton 25.06440466120.3256.23,80722.7%293
Triton 25.06480507521.51134.34,15724.8%294

Mixed traffic, one RTX A6000, the same engines, idle host. At equal load the 25.06 engines answer about twice as fast at the median up to 440 items/s and hold p99 under 250 ms further; both lines saturate near 480 items/s, where the card sits at its 300 W limit.

Six GPUs: what is served, and how fast it comes back

635 requests/s 5,184 audio-s/s p99 94 ms
1,265 requests/s 10,386 audio-s/s p99 97 ms
1,892 requests/s 15,634 audio-s/s p99 116 ms
2,522 requests/s 20,861 audio-s/s p99 220 ms
3,151 requests/s 26,122 audio-s/s p99 1,356 ms
Six RTX A6000 GPUs, one Triton each: load, latency and audio served
Requests/sItems/s offeredp50, msp99, msAudio-seconds/sMean batchMFUWatts per GPU
63560024.893.75,1841.25.2%199
1,265120028.397.410,3861.310.3%250
1,892180038.0116.315,6341.615.6%275
2,5222400119.3219.720,8612.820.8%289
3,1513000529.01356.326,12211.926.0%294

Triton 24.10, one Triton container per GPU, each with its own batchers, so throughput grows linearly with the GPUs. Bars in blue hold p99 under 250 ms; past 2,522 requests/s the queues grow and p99 runs to 1,356 ms.

Faster, and the same answers

  • 26/26 golden clips give the certified language, before any traffic is let in.
  • 99.97% of 9,996 benchmark clips agree with the fp32 model: 99.91% of the 3,499 two-second pieces and every piece in the longer buckets.
  • Macro-F1 0.8373 served against 0.8372 for fp32; accuracy identical, 0.8446.
  • Through the API, 2368/2369 pieces of 21 long recordings get the published PyTorch model’s language, and every file’s decision matches.
  • A 30-minute soak on six GPUs: 3,169,241 requests, no errors, 120588/120588 in-load golden checks right.

Triton returns the 23 logits; the client turns them into probabilities with a softmax. The CPU path, ONNX Runtime on 24 cores, serves about 52 audio-seconds per second: for development, CI and low volume.

On the phone, with no server

The mobile kit runs the same model inside an app, through sherpa-onnx and ONNX Runtime: a 169 MB int8 file on the CPU of any Android 8.1 or newer phone or any iPhone, and a fixed-window graph that Snapdragon NPUs, from the 8 Gen 1 on, and Apple’s Core ML take whole. Every file agrees with the released model on at least 99.2% of 918 benchmark clips, and long recordings go through the same Silero VAD pieces and the same JSON as the server.

sherpa-onnx v1.13.8 · ONNX Runtime 1.28.2 · Android 8.1+ · iOS 15+ · Kotlin, Java, Swift, Dart, C#, C and C++

Four model files, one released model

int8The default on every phone’s CPU, any length 169.0 MB 99.24% · 7 flips
fp32The certified graph: reference results on any CPU 464.3 MB 100.00% · 0 flips
npu-15s.encoderNPUs in fp16 on a fixed 15 s window, with its 0.1 MB front end on the CPU 471.2 MB 100.00% · 0 flips
npu-15s-nnapi.encoderAndroid NNAPI (Android 8.1 to 14), after measuring on the phone 471.3 MB 100.00% · 0 flips
The model files: size and agreement with the released model on 918 benchmark clips
FileSize, MBAgreementFlipsMacro-F1Golden clips
anuvani_lid.int8.onnx169.099.24%70.853626/26
anuvani_lid.fp32.onnx464.3100.00%00.855226/26
anuvani_lid.npu-15s.encoder.onnx471.2100.00%00.855226/26
anuvani_lid.npu-15s-nnapi.encoder.onnx471.3100.00%00.855226/26

Agreement is the share of 918 benchmark clips whose top language is the released model’s, run in fp32 on the server; every file gives the same language on all 26 golden clips. The int8 file’s macro-F1 is 0.8536 against 0.8552. The NPU encoder needs its 0.1 MB front end beside it; long audio also needs Silero VAD, 2.3 MB.

Which file for my phone?

Any phone

File
anuvani_lid.int8.onnx
Runs on
CPU

Any Android 8.1 or newer phone and any iPhone. The only format whose results do not depend on a vendor driver: start here everywhere.

Snapdragon 8 Gen 1 and newer

File
npu-15s encoder + front end
Runs on
Qualcomm QNN

Hexagon v69 and newer: 8 Gen 1, 8+ Gen 1, 8 Gen 2, 8 Gen 3, 8s Gen 3, 8 Elite, 8 Elite Gen 5 and 7+ Gen 3. The whole encoder compiles to one NPU graph, cached after the first run.

iPhone and iPad, A12 and newer

File
npu-15s encoder + front end
Runs on
Core ML

iOS 15 and newer. Core ML takes the whole encoder as one partition; the front end stays on the CPU in fp32.

Exynos, Tensor, Dimensity and others

File
anuvani_lid.int8.onnx
Runs on
CPU, or NNAPI after measuring

Android 8.1 to 14 can use the NNAPI encoder, but vendor drivers differ: measure one phone first.

Snapdragon 888

File
anuvani_lid.int8.onnx
Runs on
CPU

Hexagon v68 cannot compile the NPU graph; the kit falls back to the CPU and says so.

Budget phones, 2 to 4 GB

File
anuvani_lid.int8.onnx
Runs on
CPU, 2 to 4 threads

Cortex-A53 and A55 phones, 32-bit armeabi-v7a included. On 2 to 3 GB, cap pieces at 15 s to lower peak memory.

What each optimisation bought

  1. Dynamic int8 weights

    Every matrix multiply’s weights in 8 bits, per output channel; convolutions, the front end and attention products stay in fp32.

    464.3 MB → 169.0 MB99.24% agreement, macro-F1 -0.15 pp

  2. Unsigned weights

    x86 and some ARM integer paths can saturate on signed 8-bit products.

    worst logit error 2.13 → 0.57chosen over signed weights

  3. Pad the tail as the server does

    After each piece, the zeros the server’s bucket would add.

    905 → 918 of 918decisions that match the server

  4. Split the front end off

    The log guard underflows in fp16 and its length logic stops an NPU compiler, so the front end runs on the CPU in fp32.

    2 NPU + 87 CPU parts → 1 NPU graphthe whole encoder on the NPU

  5. Scale the residual stream for fp16

    Powers of two per block, folded into the weights, keep every LayerNorm input inside fp16’s range.

    peak 21,782 → under 64within 3.4×10⁻⁴ of PyTorch

  6. Choose the window by measuring

    The NPU graph has a fixed length; a shorter window cuts more pieces.

    4 s: 98.91% → 15 s: 100.00%15 s, the shortest with no flips

  7. Rewrite for NNAPI

    LayerNorm as plain arithmetic, every 1-D convolution as 2-D, clamps as Max and Min.

    56 parts → 1 partitionall 2,057 nodes on NNAPI

All 17 Conformer blocks and the learned layer mix are kept: nothing was pruned, distilled or truncated, and pieces are classified whole, not streamed.

What a piece costs, by its length

Peak memory, int8, MB
0 200 400 600 800 0 10 20 30 piece length, s 2 s: 307.0 MB 8 s: 384.0 MB 15 s: 473.5 MB 30 s: 687.0 MB
Arithmetic, billions of multiply-adds
0 40 80 120 160 0 10 20 30 piece length, s 1 s: 4.67 GMAC 2 s: 8.71 GMAC 4 s: 17.62 GMAC 8 s: 35.28 GMAC 15 s: 67.28 GMAC 30 s: 144.42 GMAC
Peak memory of the int8 file and arithmetic per piece, by piece length
Piece length, sPeak memory, MB (int8)Arithmetic, GMAC
1—4.67
23078.71
4—17.62
838435.28
15473.567.28
30687144.42

Measured with the kit’s command-line tool, the same C++ code as the phone libraries, on the build server with 4 threads; arithmetic counted from the graph. Real recordings, cut as the server cuts them, give a median piece of 5.54 s, and 92.3% of pieces are 15 s or shorter. The NPU graph always computes one 15 s window: 63.51 billion multiply-adds.

The int8 file on phone CPUs

  • Armv9-class: dot product, int8 matrix multiply, SVErecent flagships99.02%
  • Cortex-A76: Armv8.2 dot productmid-range and flagship phones since 201999.24%
  • Cortex-A53: Armv8.0, plain NEONbudget phones99.24%
  • Cortex-A7: 32-bit armv7-a NEONarmeabi-v7a phones99.24%
The int8 file on four emulated ARM CPUs: agreement with the released model on 918 clips
CPUStands forAgreementFlipsMacro-F1 changeGolden
Armv9-class: dot product, int8 matrix multiply, SVErecent flagships99.02%9−0.05 pp26/26
Cortex-A76: Armv8.2 dot productmid-range and flagship phones since 201999.24%7−0.11 pp26/26
Cortex-A53: Armv8.0, plain NEONbudget phones99.24%7−0.11 pp26/26
Cortex-A7: 32-bit armv7-a NEONarmeabi-v7a phones99.24%7−0.13 pp26/26

Linux builds of the phone libraries under QEMU, 944 clips each; the 26 golden clips give the same language on every core.

The NPU graph on Snapdragon and Apple

  • Snapdragon 8 Gen 1Hexagon v69one NPU graph
  • Snapdragon 8 Gen 2Hexagon v73one NPU graph
  • Snapdragon 8 Gen 3Hexagon v75one NPU graph
  • Snapdragon 8 EliteHexagon v79one NPU graph
  • Snapdragon 8 Elite Gen 5Hexagon v81one NPU graph
  • Apple Core MLA12 and newer1,268 of 1,268 nodes
The NPU encoder on Qualcomm's emulated NPU, one golden clip per chip generation
ChipNPUPlacementCompile timeLargest probability difference from the CPU
Snapdragon 8 Gen 1Hexagon v691 NPU graph31.9 s3.0e-4
Snapdragon 8 Gen 2Hexagon v731 NPU graph16.2 s4.7e-5
Snapdragon 8 Gen 3Hexagon v751 NPU graph24.6 s4.7e-5
Snapdragon 8 EliteHexagon v791 NPU graph19.8 s4.7e-5
Snapdragon 8 Elite Gen 5Hexagon v811 NPU graph22.1 s4.7e-5

Qualcomm’s emulated NPU in fp16, one golden clip per chip generation, same language as the CPU; Core ML by ONNX Runtime’s placement check. Neither has run on a real phone yet.

Get it from Hugging Face

One repository, CIIL/Anuvani-LID, holds the model and both kits: the PyTorch model with its code at the root, the serving recipe in triton_inference/ and the on-device kit in mobile_inference/. Pick how you want to run it.

huggingface.co/CIIL/Anuvani-LID · Python · Triton · Android and iOS

CIIL/Anuvani-LID
the model in transformers format, its code, labels and five FLEURS sample clips
triton_inference/
serving at scale on NVIDIA GPUs, and a CPU path
mobile_inference/
on-device inference for Android and iOS, on ONNX Runtime

Python

The model at the root of the repository loads in transformers, with its own code (hence trust_remote_code). Give the pipeline a file path and it resamples for you.

pipelinePython
from transformers import pipeline
repo = "CIIL/Anuvani-LID"
clf = pipeline("audio-classification", model=repo, feature_extractor=repo, trust_remote_code=True)
# [{'label': 'hindi', 'score': 0.98}, ...]
print(clf("audio.wav")[:3])

For recordings of minutes or hours, the built-in helper finds the speech phrases with Silero VAD, classifies every piece and weights the pieces by duration: the same procedure as the production API.

AutoModelPython
import soundfile as sf, torch
from transformers import AutoModelForAudioClassification, AutoFeatureExtractor
repo = "CIIL/Anuvani-LID"
# native Wav2Vec2FeatureExtractor
fe = AutoFeatureExtractor.from_pretrained(repo)
model = AutoModelForAudioClassification.from_pretrained(repo, trust_remote_code=True).eval()
# 16 kHz mono
wav, sr = sf.read("audio.wav")
logits = model(**fe(wav, sampling_rate=sr, return_tensors="pt")).logits
print(model.config.id2label[logits.argmax(-1).item()])
Long audioPython
import librosa
# any format/length
wav, _ = librosa.load("lecture_1hour.mp3", sr=16000, mono=True)
# needs: pip install silero-vad
out = model.classify_long_audio(wav)
# overall (duration-weighted over the speech pieces)
print(out["label"], out["score"])
# share of speech time per language
print(out["dominant_by_time"], out["language_time_share"])
# per phrase piece — surfaces code-switching
for p in out["timeline"]:
    print(f"{p['start']:7.1f}-{p['end']:7.1f}s  {p['label']}  {p['score']:.3f}")

With no transformers and no torch, the serving graph runs in ONNX Runtime: raw 16 kHz audio in, 23 logits out.

ONNX RuntimePython
import onnxruntime as ort, soundfile as sf, numpy as np
from huggingface_hub import hf_hub_download
repo = "CIIL/Anuvani-LID"
sess = ort.InferenceSession(hf_hub_download(repo, "triton_inference/assets/model/anuvani_lid.onnx"))
labels = open(hf_hub_download(repo, "labels.txt")).read().split()
# 16 kHz mono
wav, _ = sf.read("audio.wav", dtype="float32")
logits = sess.run(["logits"], {"audio": wav[None], "audio_length": np.array([len(wav)], np.int64)})[0]
print(labels[int(logits.argmax())])

Triton

triton_inference/ is the whole serving recipe: Docker images, Triton configurations, the client tier, the accuracy gate and the load tests. ./lid builds TensorRT engines on your GPU, starts Triton and the API, and refuses traffic until the gate passes.

Serve on your GPUShell
hf download CIIL/Anuvani-LID --include "triton_inference/*" --local-dir Anuvani-LID
# downloads do not keep executable bits
cd Anuvani-LID/triton_inference && chmod +x lid
./lid doctor && ./lid prepare && ./lid build && ./lid up && ./lid gate
curl -F file=@speech.wav localhost:8080/v1/lid | python3 -m json.tool

Two keys in deploy/compose/.env, written by ./lid build, scale a node to N GPUs, one Triton per GPU, and the client tier finds them by itself.

Mobile

mobile_inference/ holds the model files, prebuilt libraries for Android and Linux on ARM, the sherpa-onnx patches, app code and the gates. Start with int8 on the CPU everywhere.

Download the kitShell
hf download CIIL/Anuvani-LID --include "mobile_inference/*" --local-dir Anuvani-LID
# downloads drop executable bits
cd Anuvani-LID/mobile_inference && chmod +x mobile prebuilt/*/bin/*
# check the model files
(cd models && sha256sum -c SHA256SUMS)
Android, KotlinKotlin
val lid = LanguageIdentifier(
    modelDir = File(filesDir, "anuvani-lid"),       // the model files
    workDir = filesDir,                              // writable: provider configs, compiled NPU graphs
    accelerator = Accelerator.CPU_INT8,
    threads = 4,
)
// samples: mono FloatArray in [-1, 1]; any sample rate (resampled to 16 kHz)
val r = lid.identify(samples, sampleRate)            // blocking: call it from a background thread
r.language          // "hindi", or null when there is no speech
r.dominantByTime    // the language with the most speech time (use this for mixed recordings)
r.segments          // timeline: start, end, language, probability of every piece of speech
r.json              // the anuvani-lid/1 JSON (docs/02), the server's format
lid.close()
iOS, SwiftSwift
import AnuvaniLid

let lid = try LanguageIdentifier(
    modelDirectory: modelsURL,                                     // the model files
    cacheDirectory: FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0],
    accelerator: .coreML,                                          // or .cpuInt8 (the default)
    threads: 4)
// samples: [Float] mono in [-1, 1], any sample rate (resampled to 16 kHz)
let r = try lid.identify(samples: samples, sampleRate: 16000)     // blocking: not on the main thread
r.overall.label          // "hindi", or nil without speech
r.dominant_by_time       // the language with the most speech time (mixed recordings)
r.segments               // timeline
let json = lid.identifyJSON(samples: samples, sampleRate: 16000)  // the same, as anuvani-lid/1 JSON text
let scores = lid.classify(samples: segment, sampleRate: 16000)   // one stretch of speech: 23 probabilities

Code under Apache-2.0; the sample clips are FLEURS (CC-BY-4.0); Silero VAD is MIT. Each kit starts at its README.

Method

How systems are compared

Every cross-system number on this page is from SUITE-42, the paper’s comparison panel, and every system received identical clips. Its 37 core conditions (47,730 clips) cover the ten languages every compared system supports: Hindi, Bengali, Tamil, Telugu, Marathi, Gujarati, Kannada, Malayalam, Punjabi and Urdu. Its all-23 panel adds five IndicVoices conditions (17,229 clips) on all 23 classes.

The prompted audio LLMs and Azure were given the candidate list, ten languages on the core panel and 23 on the all-23 panel; Sarvam Saaras v3 ran in auto-detect mode; open models predicted over their own label sets. Anuvani-LID always chose among all 23 classes, so it can make errors a ten-candidate system cannot; restricted to the same ten it scores 0.923. Azure supports 11 of the 23 classes and has no all-23 score. All API queries were made between 16 and 21 July 2026. Sarvam Saaras v3 is the strongest rival on short utterances and on Hindi varieties (0.918), and edges Anuvani-LID on SPRING-INX (0.956 against 0.953).

Which checkpoint the numbers describe

Every Anuvani-LID number on this page is the released model: the uniform average of seven checkpoints of one 425,000-step run, first of 31 candidates at SUITE-102 mean 0.8453, with one calibration temperature, 0.674. The candidate that involved no choice, the run’s final EMA weights, scores 0.912 on the core conditions and 0.889 on all 23, so choosing the average on SUITE-102 changes no ranking.

What the numbers can bear

Every paired difference against another system excludes zero (McNemar, p < 10⁻¹⁰⁰ over 47,730 clips). Per condition, Anuvani-LID is significantly better than Gemini 3.5 Flash on 21 of 37 and worse on 9, and better than every open model on at least 28. Training is another matter: two runs of one configuration landed 3.18 pp apart, so a gap of under about 3 pp between two training recipes needs more than one seed.

The all-23 test shares none of its 1,308 speakers with training. FLEURS, SPRING-INX, MUCS and Common Voice are held out by split: their evaluation splits, with an empty clip-level intersection with training. Kathbath shares 4 of its 456 speakers with training and is an in-domain comparator. Every held-out tier is a public corpus; SUITE-102 adds one licensed in-domain comparator, LDC-IL.

Training

  • 54,643 hours · 31.24M utterances · 6 × RTX A6000
  • 425,000 steps · 17-block Conformer, d=512 · 115.6M parameters
  • Benchmark: SUITE-102, 102 conditions · 318,861 utterances

Systems compared

  • Anuvani-LIDThis work
  • Gemini 3.5 FlashGoogle
  • Sarvam Saaras v3Sarvam AI
  • MMS-LID-126Meta
  • MMS-LID-256Meta
  • MMS-LID-512Meta
  • MMS-LID-1024Meta
  • MMS-LID-2048Meta
  • MMS-LID-4017Meta
  • Voxlect Indic-WhisperUSC SAIL
  • GPT-audioOpenAI
  • NeMo AmberNetNVIDIA
  • VoxLingua107 ECAPASpeechBrain
  • GPT-audio-miniOpenAI
  • Whisper-large-v3OpenAI
  • Azure Speech LIDMicrosoft

Voxlect Indic-Whisper is the Whisper-large-v3 regional-language classifier of Feng (2025), trained on 3–15 s clips. Brand marks are vendored from lobehub’s icon set and are the property of their respective owners.

Sources

  • The Anuvani-LID paper: Figure 1, Figure 9, Tables 3, 7 and 8, Appendix D
  • Its figure data (paper_eval): every value on this half, unrounded
  • Figure 8 and §5.2, Stage VI: SUITE-102 and the 31 candidates
  • Table 6: the training settings

Fig. 0 Hero one code-mixed voice · the 22 scheduled languages of India and English · colour = language family
One voice, twenty-three languages A waveform enters from the left and fans out into 23 threads, one per language, grouped by family: Indo-Aryan, Assamese, Bengali, Dogri, Gujarati, Hindi, Kashmiri, Konkani, Maithili, Marathi, Nepali, Odia, Punjabi, Sanskrit, Sindhi, Urdu; Dravidian, Kannada, Malayalam, Tamil, Telugu; Tibeto-Burman, Bodo, Manipuri; Austroasiatic, Santali; Germanic, English. Hindi English Hindi Bengali English Tamil Hindi Santali English Bodo Marathi Telugu Hindi Indo-Aryan · 15 Assamese Bengali Dogri Gujarati Hindi Kashmiri Konkani Maithili Marathi Nepali Odia Punjabi Sanskrit Sindhi Urdu Dravidian · 4 Kannada Malayalam Tamil Telugu Tibeto-Burman · 2 Bodo Manipuri Austroasiatic · 1 Santali Germanic · 1 English One voice, twenty-three languages A waveform enters from the left and fans out into 23 threads, one per language, grouped by family: Indo-Aryan, Assamese, Bengali, Dogri, Gujarati, Hindi, Kashmiri, Konkani, Maithili, Marathi, Nepali, Odia, Punjabi, Sanskrit, Sindhi, Urdu; Dravidian, Kannada, Malayalam, Tamil, Telugu; Tibeto-Burman, Bodo, Manipuri; Austroasiatic, Santali; Germanic, English. Indo-Aryan Assamese Bengali Dogri Gujarati Hindi Kashmiri Konkani Maithili Marathi Nepali Odia Punjabi Sanskrit Sindhi Urdu Dravidian Kannada Malayalam Tamil Telugu Tibeto-Burman Bodo Manipuri Austroasiatic Santali Germanic English

One voice, switching language mid-sentence, and the 23 languages it might be speaking at any moment: the 22 scheduled languages of India and English, drawn from four families.

Table of contents 12 parts · 58 min

Every voice arrives wrapped in a language, the way a river carries the colour of the soil it has crossed. Long before the words resolve, a listener has already tasted the water: the fall of the stress, the curl of a retroflex, the verb that waits patiently at the end of the sentence. A trained ear knows a raga from its first phrase, before the melody has told you anything at all.

Spoken language identification is that first phrase, heard by a machine.

It is the smallest decision in a speech system, and the one every later decision inherits. Which recogniser to wake, which way to translate, which voice should answer: all of it waits on a single label, usually decided in the first second or two of sound. This post is about why, in 2026, we think that decision deserves a model of its own, and about the one we built for the 22 scheduled languages of India and English: Anuvani-LID.

The first question every speech system asks

Before a machine can transcribe, translate or reply, it has to answer a question most of us never notice ourselves asking: which language is this? That is spoken language identification, or LID. Given a stretch of audio, the system names the language being spoken from a fixed list of candidates.

Humans are astonishingly good at it. Four-day-old infants already tell their mother’s language apart from an unfamiliar one, long before they understand a single word (Mehler et al., 1988). They are listening to rhythm and melody, not vocabulary. A machine must learn the same trick from the raw signal: sixteen thousand air-pressure samples a second, with no spaces, no letters and no script.

A useful picture is the front desk of a large multilingual hospital. The receptionist does not treat anyone. They decide which specialist you see. If they get that wrong, the best specialist in the building cannot help you, because they are not hearing your problem in your language.

In a modern voice pipeline, LID sits just after voice-activity detection, and its one label steers four things at once (Li, Ma & Lee, 2013):

  • which speech recogniser, or which language setting, transcribes the audio;
  • which direction a translation system runs;
  • which language the assistant’s language model replies in, and which voice speaks the reply;
  • which human team a call is handed to.

In India this is daily infrastructure, not a thought experiment. Kisan Call Centres answer farmers in 22 languages (Department of Agriculture & Farmers Welfare). The Tele-MANAS mental-health helpline routes callers to state cells by language (PIB, 2026). Bhashini offers automatic language detection across its national voice services (PIB, 2026). As our paper puts it, errors at this stage propagate: “a Maithili call sent to a Hindi recogniser degrades every later component.”

Fig. 1 The gate a voice pipeline · one label, four decisions
The gate: one label steers four decisions A voice pipeline runs from the caller through voice activity detection to language identification, which emits one label. That label chooses the speech recogniser, the direction of translation, the language and voice of the reply, and the human team. A Maithili call labelled Hindi sends all four wrong at once. one label steers four things at once MIC Caller speaks Maithili VAD Voice activity detection LID Language identification LABEL HINDI MAITHILI wrong label right label ASR Speech recogniser a Hindi model transcribes a Maithili model transcribes MT Translation runs Hindi to English runs Maithili to English LLM Reply language and voice answers in Hindi answers in Maithili DESK Human hand-off goes to the Hindi team goes to the Maithili team The gate: one label steers four decisions A voice pipeline runs from the caller through voice activity detection to language identification, which emits one label. That label chooses the speech recogniser, the direction of translation, the language and voice of the reply, and the human team. A Maithili call labelled Hindi sends all four wrong at once. MIC Caller speaks Maithili VAD Voice activity detection LID Language identification LABEL HINDI MAITHILI one label steers four things at once wrong label right label ASR Speech recogniser a Hindi model transcribes a Maithili model transcribes MT Translation runs Hindi to English runs Maithili to English LLM Reply language and voice answers in Hindi answers in Maithili DESK Human hand-off goes to the Hindi team goes to the Maithili team
The label the identifier gives

One label steers four things at once. Here a Maithili call is labelled Hindi, and every downstream component inherits the mistake. Flip the switch to give the identifier the right label.

A short history: from phonotactics to self-supervised encoders

LID is one of the oldest problems in speech technology, and its history is a story of steadily richer representations of the same signal (Li, Ma & Lee, 2013).

Sound sequences (1990s). Languages differ in which sounds they allow and in what order. Early systems exploited that directly: recognise a string of phones, then score it with a small n-gram model per language. Zissman’s comparison of four such approaches on telephone speech set the template for a decade (Zissman, 1996), and NIST’s Language Recognition Evaluations turned the problem into a shared benchmark (Sadjadi et al., 2018).

Utterance embeddings (2010s). The field then learned to summarise a whole utterance as a single vector. i-vectors compressed an utterance’s acoustic statistics into a few hundred numbers (Dehak et al., 2011). Deep networks trained directly on language labels overtook them, especially on short clips (Lopez-Moreno et al., 2014). x-vectors pooled frame-level features into a learned embedding (Snyder et al., 2018); attentive statistics pooling let the network decide which frames mattered (Okabe et al., 2018); and ECAPA-TDNN refined the recipe into today’s workhorse (Desplanques et al., 2020). VoxLingua107 made 107-language training data widely available (Valk & Alumäe, 2021), and compact models such as NVIDIA’s AmberNet followed (Jia et al., 2023).

Self-supervised encoders (2020 onward). wav2vec 2.0 showed that a network could learn speech structure from unlabelled audio (Baevski et al., 2020). XLSR-53 and XLS-R scaled that across dozens, then 128, languages (Conneau et al., 2021; Babu et al., 2022), and w2v-BERT added masked prediction (Chung et al., 2021). In this era one pre-trained encoder sprouts several small heads: a CTC head for transcription (Graves et al., 2006) and a classification head for language. Meta’s MMS is the clearest example: 1,107-language ASR built from per-language adapters and CTC heads, shipped alongside separate LID models covering up to 4,017 languages (Pratap et al., 2024). NVIDIA found that multilingual self-supervised Conformers are “accidental learners” of language identity (Bartley et al., 2023). For Indian languages, IndicWav2Vec, IndicSUPERB and the 279k-hour MahaDhwani encoder brought the same approach home (Javed et al., 2022; Javed et al., 2023; Bhogale et al., 2025).

A parallel thread: the language as a token. Alongside this, researchers began folding LID into the recogniser. Watanabe, Hori and Hershey made the language a symbol the end-to-end model emits before the transcript (2017). Google trained single models on nine Indian languages, with and without a language-ID input (Toshniwal et al., 2018; Kannan et al., 2019). Later work added auxiliary LID objectives inside the encoder (Chen et al., 2023). That thread leads straight to the models that dominate today.

Fig. 2 Timeline, two lanes 1996 → 2026 · to scale from 2010; the 1990s are compressed
Two lanes of language identification, 1996 to 2026 A timeline with two lanes. In the top lane, language identification as its own model: PRLM in 1996, i-vectors in 2011, DNNs in 2014, x-vectors and ECAPA-TDNN in 2018 to 2020, self-supervised encoders with an LID head such as MMS-LID and AmberNet in 2023, and Anuvani-LID in 2026. In the bottom lane, language identification inside the recogniser: a joint LID token in 2017, a language-ID input in 2018 to 2019, Whisper’s language token in 2022, and speech-LLMs from 2024 to 2026. LID as its own model LID inside ASR 1996 2010 2015 2020 2025 PRLM 1996 · phone strings, n-grams i-vector 2011 · utterance embeddings DNN 2014 · trained on language labels x-vector, ECAPA-TDNN 2018–20 · pooled embeddings SSL encoder + LID head 2023 · MMS-LID, AmberNet Anuvani-LID 2026 · this work Joint LID token 2017 · Watanabe et al. Language-ID input 2018–19 · Google, 9 Indian languages Whisper’s language token 2022 · first decoded symbol Speech-LLMs 2024–26 · Voxtral, Qwen, Gemini here the language becomes a token the recogniser emits Two lanes of language identification, 1996 to 2026 A timeline with two lanes. In the top lane, language identification as its own model: PRLM in 1996, i-vectors in 2011, DNNs in 2014, x-vectors and ECAPA-TDNN in 2018 to 2020, self-supervised encoders with an LID head such as MMS-LID and AmberNet in 2023, and Anuvani-LID in 2026. In the bottom lane, language identification inside the recogniser: a joint LID token in 2017, a language-ID input in 2018 to 2019, Whisper’s language token in 2022, and speech-LLMs from 2024 to 2026. LID as its own model LID inside ASR PRLM 1996 · phonotactics i-vector 2011 · utterance vectors DNN 2014 · language labels x-vector, ECAPA 2018–20 · pooled frames SSL + LID head 2023 · MMS-LID, AmberNet Anuvani-LID 2026 · this work Joint LID token 2017 · Watanabe et al. Language-ID input 2018–19 · Google Whisper’s token 2022 · first symbol Speech-LLMs 2024–26 · Voxtral, Qwen

Thirty years of steadily richer representations of the same signal, and a parallel thread that folded the language decision into the recogniser as a token.

One model for everything: the text-generation turn

By 2020, natural-language processing had found an intoxicating idea. GPT-2 had framed language models as “unsupervised multitask learners” (Radford et al., 2019). T5 recast every NLP task as text-to-text (Raffel et al., 2020). Then GPT-3 showed that one next-token predictor with 175 billion parameters could translate, answer questions and do arithmetic from a prompt and a few examples, with no task-specific head at all (Brown et al., 2020).

The lesson that crossed into speech was simple and powerful. With enough data and compute, stop building a head per task. Turn every task into open-ended text generation, and let one model learn them all.

Whisper is where that lesson landed. An encoder reads 30 seconds of log-Mel spectrogram; an autoregressive decoder writes text. The paper is explicit about the design: “We use a simple format to specify all tasks and conditioning information as a sequence of input tokens to the decoder.” The first of those tokens is the language: “we predict the language being spoken which is represented by a unique token for each language in our training set (99 total)” (Radford et al., 2023). A Hindi transcript therefore begins:

<|startoftranscript|> <|hi|> <|transcribe|> <|notimestamps|> नमस्ते, आप कैसे हैं? <|endoftext|>

LID became a side effect of generation. The model’s belief about the language is simply whichever language token wins the first decoding step.

The label grew a script. Whisper’s tokens are two-letter ISO 639-1-style codes, with no notion of writing system. Later systems widened the code. Meta’s Omnilingual ASR, covering more than 1,600 languages, conditions on {language}_{script} pairs such as hin_Deva and urd_Arab: an ISO 639-3 language code joined to an ISO 15924 script code (Omnilingual ASR team, 2025; repo). Google’s Chirp 3 uses BCP-47 locale tags such as pa-Guru-IN (docs). Qwen3-ASR writes the language as a plain-text prefix before the transcript (Qwen Team, 2026).

The family tree kept growing. OWSM reproduced Whisper-style training on public data (Peng et al., 2023). Qwen-Audio unified more than 30 audio tasks under hierarchical tags (Chu et al., 2023). Mistral’s Voxtral (July 2025) joins a Whisper large-v3 encoder to Mistral language decoders, in 3B and 24B variants, adds a dedicated transcribe-mode token, and advertises “automatic language detection” (Mistral AI, 2025; Voxtral, 2025). Qwen3-Omni and Qwen3.5-Omni fold recognition into omni-modal models (Qwen Team, 2025; 2026). At the frontier, Gemini 3.5 Flash and OpenAI’s GPT-audio treat “which language is this?” as one more question to answer in text.

System How the language decision is made Label format
Whisper, OWSM Predicted as the first decoder token <|hi|> (first decoded token)
Voxtral Detected inside the model; transcribe-mode token internal
Qwen3-ASR Written as a text prefix before the transcript language Hindi
Omnilingual ASR Optional input; no detector shipped hin_Deva
NVIDIA Canary Required input prompt source_lang='en'
Google Chirp 3 Input list, or auto hi-IN, pa-Guru-IN
Meta MMS Selects a per-language adapter; separate LID model hin
Gemini, GPT-audio Answered in free text from a prompt free text

It is worth saying plainly: this was a real advance. One training run, one model, remarkable robustness, and language identification apparently for free. Qwen3-ASR reports 97.9% average LID accuracy across four mainstream benchmarks. The question this post asks is narrower. For the first decision in a voice pipeline, is “for free” good enough?

Fig. 3 Three architectures, one question ring = the point where the language is decided
Three architectures and where each decides the language Three panels. (a) A self-supervised encoder feeds two heads: a CTC head that writes the text and a classifier head that names the language; the language is decided in the classifier. (b) An encoder–decoder in the Whisper style: the decoder writes a sequence of tokens and the language token is the first symbol it decides, before the transcript. (c) A speech-LLM: an audio encoder and adapter feed a language model together with a prompt; the language arrives as part of the prompt or is written as a text prefix in the output. (a) One encoder, two heads Audio 16 kHz waveform SSL Self-supervised encoder CTC Text head LID Language head decided here नमस्ते, आप… LANGUAGE HINDI (b) Encoder–decoder Audio padded to 30 s ENC Audio encoder DEC Autoregressive decoder DECODED, ONE STEP AT A TIME 1 <|startoftranscript|> 2 <|hi|> 3 <|transcribe|> 4 <|notimestamps|> 5 नमस्ते, आप कैसे हैं? DECIDED HERE (c) Speech-LLM Audio ENC Audio encoder Adapter audio as tokens Prompt can carry the language LLM Language model language Hindiनमस्ते, आप कैसे हैं? decided here Three architectures and where each decides the language Three panels. (a) A self-supervised encoder feeds two heads: a CTC head that writes the text and a classifier head that names the language; the language is decided in the classifier. (b) An encoder–decoder in the Whisper style: the decoder writes a sequence of tokens and the language token is the first symbol it decides, before the transcript. (c) A speech-LLM: an audio encoder and adapter feed a language model together with a prompt; the language arrives as part of the prompt or is written as a text prefix in the output. (a) One encoder, two heads Audio 16 kHz waveform SSL Self-supervised encoder CTC Text head LID Language head decided here नमस्ते, आप… LANGUAGE HINDI (b) Encoder–decoder Audio padded to 30 s ENC Audio encoder DEC Autoregressive decoder DECODED, ONE STEP AT A TIME 1 <|startoftranscript|> 2 <|hi|> 3 <|transcribe|> 4 <|notimestamps|> 5 नमस्ते, आप कैसे हैं? DECIDED HERE (c) Speech-LLM Audio ENC Audio encoder Adapter audio as tokens Prompt can carry the language LLM Language model language Hindiनमस्ते, आप कैसे हैं? decided here

Where is the language decided? In a classifier head trained for it, in the first token an autoregressive decoder happens to write, or in a line of text a language model is asked for.

Our position: decouple the first decision

Despite all of this progress, we believe the language decision belongs in a model of its own. It can be optional for a pipeline that already knows its language. For any voice agent that does not, it is the first component you build.

The field is quietly converging on the same view from the other side. The newest recognisers increasingly ask for the language rather than detect it. Omnilingual ASR takes an optional language_script code, and conditioning on it “largely resolves the wrong-script problem” of its CTC models. NVIDIA’s Canary requires source_lang. AI4Bharat’s IndicConformer is called as model(wav, "hi", "ctc"). Meta’s MMS loads a per-language adapter. And vendors advise the same thing in their docs: Sarvam says to “always specify the language code when you know the language of the audio. This improves accuracy and reduces processing time” (Sarvam docs).

So the real question is not whether a voice system needs a language decision. It is who makes it, how well, and whether you can see it. A dedicated model gives you six things a language token cannot:

  1. Weights tuned for one job. Every gradient step is spent separating languages, not predicting the next word.
  2. A calibrated confidence. A probability you can threshold, so the system can abstain, ask, or fall back.
  3. Its own time resolution. A decision per turn or per window, rather than one per 30-second chunk or per file.
  4. Its own label space. Languages your recogniser has never seen, and an honest “none of these”.
  5. Its own life cycle. Benchmarked, versioned and rolled back independently of the recogniser.
  6. A small footprint. Small enough to run on a phone or a CPU, in front of any recogniser you choose.

The rest of this post defends that position in three passes: first the theory of why a dedicated objective learns language better, then the linguistic and data realities that make the problem hard, and finally the systems case.

Fig. 4 Coupled vs decoupled the same call, two pipelines · dashed = the path for doubt
Coupled and decoupled language decisions Two panels. (a) Coupled: audio enters a recogniser and text comes out; somewhere inside, a language token is decided where nothing can see it. (b) Decoupled: audio enters a dedicated language identifier, which emits a label and a confidence, here Hindi at 0.97. A router sends that to the recogniser, the language of the reply and the voice that speaks it; a dashed path leads to asking the caller when the confidence is low. (a) Coupled: the recogniser decides Audio ASR Recogniser ⟨language token⟩chosen in here, unseen Text no confidence to read, nothing to abstain with (b) Decoupled: a dedicated identifier decides Audio LID Language identifier LABEL · CONFIDENCE HINDI 0.97 Router ASR Recogniser LLM Reply language TTS Reply voice Ask the caller when confidence is low a probability you can threshold Coupled and decoupled language decisions Two panels. (a) Coupled: audio enters a recogniser and text comes out; somewhere inside, a language token is decided where nothing can see it. (b) Decoupled: audio enters a dedicated language identifier, which emits a label and a confidence, here Hindi at 0.97. A router sends that to the recogniser, the language of the reply and the voice that speaks it; a dashed path leads to asking the caller when the confidence is low. (a) Coupled: the recogniser decides Audio ASR Recogniser ⟨language token⟩chosen in here, unseen Text no confidence to read, nothing to abstain with (b) Decoupled: a dedicated identifier decides Audio LID Language identifier LABEL · CONFIDENCE HINDI 0.97 Router ASR Recogniser LLM Reply TTS Voice Ask the caller low confidence

Inside a recogniser the language decision is a token nothing downstream can inspect. Made by a model of its own, it becomes a label with a confidence, and a router can send the call on, or ask.

Why a dedicated objective learns language better

This is the technical heart of the argument. It rests on three observations: the evidence for language lives in the acoustics, not the text; an autoregressive recogniser spends almost none of its training signal on that evidence; and a dedicated classifier can use a toolkit that a language token cannot.

The signal is far richer than the text

Written Hindi is a few Devanagari characters per word, three bytes each in UTF-8. Across 17 languages, spoken language carries linguistic information at a strikingly constant rate of about 39 bits per second (Coupé et al., 2019). The waveform that carries it runs at 256,000 bits per second (16 kHz, 16-bit), and even a compact 80-band log-Mel front end produces 8,000 numbers a second. That surplus is not noise. It holds the speaker, the room, the channel, the emotion, and, crucially, cues to the language that never reach the page.

Spoken-language-recognition research has long organised those cues into a hierarchy (Li, Ma & Lee, 2013): acoustic-phonetic (which sounds exist), phonotactic (which sequences are allowed), prosodic (rhythm, stress, tone) and lexical. Rhythm alone separates language classes measurably (Ramus, Nespor & Mehler, 1999). Our paper catalogues the cues that matter for India: the degree of retroflexion (stronger in Tamil than Hindi, weaker in Nepali), Hindi’s four-way stop series and Gujarati’s breathy vowels, vowel length that is contrastive in Dravidian languages but not in Bengali or Assamese, lexical tone in Punjabi, Dogri, Bodo and Meitei, and rare segments such as Sindhi implosives and Santali checked finals.

And one thing is missing from speech entirely: script. Devanagari alone serves at least ten of our 23 classes, and Hindi and Urdu are famously “one language, two scripts” (King, 1994). A model trained to emit text must guess a writing system from sound, a variable the audio simply does not contain.

LID is a problem about the acoustic signal. An objective defined on text tokens sees it only indirectly.

What each objective actually optimises

A dedicated LID model minimises a loss on a softmax over languages. Every parameter update follows the gradient of one question: which language?

LLID=− (1−pθ(ℓ∣x))γ log⁡pθ(ℓ∣x)\mathcal{L}_{\text{LID}} = -\,(1 - p_\theta(\ell \mid x))^{\gamma}\,\log p_\theta(\ell \mid x)

Here x is the audio, ℓ the true language, and γ the focal parameter (γ = 0 recovers ordinary cross-entropy). Trained this way, deep classifiers drift toward neural collapse: features of each class tighten around their mean, and the class means spread into a maximally separated, equiangular configuration (Papyan, Han & Donoho, 2020). That is precisely the geometry you want when Hindi, Urdu and Maithili sit a few phonetic cues apart.

An autoregressive recogniser minimises something else: the average surprise of every token in the transcript, with the language token as just the first.

LASR=−1T∑t=1Tlog⁡pθ(yt∣y<t,x),y1=⟨lang⟩\mathcal{L}_{\text{ASR}} = -\frac{1}{T}\sum_{t=1}^{T} \log p_\theta(y_t \mid y_{<t}, x), \qquad y_1 = \langle \text{lang} \rangle

The language term carries a weight of 1/T. In Whisper’s tokenizer we measured about 1.1 tokens per English word and 5.7 per Hindi word, so a 30-second segment yields roughly 85 target tokens in English and 430 in Hindi. The language decision therefore receives about 1% of the supervision in English and about 0.2% in Hindi. The languages that most need a good LID get the smallest share of it. (This is our estimate, not a published measurement.)

Two further details weaken that signal. Whisper’s language targets were not human labels at all: “these language targets are sourced from the aforementioned VoxLingua107 model”, a separate LID classifier (Radford et al., 2023). And in the standard fine-tuning recipe the language token is fixed per dataset, so the “LID” target becomes a constant (Hugging Face, 2022).

Shared weights, competing objectives. When one network serves several objectives, their gradients can conflict, and the dominant objective wins the shared parameters (Yu et al., 2020; Sener & Koltun, 2018; Kendall et al., 2018). Multilingual models show the same pattern as negative interference and the “curse of multilinguality” (Wang, Lipton & Tsvetkov, 2020; Conneau et al., 2020). Inside an autoregressive recogniser, language identification is the minority objective, sharing every weight with next-token prediction.

Reading the wrong layer. A decoder cross-attends to the final encoder layer. But language identity does not peak there. Layer-wise analyses of self-supervised speech models show information shifting across depth (Pasad et al., 2021; Pasad et al., 2023). In our encoder, linear-probe macro-F1 for language rises to 0.56 at blocks 9–11 of the pre-trained model and collapses to 0.13 at block 17. After fine-tuning it peaks at blocks 11–12 (0.86).

The toolkit a language token cannot use

A dedicated model can be shaped around the problem. Each tool below has a literature behind it, and our staged study measured what it is worth.

  • Pooling. Statistics and attentive statistics pooling compress a variable-length utterance into one vector, attending to the few frames that carry a retroflex burst or a tonal contour (Snyder et al., 2018; Okabe et al., 2018). In our study, pooling heads differed by only about 1 point: the head matters less than you would think.
  • Layer aggregation. A learned softmax-weighted sum over every encoder block, as in SUPERB and ELMo’s scalar mix, lets the classifier read language where it lives (Yang et al., 2021; Peters et al., 2018). It added 0.9 points in-domain and lifted every acoustic family: telephony +2.8, noise +1.9, confusable pairs +1.4.
  • The loss decides calibration. Focal loss down-weights easy examples by (1 − p)γ, concentrating gradient on hard, confusable clips (Lin et al., 2017), and improves calibration (Mukhoti et al., 2020). Cosine-margin heads such as AM-Softmax and ArcFace sharpen embeddings but produce badly calibrated scores (Wang et al., 2018; Deng et al., 2019). In our study they reached an expected calibration error of 0.75–0.79; focal loss reached 0.023 with the best macro-F1. Post-hoc temperature scaling (Guo et al., 2017) then cut our all-23 test ECE from 0.054 to 0.008.
  • Sampling for a skewed world. Temperature sampling, pℓ ∝ nℓ1/T, trades head for tail (Arivazhagan et al., 2019). At T = 2 the two languages under 500 hours that the in-domain test covers, Dogri and Konkani, rose from 0.742 to 0.930 F1, and Dogri alone from 0.50 to 0.89. Stacking a second rebalancer (Menon et al., 2021) counted the prior twice and cost 3.5 points in-domain; the two largest classes collapsed, English from 0.906 to 0.699 F1 and Hindi from 0.713 to 0.344.
  • Augmentation aimed at deployment. Duration cropping, MUSAN noise and babble, room impulses, 8 kHz codecs and SpecAugment (Ko et al., 2015; Snyder et al., 2015; Ko et al., 2017; Park et al., 2019). Cropping alone added 9.5 points at 0.5 s; multi-talker babble took our babble conditions from 0.804 to 0.920.
  • Curriculum and weight averaging. A competence curriculum raised the weight of the confusable Indo-Aryan cluster as training progressed (Platanios et al., 2019), and a uniform “soup” of seven checkpoints ranked first of 31 candidates (Wortsman et al., 2022).

None of these levers is available to a language token without retraining the whole recogniser around it. A dedicated model can pull all of them at once.

Fig. 5 The supervision budget one training example’s supervision · each bar = the whole loss
The share of one training example’s supervision that goes to the language Three horizontal bars of equal length. Dedicated LID: the whole bar, 100% of the loss, is the language decision. Autoregressive ASR on a 30-second English segment: a sliver of one token in about 85, roughly 1.2%, is the language token and the rest is transcript tokens. The same for Hindi: one token in about 430, roughly 0.23%. Dedicated LID one label per clip 100% of the loss is the language decision Autoregressive ASR English, 30 s segment 1 token in 85 ≈ 1.2% transcript tokens Autoregressive ASR Hindi, 30 s segment 1 token in 430 ≈ 0.23% transcript tokens Our estimate: 1.1 Whisper tokens per English word, 5.7 per Hindi word. The share of one training example’s supervision that goes to the language Three horizontal bars of equal length. Dedicated LID: the whole bar, 100% of the loss, is the language decision. Autoregressive ASR on a 30-second English segment: a sliver of one token in about 85, roughly 1.2%, is the language token and the rest is transcript tokens. The same for Hindi: one token in about 430, roughly 0.23%. Dedicated LID one label per clip 100% of the loss is the language decision Autoregressive ASR English, 30 s segment 1 token in 85 ≈ 1.2% transcript tokens Autoregressive ASR Hindi, 30 s segment 1 token in 430 ≈ 0.23% transcript tokens Our estimate: 1.1 Whisper tokens per English word, 5.7 per Hindi word.
The numbers
ObjectiveTargets per segmentShare on the language
Dedicated LID1 label100%
Autoregressive ASR, English, 30 s≈ 851 / 85 ≈ 1.2%
Autoregressive ASR, Hindi, 30 s≈ 4301 / 430 ≈ 0.23%

The whole training signal of one example, and how much of it is spent on which language. A dedicated identifier spends all of it on the language. A recogniser spends one token in 85 on it for English and one in 430 for Hindi: the languages that most need a good identifier get the smallest share. Our estimate, not a published measurement.

Fig. 6 Where language lives a 17-block Conformer encoder with one block opened, after Gulati et al. (2020)
The encoder as a stack of 17 Conformer blocks, with one block opened An audio waveform enters at the bottom and becomes log-Mel frames, subsampled four-fold, which pass up through a tower of 17 identical Conformer blocks. Block 11 is opened beside the tower: a half-step feed-forward module, multi-head self-attention, a convolution module and a second half-step feed-forward module, each adding its output back to the residual stream, then LayerNorm. Linear-probe macro-F1 for language is 0.56 at blocks 9 to 11 of the pre-trained model and 0.13 at block 17; after fine-tuning it peaks at 0.86 at blocks 11 and 12, shown in teal. A decoder’s cross-attention reads block 17 only, shown in orange; learned layer weights read all 17 blocks. Block 11, opened every block is built the same way (×17) from block 10 Feed-forward half step Self-attention global context Convolution local context Feed-forward half step LayerNorm the block’s output Feed-forward Self-attention Convolution Feed-forward LayerNorm to block 12 Σ Learned layer weights reads all 17 blocks Conformer block 1 Conformer block 2 Conformer block 3 Conformer block 4 Conformer block 5 Conformer block 6 Conformer block 7 Conformer block 8 Conformer block 9 Conformer block 10 Conformer block 11 Conformer block 12 Conformer block 13 Conformer block 14 Conformer block 15 Conformer block 16 Conformer block 17 DEC Decoder reads block 17 only 0.13pre-trained · block 17 0.86fine-tuned · blocks 11–12 0.56pre-trained · blocks 9–11 linear-probe macro-F1 for language log-Mel frames, subsampled 4× to 40 ms Audio 16 kHz waveform block 1 The encoder as a stack of 17 Conformer blocks, with one block opened An audio waveform enters at the bottom and becomes log-Mel frames, subsampled four-fold, which pass up through a tower of 17 identical Conformer blocks. Block 11 is opened beside the tower: a half-step feed-forward module, multi-head self-attention, a convolution module and a second half-step feed-forward module, each adding its output back to the residual stream, then LayerNorm. Linear-probe macro-F1 for language is 0.56 at blocks 9 to 11 of the pre-trained model and 0.13 at block 17; after fine-tuning it peaks at 0.86 at blocks 11 and 12, shown in teal. A decoder’s cross-attention reads block 17 only, shown in orange; learned layer weights read all 17 blocks. Σ Layer weights reads all 17 Conformer block 1 Conformer block 2 Conformer block 3 Conformer block 4 Conformer block 5 Conformer block 6 Conformer block 7 Conformer block 8 Conformer block 9 Conformer block 10 Conformer block 11 Conformer block 12 Conformer block 13 Conformer block 14 Conformer block 15 Conformer block 16 Conformer block 17 DEC Decoder reads block 17 only 0.13block 17 0.86blocks 11–12 0.56blocks 9–11 0.86 fine-tuned, others pre-trained log-Mel · 4× subsampling Audio Block 11, opened every block is built the same way (×17) from block 10 Feed-forward half step Self-attention multi-head · global context Convolution depthwise · local context Feed-forward half step LayerNorm the block’s output Feed-forward Self-attention Convolution Feed-forward LayerNorm to block 12

Language identity peaks in the middle of the encoder, not at the end. The audio climbs a stack of 17 identical Conformer blocks; a linear probe finds language at 0.56 in blocks 9–11 of the pre-trained model but only 0.13 at block 17, and 0.86 at blocks 11–12 after fine-tuning. A decoder cross-attends to block 17 alone; learned layer weights read all seventeen.

When the language token is wrong, the whole inference breaks

In an autoregressive recogniser the language token is the first domino. Get it right and it is invisible. Get it wrong and every token after it inherits the mistake.

The mechanism: a wrong first token becomes a wrong task

An autoregressive decoder conditions each step on its own earlier outputs. In training it sees the true prefix; at inference it sees its own guesses. That mismatch, known as exposure bias, means an early error is carried forward rather than corrected (Bengio et al., 2015; Ranzato et al., 2016). The language token is the earliest error there is.

Whisper’s training data explains what the model does next. When a clip’s audio language and transcript language disagreed, OpenAI dropped it from recognition training, but “if the transcript language is English” they kept the pair “as X→en speech translation training examples instead” (Radford et al., 2023, §2.1). A mismatch between the language token and the audio is therefore something the model learned to treat as translation. English audio decoded with --language fr comes back as fluent French (openai/whisper #2285). Peng et al. even observed Whisper translating code-switched speech into Mandarin, a direction it was never trained on (Peng et al., 2023).

This is what makes the failure dangerous. The output is fluent, so it looks like success. It belongs with the failure modes the hallucination literature has documented in neural recognisers: output that is “fluent and coherent” but untethered from what was said (Frieske & Shi, 2024); whole invented phrases in about 1% of Whisper transcripts, 38% of which contained explicit harms (Koenecke et al., 2024); and, in Whisper’s own words, “complete hallucination where the model will output a transcript entirely unrelated to actual audio.”

The measurements

When researchers split results by whether the language was identified correctly, the gap is not a few points. It is the difference between a usable transcript and a useless one.

Study Setting Language right Language wrong
Yan, Pratap, Watanabe & Auli, 2024 MMS on FLEURS-102 (14.4% of clips misidentified) 20.8% WER 69.1% WER
Amooie et al., 2026 Bilingual XLS-R, Frisian–Dutch 14.1% WER 53.3% WER
Amooie et al., 2026 Danish–Swedish 20.7% WER 59.7% WER
Amooie et al., 2026 Slovak–Czech 24.5% WER 35.4% WER
Yang, Huang & Lee, 2024 Whisper, Mandarin–English code-switching, token pair 26.8% MER (zh + en) 54.2% MER (zh + es)
Peng et al., 2023 Whisper on SEAME, English words 44.7% WER (zh + en prompt) 85.5% WER (detected token)

Adversaries know this too. By fooling only Whisper’s language detector, Olivier and Raj pushed WER above 100% for Armenian and Lithuanian and to 75% or more for Czech, Danish and Indonesian; outputs became “a mostly nonsensical mix of the true and target language” (Olivier & Raj, 2023).

The same conclusion appears across very different architectures. “Language-agnostic ASR performance highly relies on the accuracy of LID as wrong LID predictions may lead to transcription in the wrong language” (Kwok, Yip & Chng, 2024). “Performance can deteriorate dramatically when LID is absent”, because of “cascaded errors inherent in the implicit language identification and monolingual recognition pipeline” (Li et al., 2025). “A key to understanding their imbalanced performance across different languages is to examine if the model actually knows which language it should transcribe” (Chen et al., 2023). And for CTC models, which have no token at all, the failure shows up as script: they “often fail due to script misprediction… the decoded characters belong to another language altogether” (Omnilingual ASR team, 2025).

In the wild

  • Speech-LLMs. A Google DeepMind study reports that “models often misidentify the output language, compromising transcription fidelity and downstream application quality”; Gemini Flash produced wrong-language output on 0.6–2.2% of clips with no language hint (Kim et al., 2026). At a million calls a day, that is 6,000 to 22,000 wrong-language transcripts.
  • Hindi and Urdu. Whisper users report Hindi detected as Urdu, and Urdu or Persian script even when language='hi' is set (#1662). A Hindi speaker’s audio in a realtime voice agent came back “in japanese, urdu, and some other scripts” (openai-realtime-agents #46).
  • Model upgrades. Whisper large-v3 transcribed an English clip as Indonesian where large-v2 did not; a Hugging Face maintainer called it “a model regression from large-v2 -> v3” (transformers #27937).
  • One decision per file. openai-whisper prints “Detecting language using up to the first 30 seconds” and applies the answer to the entire recording (transcribe.py). Forty seconds of leading silence led whisper.cpp to decide the audio was Catalan (#1104). Whisper’s maintainer is candid: “It’s intended for monolingual audio inputs” (#1160).

Catastrophic WER, then hallucination

Wrong LID not only causes catastrophic WER but also triggers hallucination in autoregressive speech models. The two failures are easy to run together, and the arithmetic of the error rate separates them. Word error rate counts the substitutions, deletions and insertions needed to turn a transcript into what was said, and divides by the number of words said: (S + D + I) / N. A recogniser that writes every word in the wrong script, or translates every word, substitutes all of them and scores 100%. That is catastrophic, but it is bounded: the model is still following the audio, one wrong word for each word spoken, as in Figure 7. Substitutions and deletions can never outnumber the words spoken, so an error rate above 100% has only one source: insertions, words nobody said. Past 100%, a recogniser has invented more words than it recognised.

Error rates past that line turn up wherever the language decision fails. The attack on Whisper’s language detector described above pushed them past it for Armenian and Lithuanian (Olivier & Raj, 2023). On Pashto, where no Whisper model wrote Pashto script in more than 0.8% of utterances, zero-shot word error rates ran from 90% to 297%, and the medium model reached 461% on Common Voice; as the author notes, “a model generating Arabic-script output on Pashto audio has not achieved ASR in any interpretable sense” (Rahman, 2026).

Why the model keeps writing. The training objective explains the second failure. A recogniser trained only to predict the next token has learned that fluent text is rewarded whether or not the audio supports it. Studying LLM-based recognisers, Shivakumar and colleagues describe hallucinations as outputs with “high insertion rates” that “arise when the model deviate from input stimuli (speech signal), prioritizing distributional patterns resulting in semantically and phonetically unrelated outputs”. On meeting audio it was not trained on, their 8-billion-parameter model reached word error rates of 100.26% on headset microphones and 227.98% on distant ones, and on the distant microphones insertions alone came to 195.4 words for every hundred spoken. In the authors’ words, “the WER explodes to greater than 100% which is suggestive of increased hallucinations”. A reinforcement-learning stage that rewards low error rates directly cut those insertions to 9.0 and the error rate to 39.69% (Shivakumar et al., 2025; Figure 7c). The lesson for the language token is direct. It is the strongest “distributional pattern” a decoder is ever handed: it sets the prior for every step that follows. Hand it the wrong one and the model is being asked, from its first step, to prefer its prior to the audio.

The shape of the failure. What follows a wrong token has a recognisable form. The decoder starts in the wrong script or the wrong language, meets words that its prior cannot place, fills them with words that were never spoken, and often falls into a loop, because once a phrase has repeated a few times the repetition is itself the most likely continuation. With 30% of the audio masked, Whisper-small produced 51,797 insertions, 86% of them in such loops, “catastrophic autoregressive cycling where the decoder repeats phrases hundreds of times”; on Indian-accented speech, Whisper-large-v3’s insertion rate reached 9.62% (Ginjala et al., 2026). Long-form decoding “often exhibit[s] hallucinations, repetition loops, and content omissions” (Ahn et al., 2026), and non-speech segments alone are enough to trigger a recurring set of invented phrases (Barański et al., 2025). Figure 7b draws the pattern out word by word for a Hindi, an Urdu and a Maithili caller. Handed the wrong token, the recogniser loops on one phrase twenty times and writes about three times as many words as were spoken, so its error rate climbs to about 300%; handed the right code by a dedicated identifier, it returns the sentence as spoken.

Fig. 7 One clip, three transcripts the same audio · three first tokens
One Hindi clip, three transcripts: only the first token changed One Hindi clip is decoded three times by the same recogniser. With the Hindi language token the transcript is correct Devanagari text, namaste, aap kaise hain, with a word error rate of 0%. With the Urdu token the same words come out in Perso-Arabic script, and with the English token the output is a fluent English translation, Hello, how are you? Scored against what was said, both have a word error rate of 100%. Nothing changed but the first token. CLIP one Hindi utterance, unchanged FIRST TOKEN <|hi|> नमस्ते, आप कैसे हैं? the words, in Devanagari · WER 0% FIRST TOKEN <|ur|> نمستے، آپ کیسے ہیں؟ the same words, in Perso-Arabic script · WER 100% FIRST TOKEN <|en|> Hello, how are you? a translation, not a transcript · WER 100% the audio never changed; only the first token did One Hindi clip, three transcripts: only the first token changed One Hindi clip is decoded three times by the same recogniser. With the Hindi language token the transcript is correct Devanagari text, namaste, aap kaise hain, with a word error rate of 0%. With the Urdu token the same words come out in Perso-Arabic script, and with the English token the output is a fluent English translation, Hello, how are you? Scored against what was said, both have a word error rate of 100%. Nothing changed but the first token. CLIP one Hindi utterance, unchanged FIRST TOKEN <|hi|> नमस्ते, आप कैसे हैं? the words, in Devanagari · WER 0% FIRST TOKEN <|ur|> نمستے، آپ کیسے ہیں؟ same words, Urdu script · WER 100% FIRST TOKEN <|en|> Hello, how are you? a translation · WER 100% the audio never changed; only the first token did

The same Hindi audio, decoded with the Hindi, Urdu and English language tokens. Only the first token changed; the recogniser followed it into another script and then into another language. Scored against what was said, both wrong transcripts have a word error rate of 100%, though one of them holds exactly the right words. That is the catastrophic half of the failure; Figure 7b shows the other half, hallucination.

Fig. 7b What the wrong token does, word by word constructed example · red = invented or repeated · amber = wrong word or script · teal = as spoken
What the wrong first token does to a transcript, word by word Wrong LID not only causes catastrophic WER but also triggers hallucination in autoregressive speech models. Three constructed examples under one switch: a Hindi caller tagged Urdu, an Urdu caller tagged Hindi, a Maithili caller tagged Hindi. In each, the coupled recogniser writes in the wrong script or the wrong language, repeats one phrase 20 times, invents words, and writes about three times as many words as were spoken (Hindi: 57 for 19, word error rate 300%; Urdu: 59 for 20, word error rate 295%; Maithili: 55 for 16, word error rate 306%). Past 100%, a transcript holds more invented words than recognised ones. Given the right code by a dedicated identifier, the same recogniser returns the sentence as spoken, with a word error rate of 0%. Wrong LID not only causes catastrophic WER but also triggers hallucination in autoregressive speech models. SPOKEN Hindi, as the caller said it · 19 words

कल शाम चौपाल पर पंचायत ने नहर की मरम्मत का फ़ैसला किया और गाँव ने राहत की साँस ली।

(a) Coupled: the recogniser is handed the wrong token FIRST TOKEN <|ur|> the caller speaks Hindi loops on ⁨نہر کی⁩ ×20

کل شام چوپال پر پنچایت نے نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی مرمت کا فیصلہ کیا اور گاؤں نے راحت کی سانس لی

WER 300% CER 246% 57 words written for 19 spoken past 100%: more words invented than recognised
(b) Decoupled: a dedicated identifier supplies the code LID → TOKEN <|hi|> Hindi, with 0.97 confidence no loop, nothing invented

कल शाम चौपाल पर पंचायत ने नहर की मरम्मत का फ़ैसला किया और गाँव ने राहत की साँस ली।

WER 0% CER 0% 19 words written for 19 spoken 100%
SPOKEN Urdu, as the caller said it · 20 words

محفلِ مشاعرہ میں غزل کے مقطع پر سامعین نے بے ساختہ داد دی اور شاعر کی تخلیقی جرأت کو سراہا۔

(a) Coupled: the recogniser is handed the wrong token FIRST TOKEN <|hi|> the caller speaks Urdu loops on ⁨दाद दी⁩ ×20

महफ़िल में शायरी में गजल के मकते पर समय में बेसाख्ता दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी और शायर की तख़्त की ज़रूरत को सराहा

WER 295% CER 239% 59 words written for 20 spoken past 100%: more words invented than recognised
(b) Decoupled: a dedicated identifier supplies the code LID → TOKEN <|ur|> Urdu, with 0.97 confidence no loop, nothing invented

محفلِ مشاعرہ میں غزل کے مقطع پر سامعین نے بے ساختہ داد دی اور شاعر کی تخلیقی جرأت کو سراہا۔

WER 0% CER 0% 20 words written for 20 spoken 100%
SPOKEN Maithili, as the caller said it · 16 words

हम काल्हि भोरे गाम सँ शहर जाएब आ साँझ धरि घुरि आएब, बाबूजी केँ कहि देबनि।

(a) Coupled: the recogniser is handed the wrong token FIRST TOKEN <|hi|> the caller speaks Maithili loops on ⁨शाम तक⁩ ×20

हम कल भोर में गाँव से शहर जाएंगे और शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक घूम आएंगे, बाबूजी केँ कहि देबनि।

WER 306% CER 213% 55 words written for 16 spoken past 100%: more words invented than recognised
(b) Decoupled: a dedicated identifier supplies the code LID → TOKEN mai Maithili, with 0.97 confidence no loop, nothing invented

हम काल्हि भोरे गाम सँ शहर जाएब आ साँझ धरि घुरि आएब, बाबूजी केँ कहि देबनि।

WER 0% CER 0% 16 words written for 16 spoken 100%
invented or repeated wrong word, or the wrong script as spoken
What the wrong first token does to a transcript, word by word Wrong LID not only causes catastrophic WER but also triggers hallucination in autoregressive speech models. Three constructed examples under one switch: a Hindi caller tagged Urdu, an Urdu caller tagged Hindi, a Maithili caller tagged Hindi. In each, the coupled recogniser writes in the wrong script or the wrong language, repeats one phrase 20 times, invents words, and writes about three times as many words as were spoken (Hindi: 57 for 19, word error rate 300%; Urdu: 59 for 20, word error rate 295%; Maithili: 55 for 16, word error rate 306%). Past 100%, a transcript holds more invented words than recognised ones. Given the right code by a dedicated identifier, the same recogniser returns the sentence as spoken, with a word error rate of 0%. Wrong LID not only causes catastrophic WER but also triggers hallucination in autoregressive speech models. SPOKEN Hindi, as the caller said it · 19 words

कल शाम चौपाल पर पंचायत ने नहर की मरम्मत का फ़ैसला किया और गाँव ने राहत की साँस ली।

(a) Coupled: the wrong token FIRST TOKEN <|ur|> the caller speaks Hindi loops on ⁨نہر کی⁩ ×20

کل شام چوپال پر پنچایت نے نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی نہر کی مرمت کا فیصلہ کیا اور گاؤں نے راحت کی سانس لی

WER 300% CER 246% 57 words written for 19 spoken past 100%: more words invented than recognised
(b) Decoupled: the right code LID → TOKEN <|hi|> Hindi, with 0.97 confidence no loop, nothing invented

कल शाम चौपाल पर पंचायत ने नहर की मरम्मत का फ़ैसला किया और गाँव ने राहत की साँस ली।

WER 0% CER 0% 19 words written for 19 spoken 100%
SPOKEN Urdu, as the caller said it · 20 words

محفلِ مشاعرہ میں غزل کے مقطع پر سامعین نے بے ساختہ داد دی اور شاعر کی تخلیقی جرأت کو سراہا۔

(a) Coupled: the wrong token FIRST TOKEN <|hi|> the caller speaks Urdu loops on ⁨दाद दी⁩ ×20

महफ़िल में शायरी में गजल के मकते पर समय में बेसाख्ता दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी दाद दी और शायर की तख़्त की ज़रूरत को सराहा

WER 295% CER 239% 59 words written for 20 spoken past 100%: more words invented than recognised
(b) Decoupled: the right code LID → TOKEN <|ur|> Urdu, with 0.97 confidence no loop, nothing invented

محفلِ مشاعرہ میں غزل کے مقطع پر سامعین نے بے ساختہ داد دی اور شاعر کی تخلیقی جرأت کو سراہا۔

WER 0% CER 0% 20 words written for 20 spoken 100%
SPOKEN Maithili, as the caller said it · 16 words

हम काल्हि भोरे गाम सँ शहर जाएब आ साँझ धरि घुरि आएब, बाबूजी केँ कहि देबनि।

(a) Coupled: the wrong token FIRST TOKEN <|hi|> the caller speaks Maithili loops on ⁨शाम तक⁩ ×20

हम कल भोर में गाँव से शहर जाएंगे और शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक शाम तक घूम आएंगे, बाबूजी केँ कहि देबनि।

WER 306% CER 213% 55 words written for 16 spoken past 100%: more words invented than recognised
(b) Decoupled: the right code LID → TOKEN mai Maithili, with 0.97 confidence no loop, nothing invented

हम काल्हि भोरे गाम सँ शहर जाएब आ साँझ धरि घुरि आएब, बाबूजी केँ कहि देबनि।

WER 0% CER 0% 16 words written for 16 spoken 100%
invented or repeated wrong word, or the wrong script as spoken
The caller's language

Wrong LID not only causes catastrophic WER but also triggers hallucination in autoregressive speech models. Handed the wrong first token, the recogniser writes in the wrong script or the wrong language, falls into a loop that writes one phrase 20 times, invents words that were never said, and finds its way back only at the end. It writes about three times as many words as the caller spoke, so its word error rate climbs to about 300%; past 100%, a transcript holds more invented words than recognised ones. Given the right code by a dedicated identifier, the same recogniser returns the sentence as spoken. The sentences are constructed to show the documented pattern, not recorded model outputs, and the error rates are those of the illustration; real loops run longer still, with Whisper repeating a phrase hundreds of times (Ginjala et al., 2026).

Fig. 7c Past 100%, the errors are words nobody said Shivakumar et al., 2025, Table III · LLM-based recognisers on meeting audio they were not trained on · per 100 words spoken
Word error rate split into substitutions, deletions and insertions, before and after a reward on word error rate A stacked bar chart from Shivakumar et al. (2025), Table III: LLM-based recognisers of 8 and 2 billion parameters on AMI meeting audio they were not trained on. Each bar is a word error rate, split into substitutions, then deletions, then insertions, per 100 words spoken. 8B model, distant microphones: trained on the next token only, 227.98% with 195.4 insertions; after the reward, 39.69% with 9.0. 8B model, headset microphones: trained on the next token only, 100.26% with 82 insertions; after the reward, 22.16% with 4.6. 2B model, distant microphones: trained on the next token only, 87.88% with 56.7 insertions; after the reward, 37.59% with 7.4. 2B model, headset microphones: trained on the next token only, 56.0% with 38.4 insertions; after the reward, 20.0% with 2.8. Substitutions and deletions can never pass 100%, so everything past the 100% line is inserted words. 0 50% 100% 150% 200% 8B model, distant microphones (AMI-SDM), trained on the next token only (SFT): word error rate 227.98%; insertions 195.4, deletions 17.4, substitutions 15.3 per 100 words spoken next token only 195.4 inserted 8B model, distant microphones (AMI-SDM), after the reward on word error rate (GRPO): word error rate 39.69%; insertions 9.0, deletions 20.2, substitutions 10.5 per 100 words spoken + WER reward 8B model distant microphones · AMI-SDM 8B model, headset microphones (AMI-IHM), trained on the next token only (SFT): word error rate 100.26%; insertions 82, deletions 10.5, substitutions 7.7 per 100 words spoken next token only 82 inserted 8B model, headset microphones (AMI-IHM), after the reward on word error rate (GRPO): word error rate 22.16%; insertions 4.6, deletions 11.6, substitutions 6.0 per 100 words spoken + WER reward 8B model headset microphones · AMI-IHM 2B model, distant microphones (AMI-SDM), trained on the next token only (SFT): word error rate 87.88%; insertions 56.7, deletions 16.6, substitutions 14.6 per 100 words spoken next token only 56.7 inserted 2B model, distant microphones (AMI-SDM), after the reward on word error rate (GRPO): word error rate 37.59%; insertions 7.4, deletions 18.1, substitutions 12.1 per 100 words spoken + WER reward 2B model distant microphones · AMI-SDM 2B model, headset microphones (AMI-IHM), trained on the next token only (SFT): word error rate 56.0%; insertions 38.4, deletions 10.3, substitutions 7.3 per 100 words spoken next token only 2B model, headset microphones (AMI-IHM), after the reward on word error rate (GRPO): word error rate 20.0%; insertions 2.8, deletions 10.96, substitutions 6.3 per 100 words spoken + WER reward 2B model headset microphones · AMI-IHM past this line, every error is a word nobody said; substitutions and deletions can never cross it 227.98% 39.69% 100.26% 22.16% 87.88% 37.59% 56.0% 20.0% substitutions: wrong words deletions: words left out insertions: words nobody said Word error rate split into substitutions, deletions and insertions, before and after a reward on word error rate A stacked bar chart from Shivakumar et al. (2025), Table III: LLM-based recognisers of 8 and 2 billion parameters on AMI meeting audio they were not trained on. Each bar is a word error rate, split into substitutions, then deletions, then insertions, per 100 words spoken. 8B model, distant microphones: trained on the next token only, 227.98% with 195.4 insertions; after the reward, 39.69% with 9.0. 8B model, headset microphones: trained on the next token only, 100.26% with 82 insertions; after the reward, 22.16% with 4.6. 2B model, distant microphones: trained on the next token only, 87.88% with 56.7 insertions; after the reward, 37.59% with 7.4. 2B model, headset microphones: trained on the next token only, 56.0% with 38.4 insertions; after the reward, 20.0% with 2.8. Substitutions and deletions can never pass 100%, so everything past the 100% line is inserted words. 0 50% 100% 150% 200% 8B model · distant microphones 8B model, distant microphones (AMI-SDM), trained on the next token only (SFT): word error rate 227.98%; insertions 195.4, deletions 17.4, substitutions 15.3 per 100 words spoken next token only 195.4 inserted 8B model, distant microphones (AMI-SDM), after the reward on word error rate (GRPO): word error rate 39.69%; insertions 9.0, deletions 20.2, substitutions 10.5 per 100 words spoken + WER reward 8B model · headset microphones 8B model, headset microphones (AMI-IHM), trained on the next token only (SFT): word error rate 100.26%; insertions 82, deletions 10.5, substitutions 7.7 per 100 words spoken next token only 82 inserted 8B model, headset microphones (AMI-IHM), after the reward on word error rate (GRPO): word error rate 22.16%; insertions 4.6, deletions 11.6, substitutions 6.0 per 100 words spoken + WER reward 2B model · distant microphones 2B model, distant microphones (AMI-SDM), trained on the next token only (SFT): word error rate 87.88%; insertions 56.7, deletions 16.6, substitutions 14.6 per 100 words spoken next token only 2B model, distant microphones (AMI-SDM), after the reward on word error rate (GRPO): word error rate 37.59%; insertions 7.4, deletions 18.1, substitutions 12.1 per 100 words spoken + WER reward 2B model · headset microphones 2B model, headset microphones (AMI-IHM), trained on the next token only (SFT): word error rate 56.0%; insertions 38.4, deletions 10.3, substitutions 7.3 per 100 words spoken next token only 2B model, headset microphones (AMI-IHM), after the reward on word error rate (GRPO): word error rate 20.0%; insertions 2.8, deletions 10.96, substitutions 6.3 per 100 words spoken + WER reward past the 100% mark: inserted words only 227.98% 39.69% 100.26% 22.16% 87.88% 37.59% 56.0% 20.0% substitutions: wrong words deletions: words left out insertions: words nobody said
The numbers
Insertions, deletions and substitutions per 100 words spoken, and word error rate, from Shivakumar et al. (2025), Table III
System, audio and trainingInsertionsDeletionsSubstitutionsWER
8B, distant microphones (AMI-SDM), trained on the next token only (SFT)195.417.415.3227.98%
8B, distant microphones (AMI-SDM), after the reward on word error rate (GRPO)9.020.210.539.69%
8B, headset microphones (AMI-IHM), trained on the next token only (SFT)8210.57.7100.26%
8B, headset microphones (AMI-IHM), after the reward on word error rate (GRPO)4.611.66.022.16%
2B, distant microphones (AMI-SDM), trained on the next token only (SFT)56.716.614.687.88%
2B, distant microphones (AMI-SDM), after the reward on word error rate (GRPO)7.418.112.137.59%
2B, headset microphones (AMI-IHM), trained on the next token only (SFT)38.410.37.356.0%
2B, headset microphones (AMI-IHM), after the reward on word error rate (GRPO)2.810.966.320.0%

Past 100%, a word error rate is made of words nobody said. Each bar splits the error into substitutions, deletions and insertions; the first two can never outnumber the words spoken, so whatever crosses the 100% line is insertions. Trained only to predict the next token, the 8-billion-parameter recogniser inserted 195.4 words for every hundred spoken on the distant microphones, and its error rate reached 227.98%. After a reinforcement-learning stage that rewards low word error rate, the same model inserted 9.0 and scored 39.69%. This audio is out of domain rather than mislabelled, but the mechanism is the one a wrong language token sets off: a decoder that follows its prior instead of the audio.

Data and linguistic constraints: where the problem gets hard

On clean, long, read speech in well-resourced languages, LID looks solved. Deployed audio is none of those things. The two largest multilingual speech efforts of the decade open with the same admission. MMS: “current speech technology is restricted to about one hundred languages which is a small fraction of the over 7,000 languages spoken around the world” (Pratap et al., 2024). Omnilingual ASR: “most of the world’s 7,000+ languages remain unsupported, leaving thousands of long-tail languages behind. Expanding ASR coverage has been costly and limited by architectures that restrict language support” (Omnilingual ASR team, 2025).

LID inherits both halves of that problem. Few languages have data, and the ones that sound alike crowd each other. India has both at once.

Twenty-two languages by constitutional design

India’s Eighth Schedule began with 14 languages. Sindhi was added in 1967; Konkani, Manipuri and Nepali in 1992; Bodo, Dogri, Maithili and Santali in 2004 (Ministry of Home Affairs, 2017). English is an official language of the Union by statute but is not scheduled (Official Languages Act, 1963).

The 2011 Census rationalised 19,569 raw mother-tongue returns into 1,369 mother tongues and grouped them into 121 languages; 96.71% of the population returned a scheduled language. Speaker numbers span four orders of magnitude, from Hindi (528M, 43.6%) to Bodo (1.5M) and Sanskrit (24,821) (Office of the Registrar General, 2018). The labels are administrative, not uniform linguistic units. The Census category “Hindi” groups 56 mother tongues, including Bhojpuri (50.6M), Rajasthani (25.8M), Chhattisgarhi (16.2M) and Magahi (12.7M), and Maithili itself was counted under Hindi until 2001. The government notes that no fixed criterion separates a language from a dialect. An LID system must learn class boundaries that are partly conventional.

Four families, one linguistic area

Fifteen scheduled languages are Indo-Aryan, four Dravidian, two Tibeto-Burman and one Austroasiatic (Munda). Indo-Aryan speakers make up 78.1% of the population and Dravidian speakers 19.6% (Glottolog 5.3; Census 2011).

Genealogy understates how alike these languages sound. Emeneau (1956) described India as a linguistic area: across families, most languages have retroflex consonants contrasting with dentals, verb-final clauses with postpositions, chains of conjunctive participles and echo words. Masica (1976) extended the analysis. Retroflex systems are distributed geographically rather than genetically (Arsenault, 2017), and Assamese is a notable exception, having merged dentals and retroflexes into alveolars (Mahanta, 2012). Indian LID research has accordingly noted heavily overlapping phone sets (Dey, Sahidullah & Saha, 2022). On FLEURS, the South Asian group has the lowest LID accuracy of any language group (Conneau et al., 2023).

Close relatives and dialect continua

Several scheduled languages are sisters, or former “dialects”, of one another:

  • Hindi and Urdu are sister languoids under Hindustani and share one colloquial form (Hammarström et al., 2026; Kachru, 2008). Urdu→Hindi is the single most common error in VoxLingua107 (Valk & Alumäe, 2021).
  • Punjabi and Dogri share 93% of basic vocabulary (Kogan, 2016), and Grierson (1916) described Dogri as a dialect of Punjabi.
  • Konkani and Marathi share 80–82% of basic vocabulary; Grierson (1905) treated Konkani as a Marathi dialect.
  • Assamese, Bengali and Odia share 86–88% of basic vocabulary and one Glottolog node, and share numeral-classifier morphology with Maithili (Emeneau, 1956).
  • Maithili speakers from the eastern dialect area commonly shift to Hindi when talking to speakers from other regions (Central Institute of Indian Languages).

Lexicostatistics measures vocabulary, not acoustics. But these are exactly the pairs where LID systems err, ours included: Hindi→Maithili (4.7% of Hindi clips), Urdu→Hindi (4.0%), Odia→Assamese (3.3%), Konkani→Marathi (2.3%). Some confusions cross family lines but not geography: Assamese→Bodo (3.0%) and Manipuri→Bodo (2.7%) reflect centuries of contact in north-eastern India, an areal similarity that no family tree records (Thomason, 2000). Of all our residual errors, 61% stay within the reference language’s family.

Fig. 8 A map of confusion share of clips mislabelled · arrow width = error rate · coastlines only
Where the confusions fall: six of the largest, on a map of South Asia A map of South Asia drawn from coastlines only, with the scheduled languages placed roughly by region. Arrows run from the language spoken to the label it received, their width the error rate: Hindi to Maithili, 4.7% of Hindi clips; Urdu to Hindi, 4% of Urdu clips; Odia to Assamese, 3.3% of Odia clips; Assamese to Bodo, 3% of Assamese clips; Manipuri to Bodo, 2.7% of Manipuri clips; Konkani to Marathi, 2.3% of Konkani clips. Sanskrit and English have no single region and are not placed. Hindi Urdu Maithili Bengali Odia Assamese Bodo Manipuri Nepali Santali Punjabi Dogri Kashmiri Gujarati Sindhi Marathi Konkani Kannada Telugu Tamil Malayalam Share of clips mislabelled Hindi → Maithili 4.7% Urdu → Hindi 4.0% Odia → Assamese 3.3% Assamese → Bodo 3.0% Manipuri → Bodo 2.7% Konkani → Marathi 2.3% Coastlines only; no borders drawn. Sanskrit and English have no one region. Where the confusions fall: six of the largest, on a map of South Asia A map of South Asia drawn from coastlines only, with the scheduled languages placed roughly by region. Arrows run from the language spoken to the label it received, their width the error rate: Hindi to Maithili, 4.7% of Hindi clips; Urdu to Hindi, 4% of Urdu clips; Odia to Assamese, 3.3% of Odia clips; Assamese to Bodo, 3% of Assamese clips; Manipuri to Bodo, 2.7% of Manipuri clips; Konkani to Marathi, 2.3% of Konkani clips. Sanskrit and English have no single region and are not placed. Hindi Urdu Maithili Bengali Odia Assamese Bodo Manipuri Nepali Santali Punjabi Dogri Kashmiri Gujarati Sindhi Marathi Konkani Kannada Telugu Tamil Malayalam Share of clips mislabelled Hindi → Maithili 4.7% Urdu → Hindi 4.0% Odia → Assamese 3.3% Assamese → Bodo 3.0% Manipuri → Bodo 2.7% Konkani → Marathi 2.3% Coastlines only; no borders drawn. Sanskrit and English have no one region.
The numbers
SpokenLabelled asShare of clips
HindiMaithili4.7%
UrduHindi4.0%
OdiaAssamese3.3%
AssameseBodo3.0%
ManipuriBodo2.7%
KonkaniMarathi2.3%

Errors follow geography and history. The largest confusions run between sisters and neighbours: Hindi→Maithili, Urdu→Hindi, Konkani→Marathi and Odia→Assamese within a family; Assamese→Bodo and Manipuri→Bodo across family lines but not across the north-east. Languages are placed roughly by region; the map shows coastlines only.

Scarce and skewed data

Speech resources do not track population. Urdu has more than 50 million first-language speakers but less audio in our pool than Maithili or Nepali, while English is abundant because most of its 128.5 million Indian speakers use it as a second or third language. Our 54,643-hour training pool holds 13,039 hours of English and 369 of Kashmiri, a 35-fold imbalance. Most openly available LID models cover only 15–21 of the 23 classes.

Low-resource languages are left with scarce training data. Figure 9 sets every class’s hours in our pool against its first-language speakers. The head is heavy: eight classes have more than 2,000 hours each, led by English (13,039) and Hindi (8,121), and together they hold 76% of the pool. The tail is thin: Kashmiri (369 hours), Konkani (375), Sindhi (390), Santali (394) and Dogri (478) have under 500 hours each, though each is the first language of 2.3 to 7.4 million people, and Manipuri (539) and Bodo (590) are barely above them. Between them the five scarcest hold 2,006 hours, under 4% of the pool and less than a sixth of what English has on its own. Per speaker the spread is wider still: about 15 hours per million speakers for Hindi and 14 for Urdu, but nearly 400 for Nepali and Bodo, so a language’s size does not predict how much of it a model will hear.

This is a pool assembled for a dedicated identifier from 18 corpora, and it is still thin enough to constrain the research: the balanced 1,000-hour subset of our first experiments could hold only 20 of the 23 classes, because Kashmiri, Santali and Sindhi had too little audio at that scale. In our staged study, trained on the natural distribution, the two languages under 500 hours that the in-domain test covers, Dogri and Konkani, reached 0.742 F1 against 0.949 for the eight largest; temperature sampling, described above, closed most of that gap.

Fig. 9 Training data does not follow speakers hours in the 54,643-hour Anuvani-LID training pool against first-language speakers (Census 2011), both log scale · diagonals: hours per million speakers
Training hours against first-language speakers for the 23 classes, both on log scales A scatter plot of the 23 classes in the Anuvani-LID training pool. Speakers run from 24,821 for Sanskrit to 528 million for Hindi; training hours from 369 for Kashmiri to 13,039 for English, a 35-fold spread. Five languages have under 500 hours: Kashmiri (369 hours, 6.8 million speakers), Konkani (375 hours, 2.3 million speakers), Sindhi (390 hours, 2.8 million speakers), Santali (394 hours, 7.4 million speakers), Dogri (478 hours, 2.6 million speakers). Urdu has 50.8 million speakers but 691 hours, less than Maithili (2,143) or Nepali (1,150). English has 13,039 hours for 0.26 million first-language speakers, or 128.5 million counting second and third languages. Diagonal lines mark 10, 100 and 1,000 training hours per million speakers. 300 1,000 3,000 10,000 10k 100k 1M 10M 100M 1B first-language speakers, Census 2011 (log scale) training hours in the pool (log scale) English: 0.26M first-language speakers, 128.5M counting second and third languages; 13,039 h of training audio Hindi: 528.3M first-language speakers, 8,121 h of training audio (15.4 h per million speakers) Urdu: 50.8M first-language speakers, 691 h of training audio (13.6 h per million speakers) Punjabi: 33.1M first-language speakers, 1,339 h of training audio (40.5 h per million speakers) Dogri: 2.6M first-language speakers, 478 h of training audio (184 h per million speakers) Kashmiri: 6.8M first-language speakers, 369 h of training audio (54.3 h per million speakers) Sindhi: 2.8M first-language speakers, 390 h of training audio (139 h per million speakers) Nepali: 2.9M first-language speakers, 1,150 h of training audio (397 h per million speakers) Maithili: 13.6M first-language speakers, 2,143 h of training audio (158 h per million speakers) Bengali: 97.2M first-language speakers, 3,517 h of training audio (36.2 h per million speakers) Assamese: 15.3M first-language speakers, 987 h of training audio (64.5 h per million speakers) Odia: 37.5M first-language speakers, 1,827 h of training audio (48.7 h per million speakers) Marathi: 83M first-language speakers, 4,792 h of training audio (57.7 h per million speakers) Konkani: 2.3M first-language speakers, 375 h of training audio (163 h per million speakers) Gujarati: 55.5M first-language speakers, 1,500 h of training audio (27.0 h per million speakers) Sanskrit: 24,821 first-language speakers, 828 h of training audio (33,359 h per million speakers) Tamil: 69M first-language speakers, 3,560 h of training audio (51.6 h per million speakers) Malayalam: 34.8M first-language speakers, 1,544 h of training audio (44.4 h per million speakers) Kannada: 43.7M first-language speakers, 3,287 h of training audio (75.2 h per million speakers) Telugu: 81.1M first-language speakers, 3,184 h of training audio (39.3 h per million speakers) Bodo: 1.5M first-language speakers, 590 h of training audio (393 h per million speakers) Manipuri: 1.8M first-language speakers, 539 h of training audio (299 h per million speakers) Santali: 7.4M first-language speakers, 394 h of training audio (53.2 h per million speakers) under 500 h each: the five lowest-resource languages 10 h per M 100 h per M 1,000 h per M Indo-Aryan Dravidian Tibeto-Burman Austroasiatic Germanic (English) English: 0.26M speak it first, 128.5M in all Sindhi Kannada Punjabi Dogri Bengali Odia Marathi Konkani Tamil Telugu Bodo Manipuri Gujarati Malayalam Kashmiri Assamese Santali Hindi Urdu Nepali Maithili Sanskrit Training hours against first-language speakers for the 23 classes, both on log scales A scatter plot of the 23 classes in the Anuvani-LID training pool. Speakers run from 24,821 for Sanskrit to 528 million for Hindi; training hours from 369 for Kashmiri to 13,039 for English, a 35-fold spread. Five languages have under 500 hours: Kashmiri (369 hours, 6.8 million speakers), Konkani (375 hours, 2.3 million speakers), Sindhi (390 hours, 2.8 million speakers), Santali (394 hours, 7.4 million speakers), Dogri (478 hours, 2.6 million speakers). Urdu has 50.8 million speakers but 691 hours, less than Maithili (2,143) or Nepali (1,150). English has 13,039 hours for 0.26 million first-language speakers, or 128.5 million counting second and third languages. Diagonal lines mark 10, 100 and 1,000 training hours per million speakers. 300 1,000 3,000 10,000 10k 100k 1M 10M 100M 1B first-language speakers, Census 2011 training hours (log scale) English: 0.26M first-language speakers, 128.5M counting second and third languages; 13,039 h of training audio Hindi: 528.3M first-language speakers, 8,121 h of training audio (15.4 h per million speakers) Urdu: 50.8M first-language speakers, 691 h of training audio (13.6 h per million speakers) Punjabi: 33.1M first-language speakers, 1,339 h of training audio (40.5 h per million speakers) Dogri: 2.6M first-language speakers, 478 h of training audio (184 h per million speakers) Kashmiri: 6.8M first-language speakers, 369 h of training audio (54.3 h per million speakers) Sindhi: 2.8M first-language speakers, 390 h of training audio (139 h per million speakers) Nepali: 2.9M first-language speakers, 1,150 h of training audio (397 h per million speakers) Maithili: 13.6M first-language speakers, 2,143 h of training audio (158 h per million speakers) Bengali: 97.2M first-language speakers, 3,517 h of training audio (36.2 h per million speakers) Assamese: 15.3M first-language speakers, 987 h of training audio (64.5 h per million speakers) Odia: 37.5M first-language speakers, 1,827 h of training audio (48.7 h per million speakers) Marathi: 83M first-language speakers, 4,792 h of training audio (57.7 h per million speakers) Konkani: 2.3M first-language speakers, 375 h of training audio (163 h per million speakers) Gujarati: 55.5M first-language speakers, 1,500 h of training audio (27.0 h per million speakers) Sanskrit: 24,821 first-language speakers, 828 h of training audio (33,359 h per million speakers) Tamil: 69M first-language speakers, 3,560 h of training audio (51.6 h per million speakers) Malayalam: 34.8M first-language speakers, 1,544 h of training audio (44.4 h per million speakers) Kannada: 43.7M first-language speakers, 3,287 h of training audio (75.2 h per million speakers) Telugu: 81.1M first-language speakers, 3,184 h of training audio (39.3 h per million speakers) Bodo: 1.5M first-language speakers, 590 h of training audio (393 h per million speakers) Manipuri: 1.8M first-language speakers, 539 h of training audio (299 h per million speakers) Santali: 7.4M first-language speakers, 394 h of training audio (53.2 h per million speakers) under 500 h each: the five scarcest 10 h/M 100 h/M 1,000 h/M Indo-Aryan Dravidian Tibeto-Burman Austroasiatic Germanic (English) English: 0.26M first, 128.5M in all Dogri Sindhi Konkani Manipuri Kashmiri Malayalam Santali Punjabi Bengali Assamese Odia Marathi Gujarati Tamil Kannada Telugu Bodo Maithili Urdu Nepali Hindi Sanskrit
The numbers
The 23 classes by training hours, with first-language speakers from the 2011 Census
LanguageFamilyFirst-language speakers (millions)Training hoursHours per million speakers
EnglishGermanic (English)0.26 (128.5 in all)13,03950,150 (101 in all)
HindiIndo-Aryan528.38,12115.4
MarathiIndo-Aryan834,79257.7
TamilDravidian693,56051.6
BengaliIndo-Aryan97.23,51736.2
KannadaDravidian43.73,28775.2
TeluguDravidian81.13,18439.3
MaithiliIndo-Aryan13.62,143158
OdiaIndo-Aryan37.51,82748.7
MalayalamDravidian34.81,54444.4
GujaratiIndo-Aryan55.51,50027.0
PunjabiIndo-Aryan33.11,33940.5
NepaliIndo-Aryan2.91,150397
AssameseIndo-Aryan15.398764.5
SanskritIndo-Aryan0.02582833,359
UrduIndo-Aryan50.869113.6
BodoTibeto-Burman1.5590393
ManipuriTibeto-Burman1.8539299
DogriIndo-Aryan2.6478184
SantaliAustroasiatic7.439453.2
SindhiIndo-Aryan2.8390139
KonkaniIndo-Aryan2.3375163
KashmiriIndo-Aryan6.836954.3

Training audio does not follow speakers. Speaker numbers span four orders of magnitude, from Hindi’s 528 million to Sanskrit’s 24,821; training hours run from English’s 13,039 to Kashmiri’s 369, a 35-fold spread. Five scheduled languages have under 500 hours each (Kashmiri 369, Konkani 375, Sindhi 390, Santali 394, Dogri 478), though each is the first language of 2.3 to 7.4 million people. Urdu has more than 50 million speakers but less audio than Maithili or Nepali, and English is abundant because most of its 128.5 million speakers use it as a second or third language. The diagonals mark 10, 100 and 1,000 training hours per million speakers.

General-purpose ASR is skewed further still. Of Whisper’s 680,000 training hours, 65% are English; 98 other languages share 117,000 hours, and “WER halves for every 16× increase in training data” (model card; Radford et al., 2023). Whisper has no language token at all for 8 of the 22 scheduled languages: Odia, Maithili, Konkani, Dogri, Bodo, Santali, Manipuri and Kashmiri (tokenizer.py). Omnilingual ASR trains on 63,592 hours of English but 236.7 of Hindi, 7.6 of Manipuri (character error rate 51.1%) and 7.3 of Kashmiri (165.8%) (results table).

Here a dedicated LID has a structural advantage that is easy to miss. A recogniser needs transcripts; a language identifier needs one label per clip. The IISc Vaani corpus holds 205.5 hours of Manipuri audio but 0.46 hours transcribed; 465.5 hours of Maithili against 20.8; 31.5 hours of Kashmiri against 0.06 (Vaani). IndicVoices collected 7,348 hours and transcribed 1,639 (Javed et al., 2024). A standalone LID can learn from all of that audio. A joint recogniser can learn language only from the transcribed slice. For the hardest, lowest-resource languages, that is a 20- to 500-fold difference in usable data.

The speaker: multilingual, code-mixing, accented

In 2011, 26.0% of Indians reported a second language and 7.1% a third (Census 2011, Table C-17). About 17% of Hindi–English social-media posts mix languages (Bali et al., 2014), and in code-switched speech more than half of the embedded segments last only 200–400 ms (Barras et al., 2020): shorter than many single words. The language changes faster than any 30-second window can follow. Language diarization, locating where each language is spoken, has become its own benchmark on Indian conversations, and it is far from solved: the best team at DISPLACE 2024 still had a 25.05% language-diarization error rate (Baghel et al., 2023; Kalluri et al., 2024).

“India is not a contest over who can post the best accuracy number. It is a man on a four-thousand-rupee phone, a ceiling fan whirring overhead, who begins a sentence in Hindi, finishes it in Bengali, and drops an Indian-accented English word somewhere in the middle.”

That English word is its own challenge. English has only 0.26 million first-language speakers in India but 128.5 million speakers in total. Indian English is an L1-influenced variety (Kachru, 1983), with apical, often retroflex /t d/, a merged /v/–/w/ and syllable-based timing (Masica, 1972; Wiltshire & Harnsberger, 2006). Acoustically, it sits closer to the other 22 classes than native English does. General-purpose LID struggles here: in one study, per-speaker accuracy on English ranged “from 35% for a speaker with a distinctive Indian accent to 100%” (Kukk & Alumäe, 2022). Mother-tongue influence runs the other way too: our own model confuses English mostly with Hindi (2.7%), Santali (2.0%) and Marathi (1.7%), exactly the L1-conditioned pattern the phonetics literature predicts.

The channel: short, noisy and narrowband

Voice queries last one or two seconds. A large share of rural access is 8 kHz telephony: G.711 caps bandwidth at 4 kHz (ITU-T, 1988), and 41% of India’s 1.35 billion telephone subscriptions are rural (TRAI, 2026). Many of the phonetic cues above are sparse, and a one-second clip may contain none of them. Systems that look strong in-corpus fall apart across corpora: Indian LID has been measured at 11.8% equal error rate in-corpus against 43.3% cross-corpus (Dey, Saha & Sahidullah, 2021), and IndicSUPERB accuracy falls from 98.2% on seen speakers to 90.8% on unseen ones (Javed et al., 2023).

Not only India

Confusable clusters are the rule wherever languages share a history, which is why the field’s flagship evaluations are built around them.

  • NIST’s 2017 Language Recognition Evaluation focused on “differentiating closely related languages (14 in total) drawn from 5 language clusters, namely Arabic, Chinese, English, Iberian, and Slavic” (Sadjadi et al., 2018).
  • Its 2022 successor found the greatest confusability among Southern African languages (Ndebele, Tsonga, Venda, Xhosa, Zulu), between South African English and Indian-accented South African English, and among Tunisian, Algerian and Libyan Arabic (Lee et al., 2023).
  • Arabic is a dialect continuum across seventeen countries (Shon et al., 2020).
  • In Europe, bilingual LID reaches only 80.0% on Finnish–Estonian, and misidentified Danish–Swedish clips carry 59.7% WER (Amooie et al., 2026).
  • In Southeast Asia, Qwen3-ASR’s remaining FLEURS errors “stem from confusion between Malay (ms) and Indonesian (id)” (Qwen Team, 2026).
  • In China, Whisper large-v3 labels Cantonese as Mandarin zh rather than yue (#2419).

India is the extreme case: every one of these properties at once, across 1.4 billion people.

Fig. 10 The world’s confusable clusters the clusters named in this essay · coastlines only
Confusable language clusters around the world, with India the densest A world map drawn from coastlines only, with numbered rings on the confusable clusters the essay names: 1, India: 23 languages, four families, one linguistic area; 2, The Arabic continuum: seventeen countries; LRE17’s Arabic cluster; 3, English: British and American, LRE17; 4, Iberian: Spanish varieties and Brazilian Portuguese, LRE17; 5, Slavic: Polish and Russian, LRE17; 6, Chinese: Mandarin and Min Nan, LRE17; Cantonese read as Mandarin; 7, Southern Africa: Ndebele, Tsonga, Venda, Xhosa, Zulu; 8, Malay–Indonesian: the remaining FLEURS errors of Qwen3-ASR; 9, Danish–Swedish: 59.7% WER on misidentified clips; 10, Finnish–Estonian: 80.0% bilingual LID accuracy. India is drawn largest. India 1 2 3 4 5 6 7 8 9 10 1 India 23 languages, four families, one linguistic area 2 The Arabic continuum seventeen countries; LRE17’s Arabic cluster 3 English British and American, LRE17 4 Iberian Spanish varieties and Brazilian Portuguese, LRE17 5 Slavic Polish and Russian, LRE17 6 Chinese Mandarin and Min Nan, LRE17; Cantonese read as Mandarin 7 Southern Africa Ndebele, Tsonga, Venda, Xhosa, Zulu 8 Malay–Indonesian the remaining FLEURS errors of Qwen3-ASR 9 Danish–Swedish 59.7% WER on misidentified clips 10 Finnish–Estonian 80.0% bilingual LID accuracy Confusable language clusters around the world, with India the densest A world map drawn from coastlines only, with numbered rings on the confusable clusters the essay names: 1, India: 23 languages, four families, one linguistic area; 2, The Arabic continuum: seventeen countries; LRE17’s Arabic cluster; 3, English: British and American, LRE17; 4, Iberian: Spanish varieties and Brazilian Portuguese, LRE17; 5, Slavic: Polish and Russian, LRE17; 6, Chinese: Mandarin and Min Nan, LRE17; Cantonese read as Mandarin; 7, Southern Africa: Ndebele, Tsonga, Venda, Xhosa, Zulu; 8, Malay–Indonesian: the remaining FLEURS errors of Qwen3-ASR; 9, Danish–Swedish: 59.7% WER on misidentified clips; 10, Finnish–Estonian: 80.0% bilingual LID accuracy. India is drawn largest. 1 2 3 4 5 6 7 8 9 10 1 India 23 languages, four families 2 The Arabic continuum seventeen countries, LRE17 3 English British and American, LRE17 4 Iberian Spanish and Portuguese, LRE17 5 Slavic Polish and Russian, LRE17 6 Chinese Mandarin, Min Nan, Cantonese 7 Southern Africa Ndebele, Tsonga, Venda, Xhosa, Zulu 8 Malay–Indonesian the remaining FLEURS errors of Qwen3-ASR 9 Danish–Swedish 59.7% WER on misidentified clips 10 Finnish–Estonian 80.0% bilingual LID accuracy

Confusable clusters are the rule wherever languages share a history: the five clusters of NIST’s LRE17, the Southern African languages of LRE22, the Arabic continuum, Malay and Indonesian, Danish and Swedish, Finnish and Estonian. India is the extreme case: every one of these properties at once. Coastlines only; no borders drawn.

Specialization erodes what little LID there is

General-purpose recognisers are trained on the internet’s idea of speech: podcasts, lectures, videos. Many of the places where speech technology matters most sound nothing like that.

The domains that need their own recognisers

  • Medicine. Clinical documentation lives on drug names, dosages and anatomy spoken fast by tired people. On real clinical interviews in Indian hospitals, Whisper large-v3 scored 46.8% WER in English, 71.7% in Hindi and 98.6% in Kannada (Kumar et al., 2025). The first multilingual medical ASR dataset appeared only recently (Le-Duc et al., 2025), which tells you medical ASR has been built one language at a time.
  • Law. Adalat AI transcribes proceedings in roughly a quarter of India’s courtrooms. Its engineers found Indic transcripts stopping mid-sentence because Whisper’s token cap is too small for Indic scripts, and had to shrink their windows to six or seven seconds (Adalat AI).
  • Finance. Earnings calls mix jargon, numbers and speakers from every accent; Earnings-22 was built precisely because general models struggle on them (Del Rio et al., 2022).
  • Aviation. Air-traffic-control speech is fast, formulaic, noisy and accented, and open models are fine-tuned specifically for it (van Doorn et al., 2024).
  • Children. Child speech differs acoustically from adult speech, and Whisper must be fine-tuned to close the gap (Attia et al., 2024).
  • Public services. Kisan Call Centre agronomy, Tele-MANAS mental-health calls and Bhashini’s citizen services each carry their own vocabulary, in 22 languages.

The standard remedy is to fine-tune a general model on domain data. Prompt-conditioned fine-tuning of Whisper cut WER by up to 33% on unseen domains, including medical conversation, air-traffic control and financial meetings (Liao et al., 2023). It works. But look at what it does to language identification.

What fine-tuning does to the language decision

It forgets other languages. Fully fine-tuning Whisper on four new languages raised the average WER on its four original languages from 11.68% to 32.29%; Chinese went from 14.37% to 68.93% (Song et al., 2024). Fine-tuning Whisper large-v3 on 12 hours of Irish took Welsh from 27.5% to 96.8% WER and Occitan from 64.2% to 79.8% (Qian et al., 2024). Notably, the Irish was trained under the English language token, because adding a new token performed slightly worse. The language slot had become a convenience, not an identity.

It confuses old languages with new ones. After Whisper was extended to ten new languages, most language-agnostic errors came from English audio being labelled as Esperanto, one of the additions (Kwok, Yip & Chng, 2024).

It trains the language slot to a constant. The standard fine-tuning recipe fixes the language for the dataset, so every training example carries the same language target (Hugging Face, 2022). A medical Hindi model is taught to say “Hindi” every time, whatever it hears.

There is an honest nuance. Probing a Whisper encoder after English and multilingual medical fine-tuning, Kahali et al. found language identity still almost perfectly linearly separable (F1 ≥ 0.99 from the first layer on) (Kahali et al., 2026). The knowledge survives in the encoder. What degrades is the decoder’s one-token read-out of it, which is exactly what a dedicated classifier replaces.

Why this makes an external LID mandatory

Every standard fix for forgetting moves the language decision outside the model. Language-specific LoRA modules must be selected by language (Song et al., 2024). MMS adapters are loaded by language. A fleet of domain models (medical Hindi, legal Tamil, agricultural Marathi) is routed by language. Specialization does not merely weaken built-in LID. It makes an external LID a requirement, and one well-built LID can then serve the entire fleet.

Fig. 11 One gate, many specialists 4 languages × 4 domains = 16 recognisers
One language identifier in front of a fleet of specialised recognisers Two isometric grids of sixteen specialised recognisers, one row per language (Hindi, Tamil, Bengali, Marathi) and one column per domain (medical, legal, finance, agriculture). (a) A single language identifier, a teal block in front of the grid, routes each call to the row for its language. (b) Without it, each of the sixteen specialists carries its own small language token, drawn in orange, and must guess the language for itself. (a) One gate: routed by language medical Hindi legal Hindi medical Tamil finance Hindi legal Tamil medical Bengali agriculture Hindi finance Tamil legal Bengali medical Marathi agriculture Tamil finance Bengali legal Marathi agriculture Bengali finance Marathi agriculture Marathi The language identifier Hindi Tamil Bengali Marathi medical legal finance agriculture Language identifier one decision, made once (b) No gate: sixteen weakened tokens medical Hindi a Hindi language token legal Hindi a Hindi language token medical Tamil a Tamil language token finance Hindi a Hindi language token legal Tamil a Tamil language token medical Bengali a Bengali language token agriculture Hindi a Hindi language token finance Tamil a Tamil language token legal Bengali a Bengali language token medical Marathi a Marathi language token agriculture Tamil a Tamil language token finance Bengali a Bengali language token legal Marathi a Marathi language token agriculture Bengali a Bengali language token finance Marathi a Marathi language token agriculture Marathi a Marathi language token Hindi Tamil Bengali Marathi medical legal finance agriculture each specialist guesses the language from its own token, fine-tuned to a constant One language identifier in front of a fleet of specialised recognisers Two isometric grids of sixteen specialised recognisers, one row per language (Hindi, Tamil, Bengali, Marathi) and one column per domain (medical, legal, finance, agriculture). (a) A single language identifier, a teal block in front of the grid, routes each call to the row for its language. (b) Without it, each of the sixteen specialists carries its own small language token, drawn in orange, and must guess the language for itself. (a) One gate medical Hindi legal Hindi medical Tamil finance Hindi legal Tamil medical Bengali agriculture Hindi finance Tamil legal Bengali medical Marathi agriculture Tamil finance Bengali legal Marathi agriculture Bengali finance Marathi agriculture Marathi The language identifier Hindi Tamil Bengali Marathi medical legal finance agriculture Language identifier (b) No gate medical Hindi a Hindi language token legal Hindi a Hindi language token medical Tamil a Tamil language token finance Hindi a Hindi language token legal Tamil a Tamil language token medical Bengali a Bengali language token agriculture Hindi a Hindi language token finance Tamil a Tamil language token legal Bengali a Bengali language token medical Marathi a Marathi language token agriculture Tamil a Tamil language token finance Bengali a Bengali language token legal Marathi a Marathi language token agriculture Bengali a Bengali language token finance Marathi a Marathi language token agriculture Marathi a Marathi language token Hindi Tamil Bengali Marathi medical legal finance agriculture each specialist guesses the language from its own weakened token

A fleet of domain recognisers, medical Hindi to agricultural Marathi, is routed by language. One well-built identifier serves the whole fleet; without it, every specialist must guess from a language slot it was fine-tuned to keep constant.

The systems case, strongest first

Theory and linguistics explain why built-in LID is weak. The engineering reasons to decouple it are just as strong, and for anyone building voice agents they are the ones that bite first. In order of importance:

1. Voice agents need the language before the transcript

A voice agent chooses its TTS voice, its LLM prompt and its reply language from the caller’s language, and it has roughly 800 ms before a conversation starts to feel slow (WebRTC.ventures, 2026). Vendor LID was not built for that budget: AWS streaming needs at least one second of speech, Azure’s at-start mode returns “in less than 5 seconds”, AWS batch recommends 30 seconds, AssemblyAI 15–90 seconds and Speechmatics 60 (AWS; Azure; AssemblyAI; Speechmatics). Builders end up hand-rolling the component: one LiveKit user’s workaround was to listen to the “first 3 seconds… and detect with whisper” before locking the session (livekit/agents #1335). When the language silently defaults, everything downstream is corrupted: a Pipecat integration “labels every transcript it produces as Hindi, regardless of what language was actually spoken” (pipecat #5691).

2. Short clips break the 30-second design

Whisper pads every input to 30 seconds, so a one-second “haan” costs a full 30-second encoder pass, and WhisperX warns that for shorter audio “language detection may be inaccurate” (asr.py). Classic LID research has always known that duration is the enemy: x-vector cost nearly triples from 30 s to 3 s clips (Snyder et al., 2018). Real turns are one to three seconds long. A dedicated model can be trained for them, with duration cropping as its most valuable single augmentation.

3. An honest “none of these”

A language token lives in a closed set. Whisper’s detector masks every non-language logit and takes the argmax of what remains (decoding.py). Vendors say the same about their own systems. Azure: “The Speech service returns one of the candidate languages provided even if those languages weren’t in the audio.” AWS: English audio offered Chinese, French and German candidates “is likely to match your media to German… and produce a German-language transcription.” A standalone model can be trained and evaluated open-set, with rejection as a first-class output.

4. A confidence you can act on

Implicit LID often hides its decision entirely. NVIDIA’s Indic ASR service “supports automatic language detection but does not produce detected language code in output” (NVIDIA NIM). Where vendors do expose it, they bolt on thresholds: AssemblyAI’s language_confidence_threshold, Speechmatics’ low_confidence_action. The LID community, by contrast, has always scored calibration explicitly through NIST’s Cavg (Lee et al., 2023). A calibrated probability is what lets an agent say “sorry, which language would you prefer?” instead of confidently answering in the wrong one.

5. Routing and throughput, stated precisely

It is tempting to claim that built-in LID ruins batching. For Whisper-style models it does not: the language is a per-sequence prompt token, and Hugging Face has supported a different language per batch item since v4.41 (PR #29688). The real costs are three.

  • Weight-routed models need the language before they run. MMS swaps per-language adapters; language-specific LoRA must be selected; IndicConformer’s API takes one language per call; fleets of per-language models split by construction. None can detect the language for itself.
  • Built-in detection is not free. openai-whisper encodes the first window once to detect the language and again to decode it, and a low-confidence decode triggers temperature fallback: up to six re-decodes, each re-running the encoder (transcribe.py).
  • Decode length depends on the language. On parallel text, Whisper’s tokenizer needs about 6× as many tokens for Hindi and Tamil as for English, and 9–13× for Bengali, Punjabi, Malayalam and Gujarati (our measurement). In static batches those sequences become stragglers, and the token cap forces shorter Indic windows (the Adalat AI story above).

An upstream LID fixes all three: it routes to the right weights, buckets traffic by language, and sets the chunking policy per script.

Fig. 12 The token tax Whisper’s multilingual tokenizer on parallel UDHR text · English = 1×
Whisper tokens per language, relative to English, for the same text A horizontal bar chart of fifteen languages. Relative to English at 1, Whisper needs 12.9 times as many tokens for Gujarati, 11.4 times as many tokens for Malayalam, 10.6 times as many tokens for Punjabi, 9.7 times as many tokens for Bengali, 8.9 times as many tokens for Kannada, 6.4 times as many tokens for Marathi, 6.1 times as many tokens for Hindi, 6.0 times as many tokens for Tamil, 5.0 times as many tokens for Nepali, 3.1 times as many tokens for Urdu; the European reference languages sit between 1.5 and 1.8. Measured on parallel Universal Declaration of Human Rights texts. 0 2× 4× 6× 8× 10× 12× 14× English = 1× Gujarati 12.9× Gujarati: 12.90× the tokens of English Malayalam 11.4× Malayalam: 11.36× the tokens of English Punjabi 10.6× Punjabi: 10.63× the tokens of English Bengali 9.7× Bengali: 9.69× the tokens of English Kannada 8.9× Kannada: 8.91× the tokens of English Marathi 6.4× Marathi: 6.39× the tokens of English Hindi 6.1× Hindi: 6.10× the tokens of English Tamil 6.0× Tamil: 6.03× the tokens of English Nepali 5.0× Nepali: 5.04× the tokens of English Urdu 3.1× Urdu: 3.11× the tokens of English Russian 1.8× Russian: 1.77× the tokens of English French 1.6× French: 1.61× the tokens of English German 1.5× German: 1.48× the tokens of English Spanish 1.5× Spanish: 1.48× the tokens of English English 1× English: 1.00× the tokens of English Indian languages European reference Whisper tokens per language, relative to English, for the same text A horizontal bar chart of fifteen languages. Relative to English at 1, Whisper needs 12.9 times as many tokens for Gujarati, 11.4 times as many tokens for Malayalam, 10.6 times as many tokens for Punjabi, 9.7 times as many tokens for Bengali, 8.9 times as many tokens for Kannada, 6.4 times as many tokens for Marathi, 6.1 times as many tokens for Hindi, 6.0 times as many tokens for Tamil, 5.0 times as many tokens for Nepali, 3.1 times as many tokens for Urdu; the European reference languages sit between 1.5 and 1.8. Measured on parallel Universal Declaration of Human Rights texts. 0 2× 4× 6× 8× 10× 12× 14× English = 1× Gujarati 12.9× Gujarati: 12.90× the tokens of English Malayalam 11.4× Malayalam: 11.36× the tokens of English Punjabi 10.6× Punjabi: 10.63× the tokens of English Bengali 9.7× Bengali: 9.69× the tokens of English Kannada 8.9× Kannada: 8.91× the tokens of English Marathi 6.4× Marathi: 6.39× the tokens of English Hindi 6.1× Hindi: 6.10× the tokens of English Tamil 6.0× Tamil: 6.03× the tokens of English Nepali 5.0× Nepali: 5.04× the tokens of English Urdu 3.1× Urdu: 3.11× the tokens of English Russian 1.8× Russian: 1.77× the tokens of English French 1.6× French: 1.61× the tokens of English German 1.5× German: 1.48× the tokens of English Spanish 1.5× Spanish: 1.48× the tokens of English English 1× English: 1.00× the tokens of English Indian languages European reference
The numbers
LanguageTokens relative to English
Gujarati12.90×
Malayalam11.36×
Punjabi10.63×
Bengali9.69×
Kannada8.91×
Marathi6.39×
Hindi6.10×
Tamil6.03×
Nepali5.04×
Urdu3.11×
Russian1.77×
French1.61×
German1.48×
Spanish1.48×
English1.00×

Whisper tokens needed for the same text, relative to English. Indian languages pay three to thirteen times over; Gujarati, Malayalam and Punjabi more than tenfold. Measured on the parallel Universal Declaration of Human Rights texts with Whisper’s multilingual tokenizer.

6. Every multilingual corpus is gated by an LID

Whisper’s own data was filtered by a separate audio language detector (Radford et al., 2023, §2.1). OWSM v4 found YODAS riddled with “incorrect language labels” and cleaned it before training (Peng et al., 2025). NVIDIA’s Granary runs Whisper twice, “first for language ID prediction, then for transcription”, and drops clips below 0.8 LID probability (Koluguri et al., 2025). YODAS itself reports that its attempts at language identification “are not significantly successful” (Li et al., 2023). For the eight scheduled languages Whisper cannot even name, Whisper cannot be that gate. An Indic LID is infrastructure for building the next Indic recogniser.

7. Cost and the edge

Routing, analytics, moderation and dataset filtering need the language, not the transcript. Running a 1.55-billion-parameter encoder–decoder for that is like hiring a translator to tell you which language a letter is in. Dedicated LIDs are small by comparison, from ECAPA-TDNN (21M) and AmberNet (29M) to Anuvani-LID (115.6M, and 84M in its 12-block form).

8. The language token is an attack surface

A universal 0.64-second audio segment can mute Whisper on more than 97% of inputs (Raina et al., 2024), and attacks aimed only at the language detector wreck transcription (Olivier & Raj, above). An independent audio LID, cross-checked against a text LID on the transcript, is a cheap second opinion that data pipelines already use.

9. Upgrades should not silently change routing

When LID lives inside the recogniser, every recogniser upgrade is also a routing change, as the large-v2 to large-v3 regressions showed. Commercial APIs change between versions too; our paper records the exact snapshots it queried for that reason. A standalone LID is benchmarked, versioned and rolled back on its own schedule.

Introducing Anuvani-LID

This is why we built Anuvani-LID: a dedicated spoken language identifier for the 22 scheduled languages of India and English. It is a 115.6M-parameter self-supervised Conformer, fine-tuned on 54,643 hours of speech from 18 corpora (31.24 million utterances), and it makes one decision, well: which of 23 languages is this?

The model

Audio becomes 80-band log-Mel features (25 ms windows, 10 ms hop), subsampled four-fold to 40 ms frames. These feed the 17 Conformer blocks of AI4Bharat’s MahaDhwani encoder (Gulati et al., 2020; Bhogale et al., 2025), pre-trained without labels on 279,000 hours of Indian audio. Instead of reading only the last block, the head reads all of them through learned weights:

zt=∑ℓ=117αℓ hℓ,t,α=softmax(w)\mathbf{z}_t = \sum_{\ell=1}^{17} \alpha_\ell\, \mathbf{h}_{\ell,t}, \qquad \boldsymbol{\alpha} = \mathrm{softmax}(\mathbf{w})

Attentive statistics pooling turns those frames into a 1,024-dimensional mean-and-deviation vector, projected to a 256-dimensional embedding and a 23-way classifier, trained end to end with focal loss (γ = 2) and label smoothing of 0.1. The recipe came out of a six-stage controlled study: temperature sampling at T = 1.75 with floors for English (16%) and Hindi (11%); a competence curriculum over the confusable Indo-Aryan cluster; speed perturbation, MUSAN noise, room impulses, 8 kHz µ-law codec simulation, one-to-six-talker babble and bimodal crops from 0.25 to 16 seconds; AdamW for 425,000 steps on six RTX A6000 GPUs (about three days); and a uniform soup of seven checkpoints, chosen from 31 candidates. At inference, a single temperature (0.674) calibrates the probabilities.

Fig. 13 Architecture Anuvani-LID · 115.6M parameters · read from the bottom up
Anuvani-LID, from waveform to a 23-way decision, drawn bottom to top A vertical model diagram in 3D. At the bottom, a 16 kHz audio waveform becomes an 80-band log-Mel spectrogram with 25 ms windows and a 10 ms hop, subsampled four-fold to 40 ms frames. These climb a tower of 17 Conformer blocks, pre-trained without labels on 279,000 hours of Indian audio; blocks 11 and 12 are teal, where language identity peaks. A tap from every block feeds the learned layer weights, a softmax over all 17 blocks. Attentive statistics pooling turns the frames into a 1,024-dimensional mean-and-deviation vector, a projection makes a 256-dimensional embedding, and a 23-way classifier trained with focal loss, gamma 2, and label smoothing 0.1 chooses one language, calibrated at inference by a single temperature, 0.674. Beside the model, the training recipe: temperature sampling at 1.75 with floors of 16% for English and 11% for Hindi; a competence curriculum over the confusable Indo-Aryan cluster; speed perturbation, MUSAN noise, room impulses, an 8 kHz mu-law codec, one-to-six-talker babble, bimodal crops from 0.25 to 16 seconds, and SpecAugment with two frequency and two time masks; AdamW for 425,000 steps on six RTX A6000 GPUs, about three days; and a uniform soup of seven checkpoints chosen from 31. log-Mel spectrogram Subsampling Conformer block 1 Conformer block 2 Conformer block 3 Conformer block 4 Conformer block 5 Conformer block 6 Conformer block 7 Conformer block 8 Conformer block 9 Conformer block 10 Conformer block 11 Conformer block 12 Conformer block 13 Conformer block 14 Conformer block 15 Conformer block 16 Conformer block 17 Learned layer weights Attentive statistics pooling Projection one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages the chosen language one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages log-Mel spectrogram 80 bands · 25 ms windows, 10 ms hop Subsampling 4× in time → 40 ms frames Conformer encoder 17 blocks, each as in Figure 6 MahaDhwani, self-supervised on 279,000 h Learned layer weights softmax(w) over all 17 blocks Attentive statistics pooling mean and deviation over time · 1,024-d Projection 256-d embedding 23-way classifier focal loss, γ = 2 · label smoothing 0.1 Audio 16 kHz waveform One of 23 languages calibrated by one temperature, 0.674 the head reads every block, not only the last Training recipe Sampling temperature T = 1.75 floors: English 16%, Hindi 11% Curriculum competence curriculum over the confusable Indo-Aryan cluster Augmentation speed perturbation · MUSAN noise room impulses · 8 kHz µ-law codec babble, 1–6 talkers bimodal crops, 0.25–16 s SpecAugment: 2 + 2 masks Optimisation AdamW · 425,000 steps six RTX A6000 GPUs, about 3 days Averaging uniform soup of 7 checkpoints chosen from 31 candidates Anuvani-LID, from waveform to a 23-way decision, drawn bottom to top A vertical model diagram in 3D. At the bottom, a 16 kHz audio waveform becomes an 80-band log-Mel spectrogram with 25 ms windows and a 10 ms hop, subsampled four-fold to 40 ms frames. These climb a tower of 17 Conformer blocks, pre-trained without labels on 279,000 hours of Indian audio; blocks 11 and 12 are teal, where language identity peaks. A tap from every block feeds the learned layer weights, a softmax over all 17 blocks. Attentive statistics pooling turns the frames into a 1,024-dimensional mean-and-deviation vector, a projection makes a 256-dimensional embedding, and a 23-way classifier trained with focal loss, gamma 2, and label smoothing 0.1 chooses one language, calibrated at inference by a single temperature, 0.674. Beside the model, the training recipe: temperature sampling at 1.75 with floors of 16% for English and 11% for Hindi; a competence curriculum over the confusable Indo-Aryan cluster; speed perturbation, MUSAN noise, room impulses, an 8 kHz mu-law codec, one-to-six-talker babble, bimodal crops from 0.25 to 16 seconds, and SpecAugment with two frequency and two time masks; AdamW for 425,000 steps on six RTX A6000 GPUs, about three days; and a uniform soup of seven checkpoints chosen from 31. log-Mel spectrogram Subsampling Conformer block 1 Conformer block 2 Conformer block 3 Conformer block 4 Conformer block 5 Conformer block 6 Conformer block 7 Conformer block 8 Conformer block 9 Conformer block 10 Conformer block 11 Conformer block 12 Conformer block 13 Conformer block 14 Conformer block 15 Conformer block 16 Conformer block 17 Learned layer weights Attentive statistics pooling Projection one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages the chosen language one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages one of 23 languages log-Mel spectrogram 80 bands · 10 ms hop Subsampling 4× → 40 ms frames Conformer encoder 17 blocks · see Figure 6 279,000 h, self-supervised Layer weights softmax over all 17 Attentive pooling mean + deviation · 1,024-d Projection 256-d embedding 23-way classifier focal loss, γ = 2 Audio 16 kHz One of 23 languages one temperature, 0.674 Training recipe Sampling temperature T = 1.75 floors: English 16%, Hindi 11% Curriculum competence curriculum over the confusable Indo-Aryan cluster Augmentation speed perturbation · MUSAN noise room impulses · 8 kHz µ-law codec babble, 1–6 talkers bimodal crops, 0.25–16 s SpecAugment: 2 + 2 masks Optimisation AdamW · 425,000 steps six RTX A6000 GPUs, about 3 days Averaging uniform soup of 7 checkpoints chosen from 31 candidates

Audio becomes 80-band log-Mel frames and climbs 17 Conformer blocks. The head reads all 17 through learned weights, pools the frames into a 1,024-dimensional mean-and-deviation vector, projects it to a 256-dimensional embedding and decides among 23 languages with a focal-loss classifier. Beside it, the recipe that came out of the six-stage study.

How we tested it

On clean, in-domain speech, every head we tried in our first pilot reached about 98% accuracy within a point of the others. The benchmark had saturated, so we rebuilt the ruler first (Geirhos et al., 2020; Kiela et al., 2021).

  • SUITE-102 has 102 conditions and 318,861 utterances. Its headline tier is the IndicVoices test set: 300 spontaneous utterances per language from 1,308 speakers, none of whom appear in training. Cross-corpus tiers come from FLEURS, SPRING-INX, MUCS, Kathbath and Common Voice. Each source is expanded into crops from 0.25 to 10 seconds, noise at 0 and 5 dB, reverberation, 8 kHz telephony, babble, confusable-cluster subsets and open-set trials (music, eight non-Indian languages and Chhattisgarhi, a close relative of Hindi outside our label set).
  • SUITE-42 is a balanced panel of 42 of those conditions for comparing commercial systems: 47,730 identical clips on 37 core conditions over the ten languages every system supports, plus 17,229 clips on an all-23 panel. Prompted APIs were given the list of candidate languages, which favours them; Anuvani-LID always chose among all 23.

How we built it: six stages, in order

The recipe beside Figure 13 was not designed in one sitting. It is what was left standing after a benchmark and six stages of controlled experiments, run in order, each starting from the recipe the stage before it had settled. Stages I to V ran at reduced scale, 1,000 to 4,000 hours, so that many arms were affordable. Stage VI trained the final recipe once, on all 54,643 hours.

StageData (classes)ArmsWhat it settled
0 · Benchmark——A held-out suite with many axes
I · Head, loss and adaptation1,000 h, balanced (20)25Attentive statistics pooling, focal loss, full fine-tuning
II · Rebalancing4,000 h, production skew (23)16T ≈ 2; one rebalancer, not two; a learned mix of all layers
III · Augmentation4,000 h, production skew (23)8Duration crops, noise, room impulses, codec, babble
IV · Curriculum4,000 h, production skew (23)5A confusability ramp on the 15 Indo-Aryan languages
V · Optimisation4,000 h proxy (23)15Peak learning rate 3 × 10−4; T = 1.75 with floors for English and Hindi
VI · Full scale54,643 h (23)1 run, 31 candidatesAn exponential moving average; an average of seven checkpoints

Three rules held from the first stage to the last.

  • One factor at a time, where the arms allow it. Most arms change one thing against a fixed reference, and the data, the budget and the benchmark stay frozen for the whole stage, so a difference between two arms has one explanation. Where an arm changed more than one thing, the stage says so.
  • The benchmark decides, not the training curve. Every arm is scored once, after training, on a benchmark of hard conditions: other corpora, short crops, noise, reverberation, telephony, confusable clusters. Not all of it is held out from training, and each stage says where it is not. The curves below show how each run behaved. They do not rank the arms, and Stage I shows why.
  • A difference must clear the noise. Training is not deterministic. In Stage II, two runs with the same configuration finished 3.2 points apart in cross-corpus macro-F1. Stages I to V trained one run per arm, so we read every comparison against that figure: a gap of less than about three points between two runs is a tie, unless the same sign across many conditions or a second seed says otherwise. A significance test on the benchmark’s clips cannot say otherwise: it measures how firmly the clips separate two checkpoints, not how far a checkpoint moves when training is repeated.

In the charts that follow, a faint line is what the trainer logged, one batch every 50 steps, and the solid line over it is its running mean. Point at a chart to read every series at that step; the panels of a figure move together. A key in the legend hides or shows its series, and every figure keeps its numbers in a table underneath.

Stage 0A ruler that can rank

first sweep: 1,000 h · 20 languages · 4 epochs · five heads scored on five slices of the rebuilt benchmark

The first sweep taught us nothing about architecture, and that was its result. Five pooling heads, trained for four epochs on the same 1,000 hours, ended between 0.976 and 0.985 accuracy on clean validation speech (Figure 14, top). Their training curves lie on top of one another. A benchmark on which everything scores 98% cannot say which design to carry forward.

So, with the sweep paused, we scored the five finished checkpoints on slices built to be hard: speech from IndicVoices, a corpus the 1,000-hour subset did not contain; subsets of confusable languages; and crops of one second and of half a second (Figure 14, bottom). Macro-F1 fell from 0.88–0.90 on the clean benchmark to 0.79–0.80 on the new corpus, 0.43–0.48 at one second and 0.18–0.23 at half a second. The order changed as well: the ECAPA-TDNN head, first on clean validation, was last on every hard slice. With one run per head those gaps are inside the noise, and we did not read a ranking into them. What the gauge established is that hard conditions pull models apart and clean ones do not. The suite grew from these slices into the 54 conditions that score Stage I, and by Stage VI into the 102 of SUITE-102.

Fig. 14 A benchmark that could not rank stage 0 · five pooling heads · 1,000 h · 4 epochs · one run each

Training accuracy

0.00 0.25 0.50 0.75 1.00 0 3.5k 7k 10.5k 14k
Training accuracy
stepAttentive statisticsMean and deviationMulti-head attentionNetVLADECAPA-TDNN
740.0570.0630.1440.1210.166
1,9740.9180.9300.9430.9500.940
4,0240.9650.9700.9710.9750.968
5,9740.9780.9830.9800.9850.979
8,0240.9840.9890.9860.9900.986
9,9740.9840.9880.9880.9910.989
12,0240.9870.9900.9920.9910.991
13,9490.9860.9890.9910.9900.990

Clean validation accuracy

0.95 0.96 0.97 0.98 0.99 1.00 0 3.5k 7k 10.5k 14k
Clean validation accuracy
stepAttentive statisticsMean and deviationMulti-head attentionNetVLADECAPA-TDNN
3,5070.9690.9680.9630.9630.973
7,0140.9670.9740.9790.9700.972
10,5210.9800.9760.9810.9730.982
14,0280.9830.9760.9840.9770.985
The same five checkpoints on five slices of the rebuilt benchmark Macro-F1 of five pooling heads on five benchmark slices. Clean benchmark 0.88–0.90; a corpus not in training 0.79–0.80; confusable languages 0.78–0.79; crops of 1 s 0.43–0.48; crops of 0.5 s 0.18–0.23. The ECAPA-TDNN head is lowest on every slice. Macro-F1 after training, by benchmark slice 0.00 0.25 0.50 0.75 1.00 Clean benchmarkAttentive statistics: 0.89Mean and deviation: 0.89Multi-head attention: 0.90NetVLAD: 0.89ECAPA-TDNN: 0.880.88–0.90 A corpus not in trainingAttentive statistics: 0.80Mean and deviation: 0.80Multi-head attention: 0.79NetVLAD: 0.80ECAPA-TDNN: 0.790.79–0.80 Confusable languagesAttentive statistics: 0.79Mean and deviation: 0.79Multi-head attention: 0.78NetVLAD: 0.79ECAPA-TDNN: 0.780.78–0.79 Crops of 1 sAttentive statistics: 0.47Mean and deviation: 0.48Multi-head attention: 0.44NetVLAD: 0.47ECAPA-TDNN: 0.430.43–0.48 Crops of 0.5 sAttentive statistics: 0.21Mean and deviation: 0.23Multi-head attention: 0.19NetVLAD: 0.21ECAPA-TDNN: 0.180.18–0.23 The same five checkpoints on five slices of the rebuilt benchmark: Macro-F1 after training, by benchmark slice Macro-F1 of five pooling heads on five benchmark slices. Clean benchmark 0.88–0.90; a corpus not in training 0.79–0.80; confusable languages 0.78–0.79; crops of 1 s 0.43–0.48; crops of 0.5 s 0.18–0.23. The ECAPA-TDNN head is lowest on every slice. Macro-F1 by benchmark slice 0.00 0.50 1.00 CleanAttentive statistics: 0.89Mean and deviation: 0.89Multi-head attention: 0.90NetVLAD: 0.89ECAPA-TDNN: 0.880.88–0.90 New corpusAttentive statistics: 0.80Mean and deviation: 0.80Multi-head attention: 0.79NetVLAD: 0.80ECAPA-TDNN: 0.790.79–0.80 ConfusableAttentive statistics: 0.79Mean and deviation: 0.79Multi-head attention: 0.78NetVLAD: 0.79ECAPA-TDNN: 0.780.78–0.79 1 s cropsAttentive statistics: 0.47Mean and deviation: 0.48Multi-head attention: 0.44NetVLAD: 0.47ECAPA-TDNN: 0.430.43–0.48 0.5 s cropsAttentive statistics: 0.21Mean and deviation: 0.23Multi-head attention: 0.19NetVLAD: 0.21ECAPA-TDNN: 0.180.18–0.23

Faint: the accuracy of one logged batch. Solid: its running mean. The validation axis starts at 0.95.

The numbers
Clean validation accuracy after four epochs, and macro-F1 on five benchmark slices, for five pooling heads
HeadClean validation accuracyClean benchmarkA corpus not in trainingConfusable languagesCrops of 1 sCrops of 0.5 s
Attentive statistics0.9830.8880.7980.7910.4670.210
Mean and deviation0.9760.8950.8020.7920.4760.226
Multi-head attention0.9840.8990.7940.7840.4360.189
NetVLAD0.9770.8890.8020.7920.4730.213
ECAPA-TDNN0.9850.8820.7860.7790.4270.181

On clean speech every head looks the same; on hard speech none of them looks good. Top: five pooling heads trained on the same 1,000 h end between 0.976 and 0.985 accuracy on clean validation, and their training curves coincide. Bottom: the same five checkpoints scored on slices of the rebuilt benchmark. Macro-F1 falls from 0.88–0.90 on the clean benchmark to 0.18–0.23 on half-second crops, and the head that led on clean validation is last on every hard slice. Training logs (Weights & Biases) and the benchmark scorecard of the first sweep.

The learning rate had been settled before that first sweep began. Fine-tuning recipes often give a new head a larger rate than the pre-trained encoder beneath it (Howard & Ruder, 2018). A 1,500-step probe compared that recipe, a head rate ten times the encoder’s, with a single rate of 10−4 for everything, on three heads of increasing size. It did not help the larger heads it was meant to help: NetVLAD reached 0.982 with one rate and 0.980 with two. Three of the six runs ended at chance with a NaN loss, so the probe is weaker evidence than it looks, and it was not repeated after the loss was fixed. We kept the simpler setting: one learning rate for the whole network.

Stage IHead, loss and adaptation: what reads the encoder, and how much of it to train

1,000 h, balanced · 20 languages · 25 arms · 4 epochs each · one run per arm · scored on 54 conditions

Stage I asked three questions about what sits on top of the encoder: how to pool frames into one vector, which loss to train with, and how much of the encoder to adapt. The reference was attentive statistics pooling, an additive-angular-margin loss and full fine-tuning, and the pooling and loss arms each changed one of those. All of them trained on the same 1,000-hour subset of 20 languages, built to give each a similar share (27 to 53 hours; Kashmiri, Santali and Sindhi had too little audio), under one budget: four epochs, 14,028 steps of 144 utterances, AdamW (Loshchilov & Hutter, 2019) with cosine decay, at a peak learning rate of 10−4 for every arm that trains the whole network and 3 × 10−4 or 10−3 for the arms that train less of it. Twenty-five arms were scored on the 54-condition predecessor of SUITE-102. Its cross-corpus slice pools 10,755 clips from four corpora; one of them, Kathbath, also supplied a fifth of the training audio, and its clips in the slice come from its validation split.

The pooling arms were mean and standard deviation (Snyder et al., 2018), multi-head attentive pooling (after India, Safari & Hernando, 2019), NetVLAD (Arandjelović et al., 2016), an ECAPA-TDNN back-end (Desplanques et al., 2020) and attentive statistics pooling (Okabe et al., 2018) over a learned mix of all 17 layers (Yang et al., 2021). The loss arms were cross-entropy, with and without label smoothing (Szegedy et al., 2016), AM-Softmax (Wang et al., 2018), logit-adjusted cross-entropy (Menon et al., 2021) and focal loss (Lin et al., 2017). The adaptation arms froze the encoder, unfroze its top six blocks, or trained bottleneck adapters (Houlsby et al., 2019) or LoRA (Hu et al., 2022) inside a frozen encoder. Eleven further arms put an ECAPA-TDNN back-end on a layer mix, with a layer norm before it, and varied its width, its loss and its training data; these change several things at once against the reference.

Fig. 15 The pooling head hardly matters, and only softmax heads were scored as probabilities stage I · 1,000 h · 20 languages · 4 epochs · one run per arm · 10,755 cross-corpus clips
The pooling head hardly matters, and only softmax heads were scored as probabilities Twenty-five training arms in four groups. For each: cross-corpus macro-F1 with its 95% bootstrap interval, and expected calibration error on a log scale. Macro-F1 lies between 0.806 and 0.840 for every fine-tuned arm except one. Calibration error is 0.75 to 0.79 for the fine-tuned cosine-margin heads, which the benchmark scored without their training scale, and 0.02 to 0.08 for softmax heads. Cross-corpus macro-F1, 95% interval 0.79 0.80 0.81 0.82 0.83 0.84 0.85 Calibration error (ECE), log scale 0.01 0.03 0.1 0.3 1 Pooling, under a margin loss Mean and deviation0.8280.791 Multi-head attention0.8250.789 NetVLAD0.8340.790 ECAPA-TDNN back-end0.8270.774 Attentive, on all 17 layers0.8370.789 Loss, with attentive pooling Cross-entropy0.8360.060 Cross-entropy, label smoothing0.8360.082 AM-Softmax0.8380.791 Logit-adjusted cross-entropy0.8260.072 Focal, γ = 2 (selected)0.8400.023 Adapting the encoder Top six blocks0.8060.753 Bottleneck adapters0.8220.792 LoRA0.8210.793 Frozen encoder0.3620.354 ECAPA-TDNN back-end on a mix of all layers All layers, margin loss0.8330.771 All layers, margin loss, 512 channels0.8340.774 Focal, γ = 20.8280.037 Focal, γ = 10.8290.066 Focal, γ = 30.8230.028 Class-balanced focal0.8280.042 Focal, 512 channels0.8300.039 Focal on a margin0.8350.776 Focal, top six blocks0.8150.035 Focal, duration crops0.8350.021 Focal, distilled to 1 s0.7340.128 The pooling head hardly matters, and only softmax heads were scored as probabilities: Cross-corpus macro-F1, 95% interval Twenty-five training arms in four groups. For each: cross-corpus macro-F1 with its 95% bootstrap interval, and expected calibration error on a log scale. Macro-F1 lies between 0.806 and 0.840 for every fine-tuned arm except one. Calibration error is 0.75 to 0.79 for the fine-tuned cosine-margin heads, which the benchmark scored without their training scale, and 0.02 to 0.08 for softmax heads. Cross-corpus macro-F1, 95% interval 0.79 0.81 0.83 0.85 Pooling, under a margin loss Mean and deviation0.828 Multi-head attention0.825 NetVLAD0.834 ECAPA back-end0.827 Attentive, all layers0.837 Loss, with attentive pooling Cross-entropy0.836 CE, label smoothing0.836 AM-Softmax0.838 Logit-adjusted CE0.826 Focal, γ = 20.840 Adapting the encoder Top six blocks0.806 Adapters0.822 LoRA0.821 Frozen encoder0.362 ECAPA-TDNN back-end, all layers All layers, margin0.833 Margin, 512 ch.0.834 Focal, γ = 20.828 Focal, γ = 10.829 Focal, γ = 30.823 Class-balanced focal0.828 Focal, 512 ch.0.830 Focal on a margin0.835 Focal, top six0.815 Focal, dur. crops0.835 Focal, distilled0.734 The pooling head hardly matters, and only softmax heads were scored as probabilities: Calibration error (ECE), log scale Twenty-five training arms in four groups. For each: cross-corpus macro-F1 with its 95% bootstrap interval, and expected calibration error on a log scale. Macro-F1 lies between 0.806 and 0.840 for every fine-tuned arm except one. Calibration error is 0.75 to 0.79 for the fine-tuned cosine-margin heads, which the benchmark scored without their training scale, and 0.02 to 0.08 for softmax heads. Calibration error (ECE), log scale 0.01 0.1 1 Pooling, under a margin loss Mean and deviation0.791 Multi-head attention0.789 NetVLAD0.790 ECAPA back-end0.774 Attentive, all layers0.789 Loss, with attentive pooling Cross-entropy0.060 CE, label smoothing0.082 AM-Softmax0.791 Logit-adjusted CE0.072 Focal, γ = 20.023 Adapting the encoder Top six blocks0.753 Adapters0.792 LoRA0.793 Frozen encoder0.354 ECAPA-TDNN back-end, all layers All layers, margin0.771 Margin, 512 ch.0.774 Focal, γ = 20.037 Focal, γ = 10.066 Focal, γ = 30.028 Class-balanced focal0.042 Focal, 512 ch.0.039 Focal on a margin0.776 Focal, top six0.035 Focal, dur. crops0.021 Focal, distilled0.128
Selected: attentive pooling, focal loss Cosine-margin head Softmax head

The macro-F1 axis starts at 0.79. An arrow marks an arm below it. Cosine-margin heads were scored on their raw cosines, without the scale of 30 they trained with.

The numbers
Stage I: macro-F1 on five benchmark slices and cross-corpus calibration error for 25 arms
ArmCross-corpus95% intervalCleanDegradedShortConfusableECE
Mean and deviation0.8280.821–0.8350.9030.7730.4420.8610.791
Multi-head attention0.8250.818–0.8320.9050.7740.4150.8590.789
NetVLAD0.8340.827–0.8400.9010.7850.4400.8630.790
ECAPA-TDNN back-end0.8270.821–0.8330.8920.7720.4300.8550.774
Attentive, on all 17 layers0.8370.829–0.8420.9050.7890.4440.8700.789
Cross-entropy0.8360.829–0.8440.8990.7720.4130.8690.060
Cross-entropy, label smoothing0.8360.829–0.8420.9000.7820.4530.8660.082
AM-Softmax0.8380.831–0.8450.9020.7810.4100.8670.791
Logit-adjusted cross-entropy0.8260.818–0.8330.8850.7650.4050.8630.072
Focal, γ = 2 (selected)0.8400.833–0.8480.8840.7670.4070.8710.023
Top six blocks0.8060.797–0.8140.9060.7310.4060.8450.753
Bottleneck adapters0.8220.815–0.8280.8980.7570.4040.8490.792
LoRA0.8210.814–0.8280.8900.7580.4050.8540.793
Frozen encoder0.3620.353–0.3710.5840.2530.1780.4080.354
ECAPA: All layers, margin loss0.8330.827–0.8400.9100.7760.4610.8640.771
ECAPA: All layers, margin loss, 512 channels0.8340.827–0.8400.9010.7800.4550.8660.774
ECAPA: Focal, γ = 20.8280.821–0.8340.9010.7740.4540.8570.037
ECAPA: Focal, γ = 10.8290.822–0.8350.9050.7730.4550.8560.066
ECAPA: Focal, γ = 30.8230.815–0.8290.8960.7680.4560.8570.028
ECAPA: Class-balanced focal0.8280.821–0.8350.8970.7690.4560.8580.042
ECAPA: Focal, 512 channels0.8300.822–0.8360.9000.7730.4570.8640.039
ECAPA: Focal on a margin0.8350.828–0.8410.9050.7810.4630.8660.776
ECAPA: Focal, top six blocks0.8150.806–0.8220.9040.7480.4350.8540.035
ECAPA: Focal, duration crops0.8350.829–0.8410.8970.7800.4960.8590.021
ECAPA: Focal, distilled to 1 s0.7340.725–0.7420.8410.6320.5020.7750.128

Twenty-five arms around one reference. Cross-corpus macro-F1 is drawn with 95% bootstrap intervals over 10,755 clips: the five pooling heads span 0.825 to 0.837 and their intervals overlap; the frozen encoder, the distilled student and the two arms that unfreeze only the top six blocks fall furthest behind. Calibration error, on a log scale, splits by the kind of head: 0.75 to 0.79 for the fine-tuned cosine-margin heads, which the benchmark scored on their raw cosines, so that no clip was given more than 0.123 confidence; 0.02 to 0.08 for softmax heads, scored as trained (0.13 under distillation). Focal loss with attentive pooling has the highest macro-F1 (0.840) and an ECE of 0.023. Anuvani-LID paper, Figure 4; confidence from the predictions saved with each scorecard.

Pooling matters little. Under the margin loss the five pooling choices land between 0.825 and 0.837 cross-corpus macro-F1, and their intervals overlap (Figure 15). At this scale a more elaborate head buys nothing that can be measured.

Only the softmax heads were scored as probabilities. A cosine-margin head outputs a cosine between −1 and 1 for each language; in training the loss multiplies it by a scale of 30. The benchmark scored the cosines as they came, without that scale. Over 20 languages no clip then received a confidence above 0.123, while 84% to 88% of clips were right, so every fine-tuned margin head shows a calibration error of 0.75 to 0.79: the gap between the two. That number describes how the heads were scored, not how well they can be calibrated, which this stage did not measure. The softmax heads were scored as they trained, and reach 0.02 to 0.08, and 0.13 under distillation. Among them, with attentive pooling, focal loss has an ECE of 0.023, 2.6 times lower than cross-entropy’s, in line with Mukhoti et al., 2020, and the highest macro-F1 of all 25 arms (0.840). It costs no parameters and no compute: the network is the reference network with its objective changed and its last layer an ordinary softmax layer.

The accuracy ranking is inside the noise. Focal loss leads AM-Softmax (0.838) and cross-entropy (0.836) by 0.2 to 0.4 points, with one run each, against a run-to-run spread of about three. On accuracy alone we could not have chosen. Metrics also disagree: the arm that reads all 17 layers classifies 1.1% more clips correctly than the focal arm, although its macro-F1 is lower. So we kept both ideas, focal loss now, for a head whose confidence can be read as it comes and is the best calibrated of those, and the layer mix as a lever to test again at larger scale.

The encoder must be fine-tuned. A frozen encoder reaches only 0.362, the one gap among the adaptation arms that dwarfs the noise. Unfreezing the top six blocks reaches 0.806, adapters 0.822 and LoRA 0.821, each a little behind full fine-tuning; like the reference, each is a margin head, scored the same way. These arms also trained at a higher learning rate, so they are not a pure test of how much to adapt. The whole network trains.

A bigger back-end is not a better one. Given focal loss, the ECAPA-TDNN back-ends are softmax heads too, but the best of the eleven reaches 0.835 cross-corpus macro-F1, below attentive pooling with focal loss, for 23 million more parameters. Focal loss and the back-end do not add up: with focal loss the back-end scores 0.828, with the margin loss 0.833, and neither reaches 0.840. All of it is inside the noise.

Fig. 16 What the training curves can and cannot tell stage I · six of the 25 arms · 14,028 steps of 144 utterances · validation after each epoch

Training accuracy

0.00 0.25 0.50 0.75 1.00 0 3.5k 7k 10.5k 14k
Training accuracy
stepFocal, γ = 2Cross-entropyAll 17 layers, margin lossLoRATop six blocksFrozen encoder
740.0740.0670.0550.1510.0930.099
1,9740.9070.9220.9500.8910.9330.826
4,0240.9580.9710.9770.9450.9690.902
5,9740.9730.9750.9860.9570.9800.928
8,0240.9800.9830.9920.9740.9860.940
9,9740.9760.9840.9910.9750.9860.944
12,0240.9820.9880.9910.9830.9890.948
13,9490.9820.9870.9920.9800.9870.951

Clean validation accuracy

0.70 0.80 0.90 1.00 0 3.5k 7k 10.5k 14k
Clean validation accuracy
stepFocal, γ = 2Cross-entropyAll 17 layers, margin lossLoRATop six blocksFrozen encoder
3,5070.9690.9610.9650.9020.9760.738
7,0140.9700.9760.9680.9390.9870.797
10,5210.9750.9820.9730.9420.9890.822
14,0280.9770.9840.9770.9410.9900.826

Faint: the accuracy of one logged batch. Solid: its running mean. The validation axis starts at 0.7.

The numbers
Clean validation accuracy after four epochs, beside the benchmark score, for six Stage I arms
ArmClean validation accuracyBenchmark: cross-corpus macro-F1
Focal, γ = 20.9770.840
Cross-entropy0.9840.836
All 17 layers, margin loss0.9770.837
LoRA0.9410.821
Top six blocks0.9900.806
Frozen encoder0.8260.362

Curves separate the frozen encoder from everything else, and little more. Every arm that fine-tunes the whole encoder ends between 0.97 and 0.99 on clean validation. Unfreezing only the top six blocks gives the third-highest clean validation accuracy of all 25 arms (0.990) and the third-lowest cross-corpus score on the benchmark (0.806). Training logs (Weights & Biases).

Figure 16 is why the benchmark, not the curve, ranks the arms. On clean validation every arm that fine-tunes the whole encoder ends between 0.97 and 0.99, and where the order is not flat it misleads. The two arms that unfreeze only the top six blocks have the highest and the third-highest clean validation accuracy of all 25, 0.992 and 0.990. On the benchmark’s cross-corpus slice they rank 22nd and 23rd. The curves earn their place for one thing: they show at a glance that a frozen encoder is not a contender, and that nothing diverged.

Fig. 17 Clip length outweighs every design choice stage I · macro-F1 on random crops of 0.25 to 3 s · IndicVoices, FLEURS and Kathbath, whose training split is a fifth of the training audio · clip length on a log scale

IndicVoices crops

0.00 0.25 0.50 0.75 1.00 0.25 0.5 1 2 3
IndicVoices crops
positionFocal, γ = 2 (selected)Cross-entropy, label smoothingAll 17 layers, margin lossECAPA, all layersECAPA, focal, duration cropsECAPA, focal, distilled to 1 s
0.25 s0.0750.1060.1020.0800.0920.152
0.5 s0.1920.2660.2470.2420.2820.324
1 s0.4320.5030.5000.4900.5230.506
2 s0.6710.7090.7180.7130.7130.646
3 s0.7750.7970.8020.7870.7840.706

FLEURS crops

0.00 0.25 0.50 0.75 1.00 0.25 0.5 1 2 3
FLEURS crops
positionFocal, γ = 2 (selected)Cross-entropy, label smoothingAll 17 layers, margin lossECAPA, all layersECAPA, focal, duration cropsECAPA, focal, distilled to 1 s
0.25 s0.1200.1440.1330.1280.1510.224
0.5 s0.2920.3420.3350.3490.3970.446
1 s0.6020.6440.6490.6350.6750.647
2 s0.8300.8610.8640.8650.8610.787
3 s0.9130.9330.9330.9310.9150.826

Kathbath crops

0.00 0.25 0.50 0.75 1.00 0.25 0.5 1 2 3
Kathbath crops
positionFocal, γ = 2 (selected)Cross-entropy, label smoothingAll 17 layers, margin lossECAPA, all layersECAPA, focal, duration cropsECAPA, focal, distilled to 1 s
0.25 s0.1220.1450.1520.1410.1880.368
0.5 s0.3180.3860.3890.3760.4960.692
1 s0.6600.6950.7110.7210.7790.885
2 s0.8890.8950.9080.9100.9380.936
3 s0.9440.9510.9590.9580.9720.939
The numbers (IndicVoices crops)
Macro-F1 on IndicVoices crops of five lengths for six Stage I arms
Arm0.25 s0.5 s1 s2 s3 s
Focal, γ = 2 (selected)0.0750.1920.4320.6710.775
Cross-entropy, label smoothing0.1060.2660.5030.7090.797
All 17 layers, margin loss0.1020.2470.5000.7180.802
ECAPA, all layers0.0800.2420.4900.7130.787
ECAPA, focal, duration crops0.0920.2820.5230.7130.784
ECAPA, focal, distilled to 1 s0.1520.3240.5060.6460.706

Between three seconds and a quarter of a second every arm loses most of its accuracy. The selected arm falls from 0.775 to 0.075 on IndicVoices crops. At one second the arm that reads all 17 layers (0.500) and label smoothing (0.503) lead the last-layer heads, and training on cropped clips helps a back-end by 3.6 points. Distilling to one-second clips wins below one second and loses above it. Benchmark scorecards of the six arms.

Short clips are a different problem. Clip length moves macro-F1 more than any design choice in the stage (Figure 17). On IndicVoices crops the selected arm falls from 0.775 at three seconds to 0.432 at one and 0.075 at a quarter of a second. At one second the focal arm is the weakest of the ten pooling and loss arms. Three things helped there, and all three return later in the programme. Reading all 17 layers reached 0.500 under the margin loss, where the last-layer margin heads score 0.45 to 0.48. Label smoothing reached 0.503, against 0.456 for plain cross-entropy. And training on cropped clips added 4.5 points at half a second and 3.6 at one second to the same back-end without crops, and nothing at three seconds, the mark of a model matched to its training lengths. Distilling a full-clip teacher into a student that sees one second led every arm at a quarter and at half a second on all three corpora, and at one second only on Kathbath, a corpus the model had trained on (0.885 against 0.660 for the selected arm). Above that it fell behind, and its cross-corpus macro-F1 fell to 0.734.

One language disappears. Macro-F1 over 20 classes can hide a class at zero. On IndicVoices the focal arm recalls 20% of Dogri clips, the best of any arm, and the mean-and-deviation arm recalls none: it calls 141 of 200 Dogri clips Punjabi. Dogri and Punjabi are close relatives, and the subset was built to give every language a similar share of the audio, so this is confusability, not scarcity. It is the thread Stage II picks up with sampling, and the layer analysis picks up again inside the network.

What Stage I settled. Attentive statistics pooling, focal loss with γ = 2, and full fine-tuning at a single learning rate. The ECAPA-TDNN back-end was dropped, more for engineering than for accuracy: it adds a second network to train, export and serve, and it did not win on the cross-corpus slice. It did help on short clips: without crops the fully fine-tuned back-ends score 0.454 to 0.463 on the benchmark’s short-clip slice, against 0.407 for the selected arm, and crops took one to 0.496. The cropped training data, which any head can use, came back in Stage III.

Stage IIRebalancing: how far to flatten a skewed pool

4,000 h in the production language mix · 23 languages · 16 arms · 1 epoch each, three at 2 · scored on 55 conditions

Stage I trained on a balanced subset, so it could say nothing about imbalance: its two arms built for a skewed pool had no skew to correct. The real pool is far from balanced. English has 13,039 hours and Dogri 478. Stage II therefore moved to a 4,000-hour replica of the pool as it was catalogued then, which keeps its skew (English is 35% of the replica’s audio, Dogri 0.5%), added the three languages Stage I had left out, and held the Stage I model fixed. One question remained: how far should training flatten that mix?

The standard tool is temperature sampling: draw language ℓ with probability pℓ ∝ nℓ1/T, where nℓ is its share of the pool (Arivazhagan et al., 2019; Conneau et al., 2020). At T = 1 languages are sampled as the data comes, at T = 2 by the square root of their size, and as T grows without bound, equally. We trained six temperatures for one epoch each, 15,123 steps of 144 utterances.

Fig. 18 Raising the temperature trades the head for the tail stage II · 4,000 h replica of the pool · 23 languages · 1 epoch · one run per temperature; uniform sampling twice

Macro-F1, by temperature

0.86 0.90 0.94 0.98 1 1.5 2 3 5 ∞
Macro-F1, by temperature
positionCross-corpusClean benchmark
T = 1 (as the data comes)0.8900.923
T = 1.50.9160.944
T = 20.9190.946
T = 30.9160.947
T = 50.9150.945
T = ∞ (uniform)0.8980.922

F1 by resource tier

0.70 0.80 0.90 1.00 1 1.5 2 3 5 ∞
F1 by resource tier
positionUnder 500 h (Dogri, Konkani)500 to 1,000 h (5)1,000 to 2,000 h (5)Over 2,000 h (8)
T = 1 (as the data comes)0.7420.9400.9370.949
T = 1.50.9020.9500.9630.939
T = 20.9300.9490.9680.935
T = 30.9530.9470.9730.930
T = 50.9590.9400.9800.922
T = ∞ (uniform)0.9320.9290.9650.887

F1 of two languages

0.40 0.60 0.80 1.00 1 1.5 2 3 5 ∞
F1 of two languages
positionDogri (478 h)English (13,039 h)
T = 1 (as the data comes)0.4990.987
T = 1.50.8130.934
T = 20.8860.906
T = 30.9210.959
T = 50.9560.898
T = ∞ (uniform)0.9140.842

T = 1 samples languages as the data comes; T = ∞ samples them equally. Bands are 95% bootstrap intervals. Tiers are by hours in the full training pool; a tier’s F1 is the mean over the languages of it that the clean benchmark scores. No axis starts at zero.

The numbers
Stage II: macro-F1 and per-tier F1 at six sampling temperatures
TemperatureCross-corpusCleanUnder 500 h500 to 1,000 h1,000 to 2,000 hOver 2,000 hDogriEnglish
T = 1 (as the data comes)0.8900.9230.7420.9400.9370.9490.4990.987
T = 1.50.9160.9440.9020.9500.9630.9390.8130.934
T = 20.9190.9460.9300.9490.9680.9350.8860.906
T = 30.9160.9470.9530.9470.9730.9300.9210.959
T = 50.9150.9450.9590.9400.9800.9220.9560.898
T = ∞ (uniform)0.8980.9220.9320.9290.9650.8870.9140.842

One knob, six settings. First panel: macro-F1 rises from T = 1 to T = 1.5 and is flat within 0.4 points from 1.5 to 5; cross-corpus peaks at T = 2 (0.919). Uniform sampling scored 0.898 here, but its identical twin scored 0.930, so the drop at that end is one run’s. Second panel: mean F1 of the languages in each resource tier on the clean benchmark. Under 500 h it scores two languages, Dogri and Konkani; they rise from 0.742 to 0.930 between T = 1 and T = 2, while the eight over 2,000 h slip from 0.949 to 0.935. Third panel: the largest language and the one that moves most. Anuvani-LID paper, Figure 5, with the clean benchmark and two languages added from the same scorecards.

A rise, then a plateau. Cross-corpus macro-F1 rises from 0.890 at T = 1 to 0.919 at T = 2 (Figure 18, first panel), and the clean benchmark rises with it. From 1.5 to 5 the curve is flat within 0.4 points, so the choice inside that range is not one the data can make. The rise is three points, at the edge of what one run can show. At the other end, uniform sampling scored 0.898 in this sweep; but it was trained twice, and the identical second run scored 0.930, above every temperature. Whether flattening all the way costs accuracy, this stage cannot say.

The mechanism is a trade. Raising the temperature moves accuracy from the large languages to the small ones (Figure 18, second panel). Between T = 1 and T = 2 the languages under 500 hours rise from 0.742 to 0.930 mean F1, while the eight languages above 2,000 hours slip from 0.949 to 0.935. The clean benchmark scores only two of the five smallest, Dogri and Konkani, and the rise is Dogri’s, from 0.50 to 0.89; Konkani stays at 0.97 to 0.99. Under uniform sampling the large languages fell to 0.887 in one run and held 0.930 in its identical twin, so that end of the trade is not established. The largest language pays most. English scores 0.987 as the data comes and 0.906 at T = 2 (Figure 18, third panel). That is one language in one run, and it wobbles from arm to arm, but the direction came back at full scale, and it is why the final recipe puts a floor under English and Hindi.

Fig. 19 Rebalance once: a second correction takes it out of the large languages stage II · 4,000 h in the production language mix · 1 epoch · one run per arm · F1 on the clean benchmark
Rebalance once: a second correction takes it out of the large languages Eight arms. For each: mean F1 of the eight languages over 2,000 hours, mean F1 of the two languages under 500 hours that the clean benchmark scores, and cross-corpus calibration error. With no rebalancing the small languages reach 0.742. One rebalancer, in the sampler or in the loss, lifts them above 0.92 and leaves the large languages at 0.92 to 0.94. Two rebalancers together drop the large languages to 0.859 and 0.902. F1, over 2,000 h 0.84 0.88 0.92 0.96 F1, under 500 h 0.70 0.80 0.90 1.00 ECE, log scale 0.005 0.03 0.1 No rebalancing Focal, sampled as the data comes0.9490.7420.045 One rebalancer Sampler at T = 2, focal (kept)0.9350.9300.046 Logit-adjusted loss, T = 10.9180.9210.009 Class-balanced focal, T = 10.9290.9300.062 Two rebalancers Logit-adjusted loss on T = 20.8590.9450.035 Class-balanced focal on T = 20.9020.9420.042 Focal strength, at T = 2 γ = 10.9270.9510.033 γ = 30.9420.9650.078 Rebalance once: a second correction takes it out of the large languages: F1, over 2,000 h Eight arms. For each: mean F1 of the eight languages over 2,000 hours, mean F1 of the two languages under 500 hours that the clean benchmark scores, and cross-corpus calibration error. With no rebalancing the small languages reach 0.742. One rebalancer, in the sampler or in the loss, lifts them above 0.92 and leaves the large languages at 0.92 to 0.94. Two rebalancers together drop the large languages to 0.859 and 0.902. F1, languages over 2,000 h 0.84 0.88 0.92 0.96 No rebalancing Focal, T = 10.949 One rebalancer T = 2, focal0.935 Logit-adj., T = 10.918 Class-bal., T = 10.929 Two rebalancers Logit-adj., T = 20.859 Class-bal., T = 20.902 Focal strength, T = 2 γ = 10.927 γ = 30.942 Rebalance once: a second correction takes it out of the large languages: F1, under 500 h Eight arms. For each: mean F1 of the eight languages over 2,000 hours, mean F1 of the two languages under 500 hours that the clean benchmark scores, and cross-corpus calibration error. With no rebalancing the small languages reach 0.742. One rebalancer, in the sampler or in the loss, lifts them above 0.92 and leaves the large languages at 0.92 to 0.94. Two rebalancers together drop the large languages to 0.859 and 0.902. F1, languages under 500 h 0.70 0.80 0.90 1.00 No rebalancing Focal, T = 10.742 One rebalancer T = 2, focal0.930 Logit-adj., T = 10.921 Class-bal., T = 10.930 Two rebalancers Logit-adj., T = 20.945 Class-bal., T = 20.942 Focal strength, T = 2 γ = 10.951 γ = 30.965 Rebalance once: a second correction takes it out of the large languages: ECE, log scale Eight arms. For each: mean F1 of the eight languages over 2,000 hours, mean F1 of the two languages under 500 hours that the clean benchmark scores, and cross-corpus calibration error. With no rebalancing the small languages reach 0.742. One rebalancer, in the sampler or in the loss, lifts them above 0.92 and leaves the large languages at 0.92 to 0.94. Two rebalancers together drop the large languages to 0.859 and 0.902. Calibration error (ECE), log 0.005 0.03 0.1 No rebalancing Focal, T = 10.045 One rebalancer T = 2, focal0.046 Logit-adj., T = 10.009 Class-bal., T = 10.062 Two rebalancers Logit-adj., T = 20.035 Class-bal., T = 20.042 Focal strength, T = 2 γ = 10.033 γ = 30.078
Kept: sampler at T = 2, focal γ = 2 One rebalancer, in the loss Two rebalancers Focal strength None

Tiers are by hours in the full training pool: eight languages over 2,000 h; under 500 h, the two of five that the clean benchmark scores, Dogri and Konkani. No F1 axis starts at zero.

The numbers
Stage II: resource-tier F1, clean macro-F1 and calibration error of eight loss and sampling arms
ArmF1, over 2,000 hF1, under 500 hClean macro-F1ECE, cross-corpus
Focal, T = 1 (no rebalancing)0.9490.7420.9230.045
Sampler at T = 2, focal γ = 20.9350.9300.9460.046
Logit-adjusted loss, T = 10.9180.9210.9380.009
Class-balanced focal, T = 10.9290.9300.9420.062
Logit-adjusted loss on T = 20.8590.9450.9110.035
Class-balanced focal on T = 20.9020.9420.9300.042
Focal γ = 1, T = 20.9270.9510.9470.033
Focal γ = 3, T = 20.9420.9650.9570.078

A loss can correct the prior, or the sampler can; not both. Alone, each lifts the two smallest languages the benchmark scores from 0.742 to above 0.92. Stacked on a sampler that has already flattened the mix, logit adjustment takes 7.6 points from the eight largest languages (0.935 to 0.859) and class-balanced focal 3.3. Focal strength changes little except calibration: γ = 3 raises ECE to 0.078. The paper reports the stacked arm by its two largest classes: in-domain macro-F1 falls 3.5 points, English from 0.906 to 0.699 F1 and Hindi from 0.713 to 0.344. Benchmark scorecards of the eight arms.

Rebalance once. A loss can correct for class frequency too. Logit adjustment adds the log prior to the logits (Menon et al., 2021); here it replaces focal loss with plain cross-entropy. The other arm weights each class in the focal loss by the inverse square root of its clip count, a simpler form of the class-balanced loss of Cui et al., 2019. Alone, either does the sampler’s job: with languages sampled as the data comes, logit adjustment matches temperature sampling on the four plain cross-corpus sets, 0.925 against 0.925 at T = 3, and is the best-calibrated arm of the stage, an ECE of 0.011 on the clean benchmark against 0.046 for plain focal loss at T = 1. Stacked on a sampler at T = 2 the prior is counted twice. In-domain macro-F1 falls 3.5 points and the two largest classes collapse, English from 0.906 to 0.699 F1 and Hindi from 0.713 to 0.344; across the eight largest languages logit adjustment costs 7.6 points, and class-balanced focal 3.3 (Figure 19). The sampler stays the one rebalancer.

Focal strength is not a lever. γ = 1, 2 and 3 are 1.1 points apart on the clean benchmark. On 47 of the 55 conditions the three differ by less than the 3.2 points that separated two identical runs; the other eight are all crops of one second or less, where the largest gap is 4.5 points. The paper reads the same runs as γ = 3 gaining 1.0 point on the four plain cross-corpus sets and 3.6 over the six one-second conditions: single runs, the first inside the 3.2-point floor and the second among the short crops where the three part. What does move for certain is calibration: γ = 3 raises ECE from 0.046 to 0.078. γ = 2 stays.

Fig. 20 One switch: the head reads every layer stage II · 4,000 h · T = 2 · focal γ = 2 · 2 epochs each · the two runs differ in one setting

Training loss (log scale)

0.01 0.03 0.1 0.3 1 3 0 10k 20k 30k
Training loss (log scale)
stepHead reads all 17 layersHead reads the last layer
1243.7813.915
4,2990.2230.318
8,6990.1180.205
12,8990.0890.156
17,2990.0540.097
21,4990.0450.088
25,8990.0450.075
30,0990.0340.059

Clean validation accuracy

0.92 0.94 0.96 0.98 0 10k 20k 30k
Clean validation accuracy
stepHead reads all 17 layersHead reads the last layer
15,1230.9440.924
30,2460.9450.934

IndicVoices crops, macro-F1

0.00 0.25 0.50 0.75 1.00 0.25 0.5 1 2 3
IndicVoices crops, macro-F1
positionHead reads all 17 layersHead reads the last layer
0.25 s0.0580.090
0.5 s0.2520.256
1 s0.5640.534
2 s0.8160.790
3 s0.8980.874
Macro-F1 by acoustic family, last layer against all layers Mean macro-F1 over the conditions of each acoustic family for the head that reads the last layer and the head that reads all 17. All six families improve: undegraded, five sets +1.5 points, noise at 5 db +2.0 points, noise at 0 db +1.8 points, reverberation +1.6 points, 8 khz telephony +2.8 points, babble +0.7 points. Benchmark macro-F1 after training, by acoustic family 0.75 0.80 0.85 0.90 0.95 1.00 Undegraded, five setsLast layer: 0.940All 17 layers: 0.955+1.5 points Noise at 5 dBLast layer: 0.892All 17 layers: 0.912+2.0 points Noise at 0 dBLast layer: 0.866All 17 layers: 0.884+1.8 points ReverberationLast layer: 0.900All 17 layers: 0.916+1.6 points 8 kHz telephonyLast layer: 0.902All 17 layers: 0.930+2.8 points BabbleLast layer: 0.784All 17 layers: 0.790+0.7 points Macro-F1 by acoustic family, last layer against all layers: Benchmark macro-F1 after training, by acoustic family Mean macro-F1 over the conditions of each acoustic family for the head that reads the last layer and the head that reads all 17. All six families improve: undegraded, five sets +1.5 points, noise at 5 db +2.0 points, noise at 0 db +1.8 points, reverberation +1.6 points, 8 khz telephony +2.8 points, babble +0.7 points. Macro-F1 by acoustic family 0.75 0.85 0.95 UndegradedLast layer: 0.940All 17 layers: 0.955+1.5 points Noise, 5 dBLast layer: 0.892All 17 layers: 0.912+2.0 points Noise, 0 dBLast layer: 0.866All 17 layers: 0.884+1.8 points ReverberationLast layer: 0.900All 17 layers: 0.916+1.6 points TelephonyLast layer: 0.902All 17 layers: 0.930+2.8 points BabbleLast layer: 0.784All 17 layers: 0.790+0.7 points

Faint: one logged batch. Solid: its running mean. Below, each point is the mean over the conditions of its family. No axis but the crop panel’s starts at zero.

The numbers
Stage II: macro-F1 by acoustic family for the last-layer head and the all-layer head, two epochs each
Acoustic familyConditionsLast layerAll 17 layersChange, points
Clean benchmark10.9580.967+0.9
Undegraded, five sets50.9400.955+1.5
Noise at 5 dB40.8920.912+2.0
Noise at 0 dB40.8660.884+1.8
Reverberation40.9000.916+1.6
8 kHz telephony40.9020.930+2.8
Babble40.7840.790+0.7

At equal budget the head that reads all 17 layers trains to a lower loss. On the benchmark it raises clean macro-F1 from 0.958 to 0.967 and every acoustic family with it, telephony most (+2.8 points), and five of the six SPRING-INX conditions by 3.0 to 3.8 points. It loses on the shortest clips: 2.9 to 4.8 points on every condition at a quarter of a second. None of the family gains is larger than the three points two identical runs can differ by. Training logs (Weights & Biases) and benchmark scorecards.

The layer mix returns. Stage I had kept one idea in reserve: let the head read a learned mix of all 17 layers instead of the last one. Stage II tested it at equal budget, two epochs each, with that one setting changed (Figure 20). In-domain macro-F1 rose from 0.958 to 0.967 and every acoustic family improved: telephony by 2.8 points, noise by 1.9, reverberation by 1.6, babble by 0.7. Five of the six SPRING-INX conditions gained 3.0 to 3.8 points. None of the family gains clears three points alone. The shortest clips went the other way: every condition at a quarter of a second lost 2.9 to 4.8 points, and every one at half a second lost up to 3.5. We adopted the mix for the breadth of the gain on full-length speech, and because when the next stage trained the same recipe again as its baseline it scored 0.967 once more. The short clips were left to the next stage’s duration crops.

A second epoch helped as well, 0.946 to 0.958 on the clean benchmark with the same sign on every slice. We took the direction, that later screens should run two epochs, and did not claim the size.

What Stage II settled. Sample near T = 2; rebalance in the sampler and nowhere else; keep focal loss at γ = 2; read all 17 layers. And one rule that outlasted the stage: a result is not a result until it clears three points, or repeats.

Stage IIIAugmentation: train on the conditions you will be tested on

4,000 h replica of the pool · 23 languages · 8 arms: seven at 2 epochs, and a babble run of 65,000 steps against the full stack without babble · one run per arm

By the end of Stage II the model was strong on full-length clean speech and weak exactly where a deployed identifier works: on a second of audio, in noise, in a reverberant room, over a telephone line. Stage III asked which perturbations of the training audio close those gaps. One rule was fixed before any run: an augmentation earns its place if it lifts the conditions it imitates without lowering clean speech.

The Stage II recipe already perturbed its audio in two ways, and both stayed on in every arm: speed perturbation (Ko et al., 2015), and SpecAugment (Park et al., 2019), which masks bands of the spectrogram, two in frequency and ten in time. That recipe is the baseline. Each arm changed one thing against it, and the last stacked them. Additive noise comes from 930 MUSAN noise clips at 0 to 15 dB (Snyder et al., 2015) and reverberation from 60,000 simulated room impulse responses (Ko et al., 2017). A codec arm passes audio through 8 kHz µ-law telephony. A duration arm crops half of all clips to a random length. One arm softens SpecAugment, from ten time masks to two. The noise clips and the impulse responses are the same pools the benchmark’s noise and reverberation conditions were built from, so those two families measure robustness to sounds and rooms the model has heard in training, not to new ones.

The first screen collapsed, and taught two things. We first ran the ladder for one epoch per arm. Three of its six arms finished at exactly chance: validation accuracy 0.0435, one in 23, with a loss that was no longer a number within the first 300 steps. All three carried the reverberation perturbation, which divides the reverberated clip by its own peak. On a clip of pure digital silence that is zero divided by zero; one such clip makes the batch loss NaN, and the optimiser carries it into almost every weight. The trigger was inferred, not caught: no silent clip turned up among those checked, but injecting silent clips reproduced the collapse. The repair has three layers: perturbations that skip a degenerate clip and return it clean, a guard that zeroes the gradients of any step that produces a non-finite one, and tests that inject silent clips. The second lesson was harder to read. That screen’s SpecAugment arm widened the masks, to ten time masks of up to a tenth of a clip each, and ended its epoch at 0.825 validation accuracy against the baseline’s 0.933. Masks wide enough to blank a short clip, or one epoch too short for a regulariser to pay back its cost: the screen cannot separate the two. The ladder was run again with both changed, at two epochs, with the masks softened instead of widened, on the layer-mix model Stage II had just adopted.

Fig. 21 Each perturbation moves the axis it simulates stage III · 4,000 h · 2 epochs · one run per arm · macro-F1 over the 44 conditions common to all arms

Training loss (log scale)

0.03 0.1 0.3 1 3 0 10k 20k 30k
Training loss (log scale)
stepBaselineNoise and room impulsesDuration cropFull stack
1243.8304.0854.0814.056
4,7490.1940.279
8,6990.1200.180
12,7990.2490.353
16,7740.2470.341
20,7990.0540.122
26,1490.0490.1040.1960.319
30,3990.1910.293

Training accuracy

0.60 0.70 0.80 0.90 1.00 0 10k 20k 30k
Training accuracy
stepBaselineNoise and room impulsesDuration cropFull stack
1240.0790.0690.0470.038
4,7490.9180.885
8,6990.9480.920
12,7990.8890.848
16,7740.9010.853
20,7990.9740.951
26,1490.9780.9520.9140.867
30,3990.9190.875

Macro-F1, by clip length

0.00 0.25 0.50 0.75 1.00 0.25 0.5 1 2 3
Macro-F1, by clip length
positionBaselineNoise and room impulsesDuration cropFull stack
0.25 s0.0730.0410.1540.157
0.5 s0.3030.2670.3980.410
1 s0.6480.6570.7120.723
2 s0.8690.8810.8980.905
3 s0.9350.9420.9490.951
Change in macro-F1 against the baseline, by condition family Change in macro-F1, in points, of five augmentation arms against the baseline arm, which perturbs speed and masks the spectrogram and nothing more, on eight families of conditions. Duration crop adds +9.5 at 0.5 s; noise and room impulses add +3.2 in noise and cost −3.6 at 0.5 s; the codec adds +1.0 on telephony; the full stack adds +10.7 at 0.5 s and +3.8 in noise for −0.4 on clean speech. Change in benchmark macro-F1 against the baseline, in points −4 −2 0 +2 +4 +6 +8 +10 +12 Clean speechSofter SpecAugment: +0.6Noise and room impulses: −0.28 kHz codec: +0.1Duration crop: −0.3Full stack: −0.4−0.4 Crops of 0.5 sSofter SpecAugment: +0.9Noise and room impulses: −3.68 kHz codec: +0.2Duration crop: +9.5Full stack: +10.7+10.7 Crops of 1 sSofter SpecAugment: +0.3Noise and room impulses: +0.98 kHz codec: +0.2Duration crop: +6.4Full stack: +7.5+7.5 NoiseSofter SpecAugment: +0.6Noise and room impulses: +3.28 kHz codec: +0.9Duration crop: +1.3Full stack: +3.8+3.8 ReverberationSofter SpecAugment: +0.6Noise and room impulses: +1.68 kHz codec: +0.6Duration crop: +1.2Full stack: +2.0+2.0 8 kHz telephonySofter SpecAugment: −0.1Noise and room impulses: +0.68 kHz codec: +1.0Duration crop: +0.4Full stack: +1.2+1.2 BabbleSofter SpecAugment: +1.0Noise and room impulses: +1.68 kHz codec: +0.1Duration crop: −0.5Full stack: +2.0+2.0 Confusable languagesSofter SpecAugment: +0.2Noise and room impulses: −0.18 kHz codec: +0.3Duration crop: 0.0Full stack: +0.2+0.2 Change in macro-F1 against the baseline, by condition family: Change in benchmark macro-F1 against the baseline, in points Change in macro-F1, in points, of five augmentation arms against the baseline arm, which perturbs speed and masks the spectrogram and nothing more, on eight families of conditions. Duration crop adds +9.5 at 0.5 s; noise and room impulses add +3.2 in noise and cost −3.6 at 0.5 s; the codec adds +1.0 on telephony; the full stack adds +10.7 at 0.5 s and +3.8 in noise for −0.4 on clean speech. Change in macro-F1, points −4 0 +4 +8 +12 CleanSofter SpecAugment: +0.6Noise and room impulses: −0.28 kHz codec: +0.1Duration crop: −0.3Full stack: −0.4−0.4 0.5 s cropsSofter SpecAugment: +0.9Noise and room impulses: −3.68 kHz codec: +0.2Duration crop: +9.5Full stack: +10.7+10.7 1 s cropsSofter SpecAugment: +0.3Noise and room impulses: +0.98 kHz codec: +0.2Duration crop: +6.4Full stack: +7.5+7.5 NoiseSofter SpecAugment: +0.6Noise and room impulses: +3.28 kHz codec: +0.9Duration crop: +1.3Full stack: +3.8+3.8 ReverberationSofter SpecAugment: +0.6Noise and room impulses: +1.68 kHz codec: +0.6Duration crop: +1.2Full stack: +2.0+2.0 TelephonySofter SpecAugment: −0.1Noise and room impulses: +0.68 kHz codec: +1.0Duration crop: +0.4Full stack: +1.2+1.2 BabbleSofter SpecAugment: +1.0Noise and room impulses: +1.68 kHz codec: +0.1Duration crop: −0.5Full stack: +2.0+2.0 ConfusableSofter SpecAugment: +0.2Noise and room impulses: −0.18 kHz codec: +0.3Duration crop: 0.0Full stack: +0.2+0.2

Faint: one logged batch. Solid: its running mean. The baseline is the Stage II recipe, which already perturbs speed and masks the spectrogram. Below, each point is one arm’s change against it; the figure beside each row is the full stack’s. The loss axis is logarithmic and the accuracy axis starts at 0.6.

The numbers
Stage III: macro-F1 of the baseline arm, and the change each augmentation arm makes, by condition family
ArmClean speechCrops of 0.5 sCrops of 1 sNoiseReverberation8 kHz telephonyBabbleConfusable languages
Baseline (macro-F1)0.9620.3030.6480.8940.9190.9330.7920.979
Softer SpecAugment (change, points)+0.6+0.9+0.3+0.6+0.6−0.1+1.0+0.2
Noise and room impulses (change, points)−0.2−3.6+0.9+3.2+1.6+0.6+1.6−0.1
8 kHz codec (change, points)+0.1+0.2+0.2+0.9+0.6+1.0+0.1+0.3
Duration crop (change, points)−0.3+9.5+6.4+1.3+1.2+0.4−0.50.0
Full stack (change, points)−0.4+10.7+7.5+3.8+2.0+1.2+2.0+0.2

The run that is hardest to train is the best on the benchmark. Top: with the full stack the training loss ends eight times higher and training accuracy ten points lower than the baseline’s, and macro-F1 on short crops rises at every length. Bottom: the change each arm makes, family by family. Duration crop moves the short crops (+9.5 points at 0.5 s), noise and room impulses move noise (+3.2), the codec moves telephony (+1.0), and the full stack keeps all three for 0.4 points of clean speech. Training logs (Weights & Biases); benchmark figures from the Anuvani-LID paper, Figure 6.

Each perturbation moves the axis it simulates. Duration cropping adds 9.5 points at half a second. Noise with room impulses adds 3.2 points in noise, and the codec adds 1.0 on telephony (Figure 21, bottom). Softening SpecAugment moves every family by 1.0 point or less, upward in all but one. The interactions matter as much. Alone, noise and reverberation cost 3.6 points at half a second; inside the stack, with cropping beside them, that cost is gone. The full stack gains 10.7 points at half a second, 7.5 at one second and 3.8 in noise for 0.4 points of clean speech, a price inside the noise floor.

The short-clip gains clear three points by a wide margin; the gains in noise, 3.2 and 3.8, sit at its edge. The three arms that crop were trained on a rebuilt copy of the replica after a storage move, so the comparison across that boundary is less clean than the one within it. The pattern is what we rely on: each arm’s largest gain falls on the family it was built for.

Training looks worse as the model gets better. The curves in Figure 21 run opposite to the benchmark. With the full stack the training loss ends about eight times higher than the baseline’s, training accuracy is 0.88 against 0.98, and clean validation accuracy is 0.935 against 0.949, though the two runs were validated on different copies of the replica. On the benchmark the same run is the best of the six ladder arms at every clip length. It is Stage I’s lesson again: a curve on the training distribution measures how hard the training data is, not how good the model is.

One arm was dropped on calibration. A consistency branch that pulls the predictions for two augmented views of a clip together added 2.0 points at half a second over the full stack, inside the noise, and doubled its calibration error, from 0.055 to 0.112. The stack had already raised it from the baseline’s 0.034, as cropping alone did.

What Stage III settled. Speed perturbation, MUSAN noise, room impulses, an 8 kHz codec, duration crops and babble, each applied to a share of the clips, and a softened SpecAugment on every clip.

Stage IVCurriculum: does the order of what the model hears matter?

4,000 h replica · 23 languages · 5 arms · 3 epochs each · one run per arm · scored on 87 conditions

Stages I to III fixed what the model sees. Stage IV asked whether the order in which it sees it adds anything (Bengio et al., 2009). We expected the largest return where the static recipe left the most error: on the confusable Indo-Aryan cluster, the weakest clean axis of Stage II at 0.909 macro-F1 on confusable pairs, and on input shorter than a second. A curriculum is a measure of difficulty and a schedule for moving along it. We kept one schedule, the competence schedule of Platanios et al., 2019, which carries an axis from its easy end to its hard end over the epochs, c(e) = min(1, √(e(1 − c02)/(N − 1) + c02)) with c0 = 0.2, and screened four measures of difficulty, each changing one axis of the Stage III recipe on the 4,000-hour replica for three epochs:

  • Duration. Training crops shrink from 6.6 to 2.95 to 1.0 seconds, in place of the random crop. It inverts SortaGrad (Amodei et al., 2016): a short clip is easy for recognition but carries less evidence for identification.
  • Resource. The sampling temperature rises from 1.2 to 2.0, so the large languages dominate early and the tail gains weight late; a reverse arm, from 1.8 to 1.0, controls for the direction.
  • Confusability. The 15 Indo-Aryan languages enter at 0.36 of their sampled weight, rising to 0.78 and then 1.0, so the Dravidian, Tibeto-Burman and Austroasiatic languages and English are seen at full weight first and the cluster where most confusions arise is brought in gradually.
  • Self-paced. Within each batch only the lowest-loss 68% of examples enter the loss, rising to all of them (Kumar, Packer & Koller, 2010).
Fig. 22 Five curricula: one bought short clips, three could not be tested stage IV · 4,000 h replica · 23 languages · 3 epochs each · one run per arm · macro-F1
Five curricula: one bought short clips, three could not be tested Five curriculum arms on four measures. Duration ordering reaches 0.517 at half a second and 0.257 at a quarter of a second, averaged over five corpora, against 0.422–0.430 and 0.170–0.177 for the three arms whose schedules never reached the sampler, but 0.896 on the all-23 test and 0.941 on the clean benchmark, against 0.927–0.930 and 0.970–0.974. The self-paced gate scores 0.904 and 0.968. Crops, 0.5 s 0.3 0.5 Crops, 0.25 s 0.1 0.2 0.3 All-23 test 0.88 0.92 In-domain 0.93 0.97 Schedule applied Duration, 6.6 to 1.0 s0.5170.2570.8960.941 Self-paced, 68% to all0.3860.1410.9040.968 Schedule never reached the sampler: the unscheduled recipe Resource, T 1.2 to 2.00.4300.1760.9280.974 Reverse, T 1.8 to 1.00.4220.1700.9270.970 Confusability, 0.36 to 10.4280.1770.9300.973 Five curricula: one bought short clips, three could not be tested: Crops, 0.5 s Five curriculum arms on four measures. Duration ordering reaches 0.517 at half a second and 0.257 at a quarter of a second, averaged over five corpora, against 0.422–0.430 and 0.170–0.177 for the three arms whose schedules never reached the sampler, but 0.896 on the all-23 test and 0.941 on the clean benchmark, against 0.927–0.930 and 0.970–0.974. The self-paced gate scores 0.904 and 0.968. Crops of 0.5 s 0.3 0.4 0.5 0.6 Schedule applied Duration0.517 Self-paced0.386 Never applied: unscheduled Resource0.430 Reverse0.422 Confusability0.428 Five curricula: one bought short clips, three could not be tested: Crops, 0.25 s Five curriculum arms on four measures. Duration ordering reaches 0.517 at half a second and 0.257 at a quarter of a second, averaged over five corpora, against 0.422–0.430 and 0.170–0.177 for the three arms whose schedules never reached the sampler, but 0.896 on the all-23 test and 0.941 on the clean benchmark, against 0.927–0.930 and 0.970–0.974. The self-paced gate scores 0.904 and 0.968. Crops of 0.25 s 0.1 0.2 0.3 Schedule applied Duration0.257 Self-paced0.141 Never applied: unscheduled Resource0.176 Reverse0.170 Confusability0.177 Five curricula: one bought short clips, three could not be tested: All-23 test Five curriculum arms on four measures. Duration ordering reaches 0.517 at half a second and 0.257 at a quarter of a second, averaged over five corpora, against 0.422–0.430 and 0.170–0.177 for the three arms whose schedules never reached the sampler, but 0.896 on the all-23 test and 0.941 on the clean benchmark, against 0.927–0.930 and 0.970–0.974. The self-paced gate scores 0.904 and 0.968. All-23 test 0.88 0.90 0.92 0.94 Schedule applied Duration0.896 Self-paced0.904 Never applied: unscheduled Resource0.928 Reverse0.927 Confusability0.930 Five curricula: one bought short clips, three could not be tested: In-domain Five curriculum arms on four measures. Duration ordering reaches 0.517 at half a second and 0.257 at a quarter of a second, averaged over five corpora, against 0.422–0.430 and 0.170–0.177 for the three arms whose schedules never reached the sampler, but 0.896 on the all-23 test and 0.941 on the clean benchmark, against 0.927–0.930 and 0.970–0.974. The self-paced gate scores 0.904 and 0.968. In-domain (clean benchmark) 0.93 0.95 0.97 Schedule applied Duration0.941 Self-paced0.968 Never applied: unscheduled Resource0.974 Reverse0.970 Confusability0.973

Crops: mean macro-F1 over five corpora (Common Voice, FLEURS, Kathbath, MUCS and the all-23 test). All-23 test: IndicVoices, speakers held out. In-domain: the clean benchmark. No axis starts at zero, and each has its own range.

The numbers
Stage IV: macro-F1 of the five curriculum arms on short crops, the all-23 test and the clean benchmark
ArmSchedule appliedCrops of 0.25 sCrops of 0.5 sCrops of 1 sAll-23 testClean benchmark
Duration, 6.6 to 1.0 syes0.2570.5170.7680.8960.941
Self-paced, 68% to allyes0.1410.3860.6990.9040.968
Resource, T 1.2 to 2.0no0.1760.4300.7270.9280.974
Reverse, T 1.8 to 1.0no0.1700.4220.7260.9270.970
Confusability, 0.36 to 1no0.1770.4280.7280.9300.973

Ordering by duration is the only curriculum that changes the short clips: at half a second it scores 0.52 against 0.42 to 0.43, and at a quarter of a second 0.26 against 0.17 to 0.18. It pays on full-length speech, 0.896 on the all-23 test against 0.927 to 0.930. The self-paced gate adds nothing. In the last three arms the schedule never reached the sampler, so they are three runs of the unscheduled recipe, and the paper uses them as its baseline. Anuvani-LID paper, Stage IV; the arms’ scorecards.

Ordering by duration buys short clips, and pays for them. Against the unscheduled recipe trained for the same three epochs, it lifts mean macro-F1 over five corpora from 0.42–0.43 to 0.52 at half a second, and from 0.17–0.18 to 0.26 at a quarter of a second (Figure 22). No other curriculum comes close on short input. But by its last epoch every clip was cut to a second, and the model heard little full-length speech: the all-23 test falls from 0.927–0.930 to 0.896, and the clean benchmark from 0.970–0.974 to 0.941. The self-paced gate did not add to the unscheduled recipe, at 0.904 and 0.968.

Three arms could not answer their question. In the resource arm, its reverse and the confusability arm, the schedule never reached the sampler. The code that should have reweighted the sampler at each epoch had lost its handle to it, skipped the update and logged a warning, in every epoch of all three runs; static temperature sampling went on as before. They are three runs of the unscheduled recipe, and that is how the paper uses them: as the baseline the duration and self-paced arms are measured against. Nothing in this stage measured whether ramping the Indo-Aryan cluster helps.

Why the ramp was kept. The final recipe schedules the language mix, on the evidence of where the errors are rather than of a measured gain. Of the unscheduled recipe’s errors on the all-23 test, 65% to 66% are on Indo-Aryan languages. Of the four curricula, the confusability ramp is the one that acts on that cluster without moving a tuned setting. The bimodal crop of Stage III already gives the short-clip exposure of the duration curriculum while keeping long segments in every batch; the self-paced gate added nothing; and the resource curriculum would hold the temperature away from T = 2, where Stage II’s curve peaks, for most of training. The ramp changes which languages fill a batch as training proceeds, not how often each is drawn relative to its size; it returns to the tuned mix by the last sub-epoch and costs nothing at inference. Once the sampler was repaired, a pair of 65,000-step runs on the proxy, with the ramp and without it, ended at 0.952 and 0.953 development accuracy (Stage V): a tie. So the ramp stays as a low-regret choice. We do not count it as a measured gain.

Fig. 23 The confusability ramp, as the final run applied it stage VI’s run · 425,000 steps in 17 sub-epochs of 25,000 · T = 1.75 · floors for English and Hindi · shares from the run’s own sampler

Weight on the Indo-Aryan languages

0.00 0.25 0.50 0.75 1.00 1 5 9 13 17 plain mix
Weight on the Indo-Aryan languages
sub-epochIndo-Aryan weight, as applied
11.000
30.520
60.667
80.743
100.809
120.869
150.951
171.000

Share of the samples, by family

0% 20% 40% 60% 1 5 9 13 17
Share of the samples, by family
sub-epochIndo-Aryan, 15 languagesDravidian, 4English, floor 16%Tibeto-Burman, 2Austroasiatic, 1
10.5730.2120.1600.0390.016
30.4510.2990.1720.0550.023
60.5020.2690.1600.0490.020
80.5210.2530.1600.0470.019
100.5370.2410.1600.0440.018
120.5490.2310.1600.0420.017
150.5650.2190.1600.0400.016
170.5730.2120.1600.0390.016

One point per sub-epoch; the Indo-Aryan key switches both of its lines. The first sub-epoch drew the plain temperature mix, before the schedule took effect; the weight shown there is 1. Shares are of all samples drawn; Hindi, inside the Indo-Aryan share, is held at 11% throughout.

The numbers
The final run: the Indo-Aryan weight and each family's share of the samples in each of its 17 sub-epochs
Sub-epochIndo-Aryan weightIndo-AryanDravidianEnglishTibeto-BurmanAustroasiatic
1plain mix57.3%21.2%16.0%3.9%1.6%
20.45342.2%31.4%18.2%5.8%2.4%
30.52045.1%29.9%17.2%5.5%2.3%
40.57547.3%28.8%16.5%5.3%2.2%
50.62349.0%27.8%16.0%5.1%2.1%
60.66750.2%26.9%16.0%4.9%2.0%
70.70651.2%26.0%16.0%4.8%2.0%
80.74352.1%25.3%16.0%4.7%1.9%
90.77753.0%24.7%16.0%4.5%1.9%
100.80953.7%24.1%16.0%4.4%1.8%
110.84054.3%23.6%16.0%4.3%1.8%
120.86954.9%23.1%16.0%4.2%1.7%
130.89755.5%22.6%16.0%4.2%1.7%
140.92456.0%22.2%16.0%4.1%1.7%
150.95156.5%21.9%16.0%4.0%1.6%
160.97656.9%21.5%16.0%4.0%1.6%
171.00057.3%21.2%16.0%3.9%1.6%

After a first sub-epoch on the plain temperature mix, the weight on the 15 Indo-Aryan languages rises from 0.45 to 1.0 along a square-root schedule. The Indo-Aryan languages go from 42% of the samples to 57%, the Dravidian four from 31% to 21% and English from 18% to 16%; by the last sub-epoch the mix is the plain one again. Anuvani-LID paper, Figure 7; shares from the run’s sampler on its training index, as the paper computes them.

At full scale the ramp spans the 17 sub-epochs of 25,000 steps that make up the 425,000-step run (Figure 23). The first sub-epoch drew the plain temperature mix, because the data workers start before the schedule is applied; from the second, the weight on the Indo-Aryan cluster rises from 0.45 to 1.0, on top of T = 1.75 and the floors of Stage V. In the first scheduled sub-epoch the Indo-Aryan languages take 42% of the samples, the Dravidian four 31% and English 18%; by the last, 57%, 21% and 16%, the plain mix again. Hindi is held at its 11% floor throughout. The run logged the schedule at every sub-epoch, and the shares drawn here reproduce every share it logged.

What Stage IV settled. The confusability ramp on the 15 Indo-Aryan languages, kept for where the errors are and for what it leaves alone. The short-clip gain of the duration curriculum is taken instead from Stage III’s bimodal crop, which keeps long segments in every batch.

Stage VOptimisation: a recipe for fourteen times the data

4,000 h proxy · 23 languages · 15 short probes, then seven 65,000-step runs · one run each

Everything so far was tuned on 4,000 hours or fewer. The full pool is 54,643 hours, about fourteen times the proxy. The proxy keeps every language’s share of the audio, so anything that depends on the mix carries over. What does not carry over is repetition: how many times training passes over the same clip. Stage V set the optimiser on the proxy and then asked which of its answers survive the change of scale. The proxy itself was drawn again from the final 54,643-hour pool, with the construction of Stage II, so that its language ratios are the pool’s.

Fig. 24 Short probes: a knee in the learning rate, and two flat knobs stage V · 4,000 h proxy · 1,200 to 2,500 steps per probe · accuracy on the 3,450-clip development set

Dev accuracy, by learning rate

0.76 0.80 0.84 0.88 3e-5 1e-4 3e-4 1e-3 kept
Dev accuracy, by learning rate
peak rateAfter 1,200 steps
3e-50.771
1e-40.839
3e-40.872
1e-30.876

Dev accuracy, by temperature

0.86 0.87 0.88 0.89 0.90 0.91 1.5 1.75 2 2.25 2.5
Dev accuracy, by temperature
T =After 2,500 steps
1.50.887
1.750.890
20.893
2.250.900
2.50.899

Dev accuracy, by warm-up

0.86 0.87 0.88 0.89 0.90 0.91 5% 10% 15% kept
Dev accuracy, by warm-up
warm-upAfter 1,200 steps
5% of the steps0.874
10% of the steps0.871
15% of the steps0.873

Each point is one short run. The learning-rate axis is logarithmic, with rates written as in the configuration: 3e-4 is 3 × 10⁻⁴. No vertical axis starts at zero, and the first spans three times the range of the other two.

The numbers
Stage V: development accuracy of twelve short probes
ProbeSettingStepsDev accuracy
Peak learning rate3 × 10⁻⁵12000.7708
Peak learning rate10⁻⁴12000.8386
Peak learning rate3 × 10⁻⁴12000.8715
Peak learning rate10⁻³12000.8761
Sampling temperature1.525000.8874
Sampling temperature1.7525000.8900
Sampling temperature2.025000.8931
Sampling temperature2.2525000.8995
Sampling temperature2.525000.8990
Warm-up5%12000.8740
Warm-up10%12000.8708
Warm-up15%12000.8735

Only the learning rate has a slope worth following. From 3 × 10⁻⁵ to 10⁻³ development accuracy rises from 0.771 to 0.876, and the last step adds 0.5 points: the knee is at 3 × 10⁻⁴. Temperatures from 1.5 to 2.5 stay within 1.2 points and warm-ups from 5% to 15% within 0.3. Anuvani-LID paper, Stage V; the probe log.

Short probes find one knee. Twelve runs of 1,200 to 2,500 steps varied the learning rate, the temperature or the warm-up, one setting at a time, and three shorter ones checked the batch size. Peak learning rates from 3 × 10−5 to 10−3 gave development accuracies from 0.771 to 0.876 (Figure 24). We took the knee at 3 × 10−4: the last step up added only 0.5 points, and a rate past the knee puts the pre-trained encoder at risk for little return. Warm-ups of 5% to 15% of the steps were flat within 0.3 points and temperatures from 1.5 to 2.5 within 1.2, so those two were set on other grounds: the shortest warm-up, and a temperature chosen below.

Fig. 25 A longer horizon changes the answer stage V · 4,000 h proxy · development accuracy during training · temperature runs are 65,000 steps, about 4.3 passes

Two learning rates, at length

0.88 0.90 0.92 0.94 0.96 0 20k 40k 60k
Two learning rates, at length
stepRate 3e-4Rate 1e-4
5,0000.891
10,0000.907
15,0000.922
15,2570.913
25,2570.941
30,5140.932
45,7710.943
61,0280.945

Three temperatures, no ramp

0.88 0.90 0.92 0.94 0.96 0 20k 40k 60k
Three temperatures, no ramp
stepT = 1.35T = 1.5T = 2
8,0000.9090.8980.898
23,2570.9270.9280.936
38,5140.9380.9370.941
53,7710.9500.9530.950

Four temperatures, with the ramp

0.88 0.90 0.92 0.94 0.96 0 20k 40k 60k
Four temperatures, with the ramp
stepT = 1.5T = 1.75T = 2.33T = 3
8,0000.8920.9120.8980.904
23,2570.9260.9240.9390.938
38,5140.9430.9420.9420.941
53,7710.9520.9520.9450.946

Each point is one pass over the development set, as logged; a temperature run’s last is at step 53,771 of its 65,000. Rates are written as in the configuration: 3e-4 is 3 × 10⁻⁴. The ramp is Stage IV’s curriculum on the Indo-Aryan languages, applied in these runs. All vertical axes start at 0.88.

The numbers
Stage V: development accuracy of seven 65,000-step runs at four evaluations
RunStep 8,000Step 23,257Step 38,514Step 53,771
T = 1.35, no ramp0.90910.92660.93770.9497
T = 1.5, no ramp0.89820.92760.93650.9534
T = 2, no ramp0.89810.93580.94090.9499
T = 1.5, with the ramp0.89230.92600.94340.9518
T = 1.75, with the ramp0.91180.92440.94170.9523
T = 2.33, with the ramp0.89820.93890.94250.9452
T = 3, with the ramp0.90370.93760.94100.9464

At three times the rate the model reaches 0.941 by step 25,000; at 10⁻⁴ it needs about 46,000 steps to reach 0.943, though the two runs also differ in schedule length and warm-up. The second and third panels follow seven temperatures over a full schedule. At the last evaluation, temperatures from 1.35 to 2 are within 0.4 points of each other; 2.33 and 3 are 0.5 to 0.7 below the runs at 1.5 and 1.75, and every run is still improving. The order at the end is not the order on the way: at step 23,000 the two highest temperatures lead every run from 1.35 to 1.75 by more than a point. Trainer logs (TensorBoard; Weights & Biases for the slower rate).

A short probe rewards whatever learns fastest. Two longer checks kept us honest (Figure 25). The first was consistent with the learning rate: a 30,000-step run at 3 × 10−4 reached 0.941 development accuracy by step 25,000, where an earlier 61,000-step run at 10−4, with a 10% warm-up, needed about 46,000 steps to reach 0.943. The two differ in schedule as well as rate, so this is a check, not a controlled comparison. The second re-opened the temperature. Seven runs of 65,000 steps, about 4.3 passes over the proxy, stood within 0.4 points of one another at their last evaluation for every temperature from 1.35 to 2, and 2.33 and 3 stood 0.5 to 0.7 points below the runs at 1.5 and 1.75. Midway the picture was the reverse: at step 23,000 the two highest temperatures led every run from 1.35 to 1.75 by more than a point, with T = 2 just behind them. A sweep stopped after a pass and a half would have chosen differently. We chose T = 1.75, inside the flat range. The runs do not single it out; it is the temperature at which the full augmentation stack, babble included, was validated, and because the proxy keeps the pool’s language ratios, the same temperature gives the same sampling mix at full scale. Only the number of repetitions grows.

Count the budget in passes, not epochs. Temperature sampling replays small languages. The number of times training passes over language ℓ is the number of samples drawn from it over the number of clips it has, steps × batch × pℓ / nℓ. On the proxy at T = 2, 46,000 steps is three epochs, and the slower run’s development accuracy had started to level off there, with its learning rate decaying towards zero. Counted per language it is 9.2 passes over Sindhi, the language with the fewest clips, and 1.5 over English. We read the plateau as the small languages being repeated rather than the model converging; it stays a reading, and the 65,000-step runs were all still improving at their last evaluation. On the full pool the same 46,000 steps would not finish one pass over Sindhi. A step count cannot be carried across scales. A count of passes can.

We set the full run at about two passes over the pool, 425,000 steps of 144 utterances, so that the large languages are seen more than once, and used the count of passes to check the small ones: under the sampler as run, the five lowest-resource languages are seen four to six times each and the high-resource languages 1.3 to 2.2 times (Figure 26). With the tail replayed that often, label smoothing of 0.1 (Szegedy et al., 2016) guards against memorising it.

Fig. 26 The budget, counted in passes the released recipe, as run · T = 1.75 · floors for English and Hindi · the ramp of Stage IV · 425,000 steps of 144 clips

Passes over a language, by its hours

0 1 2 3 4 5 6 300 1k 3k 10k as the data comes
Passes over a language, by its hours
position14 Indo-Aryan languages, ramped7 other languagesEnglish, floor 16%Hindi, floor 11%
Kashmiri, 369 h4.3 passes
Santali, 394 h5.5 passes
Bodo, 590 h4.5 passes
Assamese, 987 h2.8 passes
Malayalam, 1,544 h3.0 passes
Telugu, 3,184 h2.1 passes
Tamil, 3,560 h2.1 passes
English, 13,039 h1.5 passes

One point per language, at its hours of training audio on a logarithmic axis. A pass is one draw of every clip of that language, on average, summed over the 17 sub-epochs as the run drew them: the first from the plain mix, the rest with the ramp.

The numbers
The final recipe: each language's hours, sampling share and effective passes
LanguageHoursShare as the data comesShare, first sub-epoch (plain mix)Share, last sub-epochPasses
Kashmiri3690.6%1.6%1.6%4.3
Konkani3750.6%1.5%1.5%4.4
Sindhi3900.6%1.5%1.5%4.5
Santali3940.7%1.6%1.6%5.5
Dogri4780.7%1.6%1.6%4.2
Manipuri5390.9%1.9%1.9%5.0
Bodo5901.1%2.1%2.1%4.5
Urdu6911.2%2.3%2.3%3.3
Sanskrit8281.4%2.4%2.4%3.1
Assamese9871.8%2.8%2.8%2.8
Nepali1,1502.5%3.4%3.4%2.4
Punjabi1,3392.2%3.2%3.2%2.5
Gujarati1,5002.7%3.6%3.6%2.3
Malayalam1,5442.7%3.6%3.6%3.0
Odia1,8273.5%4.1%4.1%2.1
Maithili2,1434.0%4.5%4.5%2.0
Telugu3,1846.5%5.9%5.9%2.1
Kannada3,2875.8%5.5%5.5%2.2
Bengali3,5177.2%6.3%6.3%1.5
Tamil3,5606.6%6.0%6.0%2.1
Marathi4,7929.8%7.5%7.5%1.3
Hindi8,12116.1%11.0%11.0%1.3
English13,03920.9%16.0%16.0%1.5

The temperature gives the small languages more than their share and the floors keep English at 16% and Hindi at 11% of the samples; this is what that does to the budget. Sampled as the data comes, 425,000 steps would show every clip about twice. As run, the five smallest languages are seen 4.2 to 5.5 times and the eight largest 1.3 to 2.2 times. Computed from the released run’s saved configuration as the paper’s claim check computes it, with the first sub-epoch drawn from the plain mix.

Floors protect the two largest classes. Stage II showed that flattening the mix takes most from the largest languages. As the data comes, English and Hindi are 21% and 16% of the clips; temperature sampling alone would give them 12.3% and 10.6% of the draws. Under focal loss, which discounts easy examples, that leaves the head too little exposure, and the Hindi floor also guards the boundary between Hindi and Urdu. So the sampler never lets English fall below 16% of the samples or Hindi below 11%, whatever the temperature and Stage IV’s ramp do to the rest. No proxy run tested these values: they were set by reasoning from the sampler, here, and first trained in the released run.

Calibration is one number. A model trained with focal loss is slightly under-confident. A single temperature fitted on the 3,450-clip development set (Guo et al., 2017) repairs that: on the proxy model it cut held-out calibration error from 0.050 to 0.014, at a temperature of 0.71. The released model’s own is 0.674.

What Stage V settled. AdamW at a peak rate of 3 × 10−4 with a 5% warm-up and cosine decay; T = 1.75, with floors of 16% for English and 11% for Hindi; and a budget counted in passes, 425,000 steps of 144 utterances.

Stage VIFull scale: one run, then an average of its checkpoints

54,643 h pool · 30.59 million clips of up to 16 s · 23 languages · 425,000 steps of 144 · six RTX A6000 GPUs, about 70 hours · one run

Stage VI put the decisions of the first five stages into one configuration and trained it once on the pool, on the 30.59 million of its 31.24 million clips that are 16 seconds long or shorter: attentive statistics pooling over a learned mix of all 17 layers, focal loss with label smoothing, sampling at T = 1.75 with the floors of Stage V and the confusability ramp of Stage IV, the full augmentation stack with babble, AdamW at 3 × 10−4 with cosine decay, in bf16 mixed precision. Three things were new in training: the floors under English and Hindi, set in Stage V and trained here for the first time; an exponential moving average of the weights kept beside the live ones (decay 0.9999); and a checkpoint every 25,000 steps, 17 in all, so that the choice of what to release could be made afterwards and on evidence. An earlier full-scale run without the first two is the subject of the layer analysis below.

Fig. 27 The full-scale run stage V · the 54,643 h pool, 30.59 million clips of up to 16 s · 425,000 steps of 144 · six RTX A6000 GPUs, about 70 hours · validated every 25,000 steps

Training loss (log scale)

0.2 0.5 1 2 4 0 100k 200k 300k 400k
Training loss (log scale)
stepTraining loss
1,6492.713
60,4740.519
122,5990.453
181,4490.400
243,5490.373
302,3990.350
364,5240.338
423,3740.324

Learning rate

0 1e-4 2e-4 3e-4 0 100k 200k 300k 400k
Learning rate
stepLearning rate ×10⁴
1,6490.23
60,4742.93
122,5992.56
181,4491.98
243,5491.27
302,3990.64
364,5240.17
423,3740.01

Development accuracy and recall

0.50 0.60 0.70 0.80 0.90 1.00 0 100k 200k 300k 400k
Development accuracy and recall
stepAccuracy, all 23 languagesRecall, EnglishRecall, HindiRecall, Urdu
25,0000.8950.5210.6260.966
75,0000.9150.7930.9200.670
150,0000.9330.6660.8670.897
200,0000.9400.8670.8740.885
250,0000.9330.7070.9330.861
300,0000.9290.5470.9470.897
375,0000.9410.8390.8870.893
425,0000.9510.8600.9330.911

Faint: one logged batch. Solid: its running mean. The learning rate is as logged. The legend’s keys belong to the third panel: accuracy on the 3,450-clip development set, and recall on its 150 clips of each of three languages. The loss axis is logarithmic; the third panel starts at 0.5.

The numbers
Stage VI: development accuracy and three per-language recalls at each of the 17 checkpoints
StepDevelopment accuracyRecall, EnglishRecall, HindiRecall, Urdu
25,0000.89480.5210.6260.966
50,0000.91610.6800.8200.863
75,0000.91520.7930.9200.670
100,0000.92680.7400.8790.923
125,0000.92730.7400.8340.835
150,0000.93290.6660.8670.897
175,0000.93560.7740.8730.871
200,0000.93980.8670.8740.885
225,0000.94150.8400.8400.928
250,0000.93330.7070.9330.861
275,0000.94550.9130.8930.926
300,0000.92860.5470.9470.897
325,0000.92600.7930.9800.816
350,0000.93500.7600.9600.840
375,0000.94140.8390.8870.893
400,0000.94240.7790.9400.887
425,0000.95100.8600.9330.911

A calm run with a restless inside. The loss falls from 2.7 to 0.32 without incident under a 5% warm-up and cosine decay, and development accuracy rises from 0.895 to 0.951, best at the last checkpoint. Underneath, single languages swing: English recall is 0.91 at one checkpoint and 0.55 at the next, on 150 clips from one English corpus. Training log (Weights & Biases).

A calm run. The loss falls from 2.7 to 0.32 with no spike and no restart (Figure 27). Training accuracy ends at 0.88, low by design: half the clips are cropped and most are perturbed. Accuracy on the development set rises from 0.895 at the first checkpoint to 0.951 at the last, and the best checkpoint is the final one, so on the development set nothing was over-trained.

A restless inside. Per language the same run is far less settled. English recall on the development set is 0.52 at the first checkpoint, 0.91 at the eleventh, 0.55 at the twelfth and 0.86 at the last. Each language has 150 development clips, and the English ones all come from one corpus, so the development set exaggerates the swing: on the clean benchmark’s English the same two neighbouring checkpoints both score 0.89. But the benchmark sees it too, in smaller steps, up to 11 points between neighbours across a range of 0.82 to 0.95. A model taken from any single step inherits what that step happened to favour.

Fig. 28 Early checkpoints and late ones are good at different things stage V · 17 checkpoints, 25,000 steps apart, each scored on all 102 conditions · then ten of the 31 candidates

SUITE-102 macro-F1

0.78 0.80 0.82 0.84 0 100k 200k 300k 400k released average
SUITE-102 macro-F1
stepCheckpointIts EMA weights
25,0000.7824
75,0000.8087
150,0000.8169
200,0000.8276
250,0000.8335
300,0000.8326
375,0000.83950.8431
425,0000.84320.8441

Telephony, 7 conditions

0.88 0.90 0.92 0.94 0 100k 200k 300k 400k released average
Telephony, 7 conditions
stepCheckpoint
25,0000.922
75,0000.918
150,0000.922
200,0000.920
250,0000.913
300,0000.908
375,0000.898
425,0000.898

Crops of 1 s, 6 conditions

0.68 0.72 0.76 0.80 0 100k 200k 300k 400k released average
Crops of 1 s, 6 conditions
stepCheckpoint
25,0000.687
75,0000.701
150,0000.732
200,0000.752
250,0000.763
300,0000.775
375,0000.790
425,0000.798
SUITE-102 macro-F1 of the eight averages and the two final checkpoints SUITE-102 macro-F1 of ten candidates. The released average of seven checkpoints across the run is highest at 0.8453. The three other averages that include an early checkpoint follow at 0.8448 and 0.8447. The final EMA weights score 0.8441 and the final checkpoint 0.8432. Averages of late checkpoints only score 0.8408 to 0.8431. SUITE-102 macro-F1 of ten candidates 0.840 0.842 0.844 0.846 Averages that reach back to an early checkpoint Released: seven across the run0.8453 Five across the run0.8448 One early, four late0.8447 One early, four from the plateau0.8447 No average Final EMA weights0.8441 Final checkpoint0.8432 Averages of late checkpoints only Five best on the development set0.8431 Last seven0.8420 Last five, EMA weights0.8413 Last five0.8408 SUITE-102 macro-F1 of the eight averages and the two final checkpoints: SUITE-102 macro-F1 of ten candidates SUITE-102 macro-F1 of ten candidates. The released average of seven checkpoints across the run is highest at 0.8453. The three other averages that include an early checkpoint follow at 0.8448 and 0.8447. The final EMA weights score 0.8441 and the final checkpoint 0.8432. Averages of late checkpoints only score 0.8408 to 0.8431. SUITE-102 macro-F1 0.840 0.844 Averages with an early checkpoint Released, seven0.8453 Five across0.8448 One early, four late0.8447 One early, plateau0.8447 No average Final EMA weights0.8441 Final checkpoint0.8432 Averages of late checkpoints Five best on dev0.8431 Last seven0.8420 Last five, EMA0.8413 Last five0.8408

Ringed points are the seven checkpoints averaged into the released model; the dashed line is that average’s own score. No axis starts at zero, and the strip’s axis spans 0.6 points.

The numbers
Stage VI: SUITE-102 macro-F1, telephony mean and one-second mean of ten candidates
CandidateCheckpoints averaged (steps)SUITE-102TelephonyCrops of 1 s
Released: seven across the run100k, 175k, 275k, 325k, 350k, 400k, 425k0.84530.9230.791
Five across the run100k, 175k, 325k, 350k, 425k0.84480.9240.791
One early, four late175k, 325k, 350k, 400k, 425k0.84470.9100.795
One early, four from the plateau175k, 275k, 325k, 350k, 425k0.84470.9170.794
Final EMA weights425k0.84410.9000.798
Final checkpoint425k0.84320.8980.798
Five best on the development set225k, 275k, 375k, 400k, 425k0.84310.9060.793
Last seven275k, 300k, 325k, 350k, 375k, 400k, 425k0.84200.9030.796
Last five, EMA weights325k, 350k, 375k, 400k, 425k0.84130.8920.796
Last five325k, 350k, 375k, 400k, 425k0.84080.8910.796

One run, several models. Across the 17 checkpoints SUITE-102 macro-F1 climbs from 0.782 to 0.843, but the families do not climb together: telephony is best at 175,000 steps and worst at 325,000, while one-second crops improve to the end. An average that spans the run keeps both, 0.923 on telephony and 0.791 at one second, and ranks first of the 31 candidates at 0.8453. Averages of late checkpoints alone rank below the final checkpoint. Anuvani-LID paper, Figure 8, with two families added from the same scorecards.

The benchmark sees the same thing by family. We scored all 17 checkpoints on the 102 conditions. SUITE-102 macro-F1 climbs from 0.782 at 25,000 steps to 0.843 at the end, and to 0.844 for the final EMA weights (Figure 28). The families do not climb together. Telephony is at its best at 175,000 steps (0.932), falls to 0.877 by 325,000 and recovers to 0.898. One-second crops improve almost without pause, from 0.69 to 0.80. Early checkpoints hold the channel robustness; late ones hold the short clips.

Averaging keeps both. Averaging the weights of checkpoints from one run (Izmailov et al., 2018) gives one model, which costs nothing extra at inference, the property model soups exploit (Wortsman et al., 2022). From the 17 checkpoints we first built 11 more candidates, the EMA weights at six checkpoints and five averages, and scored all 28 on SUITE-102. Three more averages were then designed around the best of them, their members fixed from the per-family profiles before any of the three was scored, and the released model is one of those three. Which checkpoints go in matters more than how many. Averages of late checkpoints only, the obvious choice, score 0.841 to 0.843 and do not beat the final checkpoint. Averages that reach back to an early checkpoint do. The best of the 31 candidates is the average of seven checkpoints spread across the run, at 100, 175, 275, 325, 350, 400 and 425 thousand steps. It scores 0.8453, with nearly the telephony of the early checkpoints (0.923) and nearly the short-clip accuracy of the late ones (0.791). It is the released Anuvani-LID.

What the average did and did not buy. On the suite as a whole, very little: the top four candidates lie within 0.06 points of each other, and the released average is 0.1 points above the final EMA weights it could have been replaced by. What it bought is evenness. English recall on the clean benchmark is 0.87 for the final checkpoint and 0.92 for the average, and telephony rises from 0.898 to 0.923. We used SUITE-102 to design the last three averages as well as to choose among all 31, which a careful reader should hold against the suite score. The check we report is the candidate that involved no choice: the final EMA weights score 0.912 on the core conditions of the comparison panel and 0.889 on its all-23 panel, against 0.914 and 0.897 for the released average, and no ranking against another system changes. The released recipe was trained once; we did not repeat it with another seed.

Fig. 29 One temperature repairs full-length speech and overcorrects short clips the released model · temperature 0.674, fitted on the 3,450-clip development set · accuracy against confidence in 15 bins

All-23 test, 6,900 clips

0.2 0.4 0.6 0.8 1.0 0.2 0.4 0.6 0.8 1.0
All-23 test, 6,900 clips
confidenceConfidence equals accuracyAs trainedWith one temperature, 0.674
0.150.15
0.30390.256
0.43330.638
0.56630.523
0.63570.605
0.76960.735
0.90350.967
11.00

Clean benchmark, 6,000 clips

0.2 0.4 0.6 0.8 1.0 0.2 0.4 0.6 0.8 1.0
Clean benchmark, 6,000 clips
confidenceConfidence equals accuracyAs trainedWith one temperature, 0.674
0.150.15
0.37160.772
0.50250.639
0.63230.835
0.70180.846
0.83450.986
0.90360.986
11.00
Expected calibration error before and after temperature scaling, on five sets Expected calibration error of the released model on five sets, as trained and after scaling by one temperature. Development set (fitted here): 0.061 to 0.006. All-23 test, unseen speakers: 0.054 to 0.008. Clean benchmark: 0.089 to 0.025. Cross-corpus, IndicVoices: 0.024 to 0.027. FLEURS crops of 1 s: 0.041 to 0.110. Expected calibration error, 15 bins 0.00 0.02 0.04 0.06 0.08 0.10 0.12 Development set (fitted here)As trained: 0.061With one temperature: 0.0060.061 → 0.006 All-23 test, unseen speakersAs trained: 0.054With one temperature: 0.0080.054 → 0.008 Clean benchmarkAs trained: 0.089With one temperature: 0.0250.089 → 0.025 Cross-corpus, IndicVoicesAs trained: 0.024With one temperature: 0.0270.024 → 0.027 FLEURS crops of 1 sAs trained: 0.041With one temperature: 0.1100.041 → 0.110 Expected calibration error before and after temperature scaling, on five sets: Expected calibration error, 15 bins Expected calibration error of the released model on five sets, as trained and after scaling by one temperature. Development set (fitted here): 0.061 to 0.006. All-23 test, unseen speakers: 0.054 to 0.008. Clean benchmark: 0.089 to 0.025. Cross-corpus, IndicVoices: 0.024 to 0.027. FLEURS crops of 1 s: 0.041 to 0.110. Calibration error (ECE) 0.00 0.06 0.12 DevelopmentAs trained: 0.061With one temperature: 0.0060.061 → 0.006 All-23 testAs trained: 0.054With one temperature: 0.0080.054 → 0.008 Clean benchmarkAs trained: 0.089With one temperature: 0.0250.089 → 0.025 Cross-corpusAs trained: 0.024With one temperature: 0.0270.024 → 0.027 FLEURS, 1 sAs trained: 0.041With one temperature: 0.1100.041 → 0.110

Each point is one bin of clips: its mean confidence across, its accuracy up. A point above the dashed line is a model less confident than it is right. Bins holding under 0.5% of the clips are not drawn, and both axes start at 0.15.

The numbers
Expected calibration error of the released model on five sets, before and after temperature scaling
SetClipsECE as trainedECE with one temperature
Development set (fitted here)3,4500.06140.0060
All-23 test, unseen speakers6,9000.05380.0078
Clean benchmark6,0000.08920.0249
Cross-corpus, IndicVoices2,9750.02400.0267
FLEURS crops of 1 s1,5000.04100.1097

As trained, the model is right more often than it says: its points lie above the line. Dividing the logits by one temperature, 0.674, fitted on the development set, brings calibration error on the unseen-speaker all-23 test from 0.054 to 0.008 and on the clean benchmark from 0.089 to 0.025. It does not help everywhere: on the cross-corpus slice the error was already 0.024 and is 0.027 afterwards, and on clips of a second or less it makes things worse, from 0.041 to 0.110 on FLEURS crops of one second. Anuvani-LID paper, Figure 11; the short-clip row from its comparison panel.

The last step is one number. Focal loss leaves the model slightly under-confident, as Stage V found on the proxy. A single temperature, 0.674, fitted on the 3,450-clip development set, lowers expected calibration error on the held-out all-23 test from 0.054 to 0.008 and on the clean benchmark from 0.089 to 0.025 (Figure 29). On the cross-corpus slice, where the error was already 0.024, it does not help: the error is 0.027 afterwards. On short clips it hurts. Of the 42 conditions of the comparison panel it makes 9 worse, every one at a second or less among them: on FLEURS the error goes from 0.041 to 0.110 at one second and from 0.084 to 0.208 at half a second. On clips that short the model was not under-confident to begin with. Over the whole panel the mean error still falls, from 0.080 to 0.044. We report the temperature with the model.

What Stage VI settled. The released model is the uniform average of seven checkpoints of one 425,000-step run, with one calibration temperature. Everything else in it was decided earlier, on a fourteenth of the data.

Inside the model: where language identity is encoded

The six stages chose the model from the outside, by what it scored. This section opens it. We asked four questions. Where along the 17 blocks does language become readable? What does the head read when it is free to choose? Which blocks does the decision need? And does it lean on the recording channel, the shortcut behind earlier cross-corpus failures (Dey, Saha & Sahidullah, 2021)?

The subjects are three models built on one pre-trained encoder: the encoder itself, with no fine-tuning; the selected Stage I arm, fine-tuned on 1,000 hours with its head on the last block; and a model fine-tuned on all 54.6 thousand hours. That last one is the finished model of the first full-scale run, made with an earlier version of the final recipe: the same head, loss, temperature and learning rate, without the floors under English and Hindi, the moving average of the weights, or crops shorter than half a second. It is not the released average. Two more 1,000-hour models join for single questions: the Stage I arm that reads a learned mix of all 17 layers, with a margin loss, and the depth runs. Blocks are numbered from 1 at the bottom to 17 at the top.

Fig. 30 Language is built in the middle of the stack, and fine-tuning rewrites the top layer analysis · linear probes on pooled block outputs · tested on speakers the probe did not train on: 1,217 clips for the full-scale model, 953 for the others · blocks 1 (bottom) to 17 (top)

Language probe, macro-F1

0.0 0.3 0.6 0.9 1 5 9 13 17
Language probe, macro-F1
blockFine-tuned, 54.6k hFine-tuned, 1,000 hPre-trained only
10.1540.1470.146
30.2320.2240.231
70.7200.5390.527
90.8430.6710.564
110.8600.6880.563
120.8620.6710.549
150.8110.5710.237
170.6490.5310.126

Probe gain from fine-tuning

0.0 0.2 0.4 0.6 1 5 9 13 17
Probe gain from fine-tuning
blockFine-tuned, 54.6k hFine-tuned, 1,000 h
10.0080.001
30.001-0.008
70.1930.012
90.2790.107
110.2960.125
120.3140.122
150.5750.334
170.5240.405

Similarity to block 1 (CKA)

0.00 0.25 0.50 0.75 1.00 1 5 9 13 17
Similarity to block 1 (CKA)
blockFine-tuned, 54.6k hFine-tuned, 1,000 hPre-trained only
11.0001.0001.000
30.8440.9030.901
60.6420.7570.797
80.5190.6980.735
100.2610.4840.695
120.2030.4660.781
150.1590.5080.841
170.0310.4560.801

The probe is drawn at the ten blocks of the paper’s grid; similarity at all 17. The gain is each fine-tuned model’s probe score less the pre-trained encoder’s at the same block; for the full-scale model the two scores come from different test sets, 1,217 and 953 clips.

The numbers
Layer analysis: linear-probe macro-F1 by block for three checkpoints
BlockPre-trainedFine-tuned, 1,000 hFine-tuned, 54.6k hSimilarity to block 1, 54.6k h
10.1460.1470.1541.000
30.2310.2240.2320.844
50.4590.3990.4240.703
70.5270.5390.7200.588
90.5640.6710.8430.381
110.5630.6880.8600.253
120.5490.6710.8620.203
130.5000.6660.8450.188
150.2370.5710.8110.159
170.1260.5310.6490.031

Three checkpoints of one encoder. Before fine-tuning, language is most readable in blocks 9 to 11 (about 0.56) and almost unreadable at block 17 (0.13). Fine-tuning moves the peak to block 11 (0.69) on 1,000 h and block 12 (0.86) on 54.6k h. It changes nothing at the bottom and almost everything at the top: the gain is 0.00 at block 1 and +0.41 at block 17. After 54.6k h the top block shares almost nothing linearly with the first (0.03, against 0.80 before fine-tuning). Anuvani-LID paper, Figure 13, with the gain and the similarity added from the analysis files.

Language lives in the middle and upper stack. A linear probe (Belinkov, 2022) is the simplest instrument: freeze the model, pool each block’s frames into one vector per clip, and train a linear classifier on those vectors to name the language, testing on speakers it has not seen. In the pre-trained encoder the probe peaks at about 0.56 in blocks 9 to 11 and collapses to 0.13 at block 17, whose representations serve the pre-training objective and not the listener (Pasad et al., 2021). Fine-tuning moves the peak to block 11 (0.69) on 1,000 hours and to block 12 (0.86) on 54.6 thousand, higher in the stack than the lower-layer optimum reported for another self-supervised Conformer (Bartley et al., 2023).

Fine-tuning rewrites the top, not the bottom. All three models read 0.15 at block 1 and are within a point and a half of each other up to block 3. The gain over the pre-trained encoder then grows with depth: on 1,000 hours it is 0.00 at block 1, +0.11 at block 9 and +0.41 at block 17 (Figure 30, second panel). A measure of representational similarity, linear CKA (Kornblith et al., 2019), shows the same thing from another side. Before fine-tuning the top block still resembles the first (0.80). After 1,000 hours the figure is 0.46, and after 54.6 thousand it is 0.03: the top of the full-scale model shares almost nothing linearly with its bottom. By this measure fine-tuning leaves the lower blocks where pre-training put them, and turns the upper blocks into a language identifier.

Fig. 31 What the head reads, and what a last-block head needs layer analysis · learned weights of the layer mix · one block at a time replaced by the identity, scored on 784 clips (664 for the 1,000 h models)

Share of the head's layer mix

0% 10% 20% 30% 1 5 9 13 17
Share of the head's layer mix
blockLayer mix, 54.6k hLayer mix, 1,000 h, margin loss
10.0060.052
30.0120.053
60.0400.057
80.0310.059
100.0630.061
120.0650.062
150.0480.064
170.2990.066

Macro-F1 lost when a block is skipped

0.0 0.2 0.4 0.6 1 5 9 13 17
Macro-F1 lost when a block is skipped
blockLayer mix, 54.6k hLayer mix, 1,000 h, margin lossLast block only, 1,000 h, focal
10.0550.0540.089
30.0140.0200.033
60.0160.0870.151
80.0080.1180.160
10-0.0120.1160.266
120.0060.0060.041
150.0060.0040.095
170.0000.0000.672

The weights of one model sum to 100%. For the two layer-mix models the knockout is partial: their heads still receive the skipped block’s own output, so their curves show only what the blocks above it lose, and their zero at block 17 is by construction. The second panel’s axis runs below zero because skipping a block sometimes helps by a hair.

The numbers
Layer analysis: learned layer weights and single-block knockout by block
BlockWeight, 1,000 hWeight, 54.6k hLost: last block only, 1,000 hLost: layer mix, 1,000 hLost: layer mix, 54.6k h
15.2%0.6%0.0890.0540.055
25.1%0.7%0.0180.0180.020
35.3%1.2%0.0330.0200.014
45.3%1.7%0.0410.0210.010
55.6%4.4%0.0580.0190.000
65.7%4.0%0.1510.0870.016
75.7%2.1%0.3400.2790.079
85.9%3.1%0.1600.1180.008
95.9%3.3%0.1770.045-0.012
106.1%6.3%0.2660.116-0.012
116.2%7.3%0.1050.037-0.008
126.2%6.5%0.0410.0060.006
136.2%7.0%0.0600.0040.007
146.2%7.6%0.1160.0020.007
156.4%4.8%0.0950.0040.006
166.5%9.5%0.1700.0000.002
176.6%29.9%0.6720.0000.000

With more data and a longer run, the head learns where to look. On 1,000 h the learned mix stays nearly uniform, 5.1% to 6.6% a block; on 54.6k h it puts 30% on block 17 and most of the rest on blocks 10 to 16. A head that reads only the last block loses everything when that block is skipped, and half of its score without block 7. For the layer-mix models the test is partial: skipping a block removes only its effect on the blocks above, which costs the full-scale model at most 0.08. Anuvani-LID paper, Figure 13 (the 54.6k h weights) and its text; the 1,000 h weights from the analysis files.

With more data, the head learns where to look. The layer mix of Stage II gives the head one weight per block (Yang et al., 2021). On 1,000 hours those weights hardly move from uniform: between 5.1% and 6.6% a block, an effective 16.95 layers of 17. On 54.6 thousand hours they concentrate. Block 17 receives 30% of the weight and blocks 10 to 16 most of the rest, an effective 11.1 layers (Figure 31). The head’s choice and the probe’s do not coincide exactly: the probe is best at block 12, and the head leans hardest on block 17, where the probe has already fallen to 0.65. A linear probe on a frozen block and a head trained jointly with the stack are different readers, and we report the disagreement without smoothing it. The two models also differ in more than data: the 1,000-hour one has a margin loss and trained for 14,028 steps, the full-scale one focal loss for 425,000, at three times the learning rate.

Knockout reads a last-block head cleanly, and a mixing head only in part. Knockout asks what the decision needs: replace one block by the identity and measure the macro-F1 lost. For a head that reads only the last block the test is clean, since everything it sees has passed through every block. The selected Stage I arm, a focal head on block 17 trained on 1,000 hours, loses its whole score, 0.67, when block 17 is skipped, and has two bottlenecks lower down: skipping block 7 costs 0.34 and block 10 costs 0.27. For a head that reads a mix the test is partial. The model records each block’s output for the mix before the knockout replaces it, so the head still receives the skipped block’s real output, and the curve shows only what the blocks above it lose; the zero at block 17 is by construction. With that caveat, the 1,000-hour mixing arm, which also differs in its loss, loses 0.28 without block 7, and the full-scale model at most 0.08. Whether a mixing head can route around a missing block was not tested.

Fig. 32 Twelve blocks do the work of seventeen layer analysis · the bottom k blocks retrained · Stage I reference recipe · 1,000 h · two seeds at 12, 15 and 17 blocks

Cross-corpus macro-F1

0.6 0.7 0.8 0.9 3 6 9 12 15 17 65M 84M 116M
Cross-corpus macro-F1
blocks kept:Benchmark, 2 epochs
30.631
60.800
90.842
120.848
150.842
170.840

Cross-corpus, nine blocks and up

0.82 0.83 0.84 0.85 0.86 9 12 15 17
Cross-corpus, nine blocks and up
blocks kept:Benchmark, 2 epochsBenchmark, 4 epochs
90.842
120.8480.844
150.842
170.8400.835

Validation accuracy in training

0.90 0.92 0.94 0.96 0.98 1.00 3 6 9 12 15 17
Validation accuracy in training
blocks kept:Validation, clean
30.952
60.979
90.968
120.977
150.972
170.983

Ringed points carry the parameter count. A vertical bar is the half-spread of two seeds. The first panel starts at 0.6; the second enlarges its right-hand end, from 0.82 to 0.86; the third starts at 0.9. The 4-epoch point at 17 blocks is the Stage I reference arm, a single run, scored again.

The numbers
Layer analysis: benchmark macro-F1 by number of encoder blocks kept, 1,000 h, 2 epochs
Blocks keptParametersCross-corpusCleanNoisy and degradedCrops of 1 sValidation, clean
327.1M0.6310.7930.4460.4250.952
646.1M0.8000.8870.6380.6470.979
965M0.8420.8990.6830.6600.968
1284M0.848 ± 0.25 points0.9060.6890.6840.977
15103M0.842 ± 0.33 points0.9040.6860.6800.972
17115.6M0.840 ± 0.35 points0.8920.6700.6340.983

Accuracy stops rising at twelve blocks. Cross-corpus macro-F1 is 0.848 with 12 blocks and 84 million parameters against 0.840 with all 17 and 116 million: both 12-block seeds beat both 17-block seeds, by a gap the size of the spread between seeds and far inside the three-point noise of training. At four epochs, 0.844 (two seeds) against 0.835 (the single Stage I reference run). Nine blocks match all 17 with 65 million. The validation set of the same runs cannot see any of this: three blocks reach 0.952 clean validation accuracy and 0.631 on the benchmark. Anuvani-LID paper, Figure 13; validation from the training logs (Weights & Biases).

Twelve blocks suffice. Probes and knockouts are readings of a fixed model. The direct test is to retrain. We kept the bottom k blocks of the pre-trained encoder, for k from 3 to 17, and fine-tuned each under the Stage I reference recipe on 1,000 hours, with a second seed at 12, 15 and 17 blocks. Cross-corpus macro-F1 rises from 0.631 at three blocks to 0.842 at nine and stops rising at twelve: 0.848 with 84 million parameters against 0.840 with all 17 blocks and 116 million (Figure 32). Both 12-block seeds beat both 17-block seeds, but by 0.8 points, about the spread between two seeds of one depth (0.5 and 0.7 points) and far inside the three-point noise of training. At four epochs the 12-block runs score 0.844 (two seeds) against 0.835 for the single Stage I reference run. Nine blocks match all 17 (0.842 against 0.840) with 44% fewer parameters, 0.6 points behind twelve. What the experiment shows is that the top five blocks add nothing this task can use at this scale, which is what the probe had said.

Two cautions. The truncated models used the Stage I reference head on 1,000 hours, not the released recipe on the full pool, so this is a result about depth and not yet a smaller release. And the runs’ own validation accuracy, 0.95 to 0.98 at every depth, would never have found it: a three-block encoder reaches 0.952 on clean validation and 0.631 on the benchmark.

Fig. 33 The corpus is readable in every block, and erasing it leaves the language score where it was layer analysis · probes for corpus and for language on the same blocks · then three corpus directions, found on block 17, projected out of what the head reads

Fine-tuned on 54.6k h

0.00 0.25 0.50 0.75 1.00 1 5 9 13 17 guessing the largest corpus
Fine-tuned on 54.6k h
blockWhich corpus? (probe accuracy)Which language? (probe macro-F1)
10.8420.154
30.9280.232
60.925
80.925
100.953
120.9610.862
150.9670.811
170.8860.649

Fine-tuned on 1,000 h

0.00 0.25 0.50 0.75 1.00 1 5 9 13 17 guessing the largest corpus
Fine-tuned on 1,000 h
blockWhich corpus? (probe accuracy)Which language? (probe macro-F1)
10.8280.147
30.8540.224
60.839
80.848
100.842
120.8040.671
150.8680.571
170.8890.531
Language macro-F1 and corpus-probe accuracy before and after erasing the corpus directions Four measurements before and after the three directions that separate four corpora are erased at the head’s input. Language macro-F1, 54.6k h: 0.937 to 0.939. Language macro-F1, 1,000 h: 0.830 to 0.831. Corpus probe accuracy, 54.6k h: 0.897 to 0.383. Corpus probe accuracy, 1,000 h: 0.857 to 0.076. Before and after the corpus directions are erased 0.00 0.25 0.50 0.75 1.00 Language macro-F1, 54.6k hBefore: 0.937After erasure: 0.939+0.1 points Language macro-F1, 1,000 hBefore: 0.830After erasure: 0.8310.0 points Corpus probe accuracy, 54.6k hBefore: 0.897After erasure: 0.383−51.4 points Corpus probe accuracy, 1,000 hBefore: 0.857After erasure: 0.076−78.1 points Language macro-F1 and corpus-probe accuracy before and after erasing the corpus directions: Before and after the corpus directions are erased Four measurements before and after the three directions that separate four corpora are erased at the head’s input. Language macro-F1, 54.6k h: 0.937 to 0.939. Language macro-F1, 1,000 h: 0.830 to 0.831. Corpus probe accuracy, 54.6k h: 0.897 to 0.383. Corpus probe accuracy, 1,000 h: 0.857 to 0.076. Before and after erasure 0.00 0.50 1.00 Language, 54.6k hBefore: 0.937After erasure: 0.939+0.1 points Language, 1,000 hBefore: 0.830After erasure: 0.8310.0 points Corpus, 54.6k hBefore: 0.897After erasure: 0.383−51.4 points Corpus, 1,000 hBefore: 0.857After erasure: 0.076−78.1 points

The corpus probe tells four corpora apart, so guessing the largest scores about 0.25; the corpora do not share all their languages, so part of its score can come from language. Erasure finds the three directions along which the corpus means differ, on block 17, and projects them out of what the head reads; then the four cross-corpus conditions and the probe, on block 17, are run again. In the first two rows the two points coincide.

The numbers
Layer analysis: language macro-F1 and corpus-probe accuracy before and after erasing the corpus subspace
MeasurementBeforeAfter erasureChange, points
Language macro-F1, 54.6k h0.93740.9385+0.1
Language macro-F1, 1,000 h0.83030.83060.0
Corpus probe accuracy, 54.6k h0.89720.3833−51.4
Corpus probe accuracy, 1,000 h0.85670.0760−78.1

Which corpus a clip came from can be read off every block, at 0.84 or better in the full-scale model. On the 1,000 h model, whose head reads block 17, projecting out the three directions along which the corpus means differ leaves language macro-F1 at 0.830 to 0.831 while the corpus probe falls from 0.86 to 0.08. At full scale the same kind of directions, found on block 17, were removed from the layer mix: macro-F1 moved from 0.937 to 0.939, but the check that the corpus was gone, 0.90 to 0.38, was made on block 17, not on the mix. Anuvani-LID paper, section 8; the analysis files.

The corpus is visible; on the cleanest test, it is not used. A language identifier can cheat. If Bengali mostly comes from one corpus and Odia from another, the microphone is as good a clue as the phonology, and the cheat fails on the first new corpus. The information is present: a probe for which of four corpora a clip belongs to scores between 0.84 and 0.97 at every block of the full-scale model, against 0.25 for guessing (Figure 33). Part of that can come from language, since the four corpora do not share all their languages: 148 of the 300 IndicVoices clips are in languages no other corpus in the probe has. So we removed it, with a simplified form of LEACE (Belrose et al., 2023): the three directions along which the corpus means differ, found on block 17, projected out of what the head reads. On the 1,000-hour model, whose head reads block 17, the test is clean: macro-F1 on the four cross-corpus conditions stays at 0.830 to 0.831, and the corpus probe on the erased vectors falls from 0.86 to 0.08. At full scale macro-F1 moved by +0.1 points, 0.937 to 0.939, but there the directions were removed from the mix, in which block 17 has 30% of the weight, and the check that the corpus was gone, 0.90 to 0.38, was made on block 17. That bounds the claim: on the model where the test is clean, the decision does not rest on the corpus cues we could find and remove.

What the inside says about the outside. Each finding meets a choice made earlier by score alone. Language is most readable between blocks 9 and 12, so a head that reads only block 17 reads past the peak; the layer mix of Stage II lets the head choose. Fine-tuning does its work in the upper half of the stack, which is consistent with a frozen encoder failing in Stage I (0.362), while every arm that let the top of the stack change came within 3.4 points of the best fine-tuned arm. The corpus is visible, and on the model where the test is clean it is unused, which is the behaviour the held-out benchmark was built to demand. And twelve blocks would do, which is where a smaller model begins.

Results

  • Overall. Anuvani-LID reaches 0.914 mean macro-F1 on the core conditions: 5.2 points above Gemini 3.5 Flash (95% CI 4.8–5.5) and 6.8 above Sarvam Saaras v3. Restricted to the same ten candidates the APIs were given, it reaches 0.923. It is significantly better than Gemini on 21 of 37 conditions and better than every open model on at least 28.
  • Short clips. At one second it reaches 0.764 macro-F1 on FLEURS and 0.854 on in-domain speech, against 0.520 and 0.611 for Gemini: 24 points in both cases. At half a second it reaches 0.545, against 0.439 for the best competitor and 0.231 for Gemini.
  • Noise. The margin over Gemini grows as the audio gets worse: +7.0 points under babble, +6.0 in 0 dB noise, +4.3 under reverberation, against +1.9 on clean read speech.
  • All 23 languages. Only five other systems can even output all 23 classes. Anuvani-LID averages 0.897 macro-F1 on the all-23 panel, against 0.713 for Voxlect Indic-Whisper, 0.710 for Gemini and 0.384 for GPT-audio. It scores at least 0.84 F1 on every language, including Bodo (0.95), Dogri (0.97), Kashmiri (0.95), Santali (0.93) and Sindhi (0.91), each trained on under 600 hours.
  • Calibration and rejection. Temperature scaling brings expected calibration error on the all-23 test to 0.008; 100 · Cavg is 3.16 and EER 1.79%. Maximum-softmax rejection separates music and eight non-Indian languages from in-set speech with AUROC 0.89–0.91.
  • Efficiency. Language identity peaks in blocks 11–12, and a 12-block version (84M parameters) matches the full model on cross-corpus macro-F1 (0.848 against 0.840). Erasing the recording-channel subspace with LEACE changes the decision by only 0.1 points, so the model is not leaning on channel shortcuts (Belrose et al., 2023).

How it answers each problem in this post

Problem Anuvani-LID's answer Measured effect
A weak, shared LID objective A dedicated focal-loss objective over 23 languages Best macro-F1 and ECE 0.023 among 25 Stage-I arms
Language lives mid-stack Learned aggregation over all 17 blocks +2.8 telephony, +1.9 noise, +1.4 confusable
One-second clips Duration cropping, 0.25–16 s bimodal crops +24 points over Gemini at 1 s
Noisy, narrowband calls MUSAN, room impulses, 8 kHz codec, babble Babble conditions 0.804 → 0.920
Confusable clusters Curriculum over the Indo-Aryan cluster 0.975 vs 0.955 (Gemini) on confusable pairs
35-fold data skew Temperature sampling near T = 2, with floors Lowest-resource tier 0.742 → 0.930 F1
Missing languages All 22 scheduled languages plus English ≥ 0.84 F1 on every class
A closed set Open-set evaluation and calibrated scores AUROC 0.89–0.91
No usable confidence Focal loss plus temperature scaling ECE 0.054 → 0.008
Cost and the edge 115.6M parameters; 12-block variant 84M with no loss

Where we still lose

We report losses next to wins, because a benchmark that only shows wins is an advertisement.

  • Long, read, high-register speech. Gemini 3.5 Flash is significantly ahead on the five full-length FLEURS conditions (by 1.5 to 5.7 points) and on MUCS read speech (1.2). FLEURS is read Wikipedia text, a register a general-purpose audio LLM can exploit. The ranking reverses once the same clips are cut to one second.
  • Hindi varieties. On dialectal Hindi, Hinglish and rural telephony, Sarvam (0.918) and Gemini (0.912) lead us (0.779). On dialectal Hindi we label 19% of utterances Urdu; on Hinglish, 28% Urdu and 23% English. Urdu shares Hindi’s spoken grammar and English supplies the embedded words, so these are defensible confusions, and the probes reward any prior toward Hindi. But the deeper lesson is ours to learn: for code-mixed speech, one label per utterance is the wrong tool, and frame-level language diarization is the right one.
  • Indian English. On the Svarah corpus of accented English, 40% of utterances are attributed to a scheduled language.
  • The sub-second floor. At 0.25 seconds we reach only 0.24–0.35 macro-F1 in seven of eight conditions. No open model exceeds 0.18 there, but the information simply is not in the signal yet.
  • The open set. Rejecting Chhattisgarhi, a close relative of Hindi, is harder (AUROC 0.84) than rejecting unrelated languages. And India’s other languages (Bhili, Gondi, Tulu, Bhojpuri and more) remain outside our label set.

Closing: listen for one thing

Unified speech models are one of the great achievements of the last five years, and nothing in this post argues against them. It argues for something smaller and older: that the first decision in a voice pipeline deserves weights trained for it alone, a confidence you can trust, a label space you choose, a time resolution that matches a conversation, and a life cycle of its own.

India makes that case more forcefully than anywhere else. Twenty-two scheduled languages drawn from four families that have borrowed each other’s sounds for centuries. Labels that are partly administrative. Data that follows wealth rather than speakers. Calls that arrive over 8 kHz lines, a second or two at a time, in two languages at once. A general model can be very good at the average of all that. A voice agent in Patna or Guwahati does not live at the average.

There is plenty left to do. Code-mixed speech needs frame-level language diarization, not one label per utterance. Close relatives of scheduled languages must be rejected, not forced into the nearest class. And India’s languages do not end with the Eighth Schedule. We intend to keep going.

We began with the raga, recognised from its first phrase before the melody unfolds. Before a single word is understood, something has to recognise that first phrase of speech. We think that something should be listening for nothing else.

Acknowledgement

Anuvani-LID was conceived and developed by Stephen Fernandes under the leadership and guidance of Dr. Narayan Kumar Choudhary. We thank Dr. Choudhary and the Central Institute of Indian Languages (CIIL) for their assistance, for the compute they provided and for their continued support.

References

Papers and books

  • Ahn, H., Chae, J., Park, Y., Shim, K. (2026). Whisper-CD: Accurate long-form speech recognition using multi-negative contrastive decoding. arXiv:2603.06193
  • Amodei, D., et al. (2016). Deep Speech 2: End-to-end speech recognition in English and Mandarin. ICML. arXiv:1512.02595
  • Amooie, R., Hao, Y., de Vries, W., Dijkstra, J., Coler, M., Wieling, M. (2026). Improving low-resource ASR using bilingual fine-tuning with language identification: a cross-linguistic evaluation. arXiv:2606.17820
  • Arandjelović, R., Gronat, P., Torii, A., Pajdla, T., Sivic, J. (2016). NetVLAD: CNN architecture for weakly supervised place recognition. CVPR. arXiv:1511.07247
  • Arivazhagan, N., et al. (2019). Massively multilingual neural machine translation in the wild. arXiv:1907.05019
  • Arsenault, P. (2017). Retroflexion in South Asia: Typological, genetic, and areal patterns. Journal of South Asian Languages and Linguistics 4(1).
  • Attia, A. A., et al. (2024). Kid-Whisper. AIES. arXiv:2309.07927
  • Babu, A., et al. (2022). XLS-R: Self-supervised cross-lingual speech representation learning at scale. Interspeech. arXiv:2111.09296
  • Baevski, A., Zhou, Y., Mohamed, A., Auli, M. (2020). wav2vec 2.0. NeurIPS. arXiv:2006.11477
  • Baghel, S., et al. (2023). The DISPLACE challenge 2023. Interspeech. arXiv:2303.00830
  • Bali, K., Sharma, J., Choudhury, M., Vyas, Y. (2014). “I am borrowing ya mixing?” CodeSwitch Workshop. ACL
  • Barras, C., Le, V.-B., Gauvain, J.-L. (2020). Vocapia-LIMSI system for the 2020 shared task on code-switched spoken language identification. WSTCSMC 2020.
  • Barański, M., Jasiński, J., Bartolewska, J., Kacprzak, S., Witkowski, M., Kowalczyk, K. (2025). Investigation of Whisper ASR hallucinations induced by non-speech audio. ICASSP. arXiv:2501.11378
  • Bartley, T., et al. (2023). Accidental learners: Spoken language identification in multilingual self-supervised models. ICASSP. arXiv:2211.05103
  • Belinkov, Y. (2022). Probing classifiers: Promises, shortcomings, and advances. Computational Linguistics 48(1). doi
  • Belrose, N., et al. (2023). LEACE: Perfect linear concept erasure in closed form. NeurIPS. arXiv:2306.03819
  • Bengio, S., Vinyals, O., Jaitly, N., Shazeer, N. (2015). Scheduled sampling for sequence prediction. NeurIPS. arXiv:1506.03099
  • Bengio, Y., Louradour, J., Collobert, R., Weston, J. (2009). Curriculum learning. ICML. doi
  • Bhogale, K. S., et al. (2025). Towards bringing parity in pretraining datasets for low-resource Indian languages. ICASSP. MahaDhwani model card
  • Brown, T., et al. (2020). Language models are few-shot learners. NeurIPS. arXiv:2005.14165
  • Chen, W., et al. (2023). Improving massively multilingual ASR with auxiliary CTC objectives. ICASSP. arXiv:2302.12829
  • Chu, Y., et al. (2023). Qwen-Audio. arXiv:2311.07919
  • Chung, Y.-A., et al. (2021). w2v-BERT. ASRU. arXiv:2108.06209
  • Conneau, A., et al. (2020). Unsupervised cross-lingual representation learning at scale. ACL. arXiv:1911.02116
  • Conneau, A., Baevski, A., Collobert, R., Mohamed, A., Auli, M. (2021). Unsupervised cross-lingual representation learning for speech recognition. Interspeech. arXiv:2006.13979
  • Conneau, A., et al. (2023). FLEURS. SLT. arXiv:2205.12446
  • Coupé, C., Oh, Y. M., Dediu, D., Pellegrino, F. (2019). Different languages, similar encoding efficiency. Science Advances. doi
  • Cui, Y., Jia, M., Lin, T.-Y., Song, Y., Belongie, S. (2019). Class-balanced loss based on effective number of samples. CVPR. arXiv:1901.05555
  • Dehak, N., Torres-Carrasquillo, P. A., Reynolds, D., Dehak, R. (2011). Language recognition via i-vectors and dimensionality reduction. Interspeech. ISCA
  • Del Rio, M., et al. (2022). Earnings-22. Interspeech. arXiv:2203.15591
  • Deng, J., Guo, J., Xue, N., Zafeiriou, S. (2019). ArcFace. CVPR. arXiv:1801.07698
  • Desplanques, B., Thienpondt, J., Demuynck, K. (2020). ECAPA-TDNN. Interspeech. arXiv:2005.07143
  • Dey, S., Saha, G., Sahidullah, M. (2021). Cross-corpora language recognition: A preliminary investigation with Indian languages. EUSIPCO.
  • Dey, S., Sahidullah, M., Saha, G. (2022). An overview of Indian spoken language recognition from a machine learning perspective. ACM TALLIP. arXiv:2212.03812
  • Emeneau, M. B. (1956). India as a linguistic area. Language 32(1).
  • Fernandes, S., Choudhary, N. (2026). Anuvani-LID: Robust and calibrated spoken language identification for Indian languages. Preprint.
  • Frieske, R., Shi, B. E. (2024). Hallucinations in neural automatic speech recognition. arXiv:2401.01572
  • Geirhos, R., et al. (2020). Shortcut learning in deep neural networks. Nature Machine Intelligence. arXiv:2004.07780
  • Ginjala, S., Fosler-Lussier, E., Myers, C. W., Parthasarathy, S. (2026). Do LLM decoders listen fairly? Benchmarking how language model priors shape bias in speech recognition. arXiv:2604.21276
  • Graves, A., Fernández, S., Gomez, F., Schmidhuber, J. (2006). Connectionist temporal classification. ICML. PDF
  • Grierson, G. A. (1905, 1916). Linguistic Survey of India, Vols. VII and IX(1).
  • Gulati, A., et al. (2020). Conformer. Interspeech. arXiv:2005.08100
  • Guo, C., Pleiss, G., Sun, Y., Weinberger, K. Q. (2017). On calibration of modern neural networks. ICML. arXiv:1706.04599
  • Hammarström, H., et al. (2026). Glottolog 5.3.
  • Houlsby, N., et al. (2019). Parameter-efficient transfer learning for NLP. ICML. arXiv:1902.00751
  • Howard, J., Ruder, S. (2018). Universal language model fine-tuning for text classification. ACL. doi
  • Hu, E. J., et al. (2022). LoRA: Low-rank adaptation of large language models. ICLR. arXiv:2106.09685
  • India, M., Safari, P., Hernando, J. (2019). Self multi-head attention for speaker recognition. Interspeech. arXiv:1906.09890
  • Izmailov, P., Podoprikhin, D., Garipov, T., Vetrov, D., Wilson, A. G. (2018). Averaging weights leads to wider optima and better generalization. UAI. arXiv:1803.05407
  • Javed, T., et al. (2022). Towards building ASR systems for the next billion users. AAAI. arXiv:2111.03945
  • Javed, T., et al. (2023). IndicSUPERB. AAAI. arXiv:2208.11761
  • Javed, T., et al. (2024). IndicVoices. Findings of ACL. arXiv:2403.01926
  • Jia, F., Koluguri, N. R., Balam, J., Ginsburg, B. (2023). A compact end-to-end model with local and global context for spoken language identification. Interspeech. arXiv:2210.15781
  • Kachru, B. B. (1983). The Indianization of English. Oxford University Press.
  • Kachru, Y. (2008). Hindi–Urdu–Hindustani. In Language in South Asia. Cambridge University Press.
  • Kahali, S., et al. (2026). Understanding multilingual medical ASR adaptation through layer-wise analysis. arXiv:2608.18825
  • Kalluri, S. B., et al. (2024). The second DISPLACE challenge. Interspeech. arXiv:2406.09494
  • Kannan, A., et al. (2019). Large-scale multilingual speech recognition with a streaming end-to-end model. Interspeech. arXiv:1909.05330
  • Kendall, A., Gal, Y., Cipolla, R. (2018). Multi-task learning using uncertainty to weigh losses. CVPR. arXiv:1705.07115
  • Kiela, D., et al. (2021). Dynabench. NAACL. arXiv:2104.14337
  • Kim, H., Joshi, K., Zhou, L., Golik, P., Aleksic, P. (2026). Are you speaking my languages? On spoken language adherence in multimodal LLMs. arXiv:2606.17281
  • King, C. R. (1994). One Language, Two Scripts: The Hindi Movement in Nineteenth Century North India. Oxford University Press.
  • Ko, T., Peddinti, V., Povey, D., Khudanpur, S. (2015). Audio augmentation for speech recognition. Interspeech.
  • Ko, T., et al. (2017). A study on data augmentation of reverberant speech for robust speech recognition. ICASSP. IEEE
  • Koenecke, A., et al. (2024). Careless Whisper: Speech-to-text hallucination harms. FAccT. arXiv:2402.08021
  • Kogan, A. I. (2016). Genealogical classification of New Indo-Aryan languages and lexicostatistics. Journal of Language Relationship 14(3–4).
  • Koluguri, N. R., et al. (2025). Granary. arXiv:2505.13404
  • Kornblith, S., Norouzi, M., Lee, H., Hinton, G. (2019). Similarity of neural network representations revisited. ICML. arXiv:1905.00414
  • Kukk, K., Alumäe, T. (2022). Improving language identification of accented speech. Interspeech. arXiv:2203.16972
  • Kumar, M. P., Packer, B., Koller, D. (2010). Self-paced learning for latent variable models. NIPS. papers.nips.cc
  • Kumar, S., et al. (2025). ASR under the stethoscope. arXiv:2512.10967
  • Kwok, C. Y., Yip, J. Q., Chng, E. S. (2024). Continual learning with embedding layer surgery and task-wise beam search using Whisper. SLT. arXiv:2501.07875
  • Le-Duc, K., et al. (2025). MultiMed: Multilingual medical speech recognition. ACL Industry. arXiv:2409.14074
  • Lee, Y., et al. (2023). The 2022 NIST language recognition evaluation. Interspeech. arXiv:2302.14624
  • Li, H., Ma, B., Lee, K. A. (2013). Spoken language recognition: From fundamentals to practice. Proceedings of the IEEE 101(5). IEEE
  • Li, J., et al. (2025). Efficient multilingual ASR finetuning via LoRA language experts. Interspeech. arXiv:2506.21555
  • Li, X., et al. (2023). YODAS. ASRU. arXiv:2406.00899
  • Liao, F.-T., et al. (2023). Zero-shot domain-sensitive speech recognition with prompt-conditioning fine-tuning. ASRU. arXiv:2307.10274
  • Lin, T.-Y., Goyal, P., Girshick, R., He, K., Dollár, P. (2017). Focal loss for dense object detection. ICCV. arXiv:1708.02002
  • Lopez-Moreno, I., et al. (2014). Automatic language identification using deep neural networks. ICASSP. Google Research
  • Loshchilov, I., Hutter, F. (2019). Decoupled weight decay regularization. ICLR. arXiv:1711.05101
  • Mahanta, S. (2012). Assamese. Journal of the International Phonetic Association 42(2).
  • Masica, C. P. (1972). The Sound System of Indian English. CIEFL, Hyderabad.
  • Masica, C. P. (1976). Defining a Linguistic Area: South Asia. University of Chicago Press.
  • Mehler, J., et al. (1988). A precursor of language acquisition in young infants. Cognition 29(2). PubMed
  • Menon, A. K., et al. (2021). Long-tail learning via logit adjustment. ICLR. arXiv:2007.07314
  • Mukhoti, J., et al. (2020). Calibrating deep neural networks using focal loss. NeurIPS. arXiv:2002.09437
  • Okabe, K., Koshinaka, T., Shinoda, K. (2018). Attentive statistics pooling for deep speaker embedding. Interspeech. arXiv:1803.10963
  • Olivier, R., Raj, B. (2023). There is more than one kind of robustness: Fooling Whisper with adversarial examples. Interspeech. arXiv:2210.17316
  • Omnilingual ASR team, Meta (2025). Omnilingual ASR: Open-source multilingual speech recognition for 1600+ languages. arXiv:2511.09690
  • Papyan, V., Han, X. Y., Donoho, D. L. (2020). Prevalence of neural collapse during the terminal phase of deep learning training. PNAS. arXiv:2008.08186
  • Park, D. S., et al. (2019). SpecAugment. Interspeech. arXiv:1904.08779
  • Pasad, A., Chou, J.-C., Livescu, K. (2021). Layer-wise analysis of a self-supervised speech representation model. ASRU. arXiv:2107.04734
  • Pasad, A., Shi, B., Livescu, K. (2023). Comparative layer-wise analysis of self-supervised speech models. ICASSP. arXiv:2211.03929
  • Peng, P., Yan, B., Watanabe, S., Harwath, D. (2023). Prompting the hidden talent of web-scale speech models for zero-shot task generalization. Interspeech. arXiv:2305.11095
  • Peng, Y., et al. (2023). Reproducing Whisper-style training using an open-source toolkit and publicly available data. ASRU. arXiv:2309.13876
  • Peng, Y., et al. (2025). OWSM v4: Improving open Whisper-style speech models via data scaling and cleaning. Interspeech. arXiv:2506.00338
  • Peters, M. E., et al. (2018). Deep contextualized word representations. NAACL. arXiv:1802.05365
  • Platanios, E. A., et al. (2019). Competence-based curriculum learning for neural machine translation. NAACL. arXiv:1903.09848
  • Pratap, V., et al. (2024). Scaling speech technology to 1,000+ languages. JMLR 25(97). arXiv:2305.13516
  • Qian, M., Tang, S., Ma, R., Knill, K. M., Gales, M. J. F. (2024). Learn and don’t forget: Adding a new language to ASR foundation models. Interspeech. arXiv:2407.06800
  • Qwen Team (2025). Qwen3-Omni technical report. arXiv:2509.17765
  • Qwen Team (2026). Qwen3-ASR technical report. arXiv:2601.21337
  • Qwen Team (2026). Qwen3.5-Omni technical report. arXiv:2604.15804
  • Radford, A., et al. (2019). Language models are unsupervised multitask learners. OpenAI
  • Radford, A., et al. (2023). Robust speech recognition via large-scale weak supervision. ICML. arXiv:2212.04356
  • Raffel, C., et al. (2020). Exploring the limits of transfer learning with a unified text-to-text transformer. JMLR. arXiv:1910.10683
  • Raina, V., et al. (2024). Muting Whisper: A universal acoustic adversarial attack on speech foundation models. EMNLP. ACL
  • Rahman, H. (2026). Benchmarking multilingual speech models on Pashto: Zero-shot ASR, script failure, and cross-domain evaluation. arXiv:2604.04598
  • Ramus, F., Nespor, M., Mehler, J. (1999). Correlates of linguistic rhythm in the speech signal. Cognition 73(3). PubMed
  • Ranzato, M., Chopra, S., Auli, M., Zaremba, W. (2016). Sequence level training with recurrent neural networks. ICLR. arXiv:1511.06732
  • Sadjadi, S. O., et al. (2018). The 2017 NIST language recognition evaluation. Odyssey. ISCA
  • Sener, O., Koltun, V. (2018). Multi-task learning as multi-objective optimization. NeurIPS. arXiv:1810.04650
  • Shon, S., et al. (2020). ADI17: A fine-grained Arabic dialect identification dataset. ICASSP. IEEE
  • Shivakumar, P. G., Gu, Y., Gandhe, A., Bulyko, I. (2025). Group relative policy optimization for speech recognition. ASRU. arXiv:2509.01939
  • Snyder, D., Chen, G., Povey, D. (2015). MUSAN: A music, speech, and noise corpus. arXiv:1510.08484
  • Snyder, D., et al. (2018). Spoken language recognition using x-vectors. Odyssey. PDF
  • Song, Z., et al. (2024). LoRA-Whisper: Parameter-efficient and extensible multilingual ASR. Interspeech. arXiv:2406.06619
  • Szegedy, C., Vanhoucke, V., Ioffe, S., Shlens, J., Wojna, Z. (2016). Rethinking the Inception architecture for computer vision. CVPR. arXiv:1512.00567
  • Thomason, S. G. (2000). Linguistic areas and language history. In Languages in Contact. Brill.
  • Toshniwal, S., et al. (2018). Multilingual speech recognition with a single end-to-end model. ICASSP. arXiv:1711.01694
  • Valk, J., Alumäe, T. (2021). VoxLingua107. SLT. arXiv:2011.12998
  • van Doorn, J., et al. (2024). Whisper-ATC: Open models for air traffic control ASR with accuracy. ICRAT. TU Delft
  • Voxtral team, Mistral AI (2025). Voxtral. arXiv:2507.13264
  • Wang, F., Cheng, J., Liu, W., Liu, H. (2018). Additive margin softmax for face verification. IEEE Signal Processing Letters. arXiv:1801.05599
  • Wang, Z., Lipton, Z. C., Tsvetkov, Y. (2020). On negative interference in multilingual models. EMNLP. arXiv:2010.03017
  • Watanabe, S., Hori, T., Hershey, J. R. (2017). Language independent end-to-end architecture for joint language identification and speech recognition. ASRU.
  • Wiltshire, C. R., Harnsberger, J. D. (2006). The influence of Gujarati and Tamil L1s on Indian English. World Englishes 25(1).
  • Wortsman, M., et al. (2022). Model soups. ICML. arXiv:2203.05482
  • Yan, B., Pratap, V., Watanabe, S., Auli, M. (2024). Improving multilingual ASR in the wild using simple N-best re-ranking. arXiv:2409.18428
  • Yang, C.-K., Huang, K.-P., Lee, H.-y. (2024). Do prompts really prompt? Exploring the prompt understanding capability of Whisper. SLT. arXiv:2406.05806
  • Yang, S.-w., et al. (2021). SUPERB. Interspeech. arXiv:2105.01051
  • Yu, T., et al. (2020). Gradient surgery for multi-task learning. NeurIPS. arXiv:2001.06782
  • Zissman, M. A. (1996). Comparison of four approaches to automatic language identification of telephone speech. IEEE Transactions on Speech and Audio Processing 4(1). IEEE

Government, standards and industry sources

Contents

Show in the reference list