Part II: Pipeline

Dataset

No recorded Telugu corpus exists locally, so the evaluation set is synthesized: 129 template questions with exact reference answers, spoken by an open Telugu TTS model, in a clean and a noisy version.

Synthetic speech, not real speakers The numbers in these docs say nothing about accents, prosody, disfluency or recording channels. Treat them as a controlled, reproducible baseline, not as field accuracy.

Overview

Size129 questions per condition (29 capitals + 100 additions). The requirement is at least 100.
LanguageTelugu, Telugu script for text.
TTS modelfacebook/mms-tts-tel (MMS, VITS-based), run through transformers' VitsModel.
Conditionsclean: synthesized audio as is. noisy: additive white Gaussian noise at 0 dB SNR.
Generatorsynthesize_corpus.py
Why templatesEvery reference answer states exactly one checkable fact, which makes correctness and hallucination testable without a human judge. See the hallucination metric.

Question templates

29 state and country capitals

Pattern: question "<place> రాజధాని ఏది?" (What is the capital of <place>?), answer "<place> రాజధాని <capital>." This follows the example pattern given in the requirements. IDs are cap-001 to cap-029.

#PlaceTeluguCapitalTelugu
1TelanganaతెలంగాణHyderabadహైదరాబాద్
2Andhra Pradeshఆంధ్రప్రదేశ్Amaravatiఅమరావతి
3Tamil NaduతమిళనాడుChennaiచెన్నై
4Karnatakaకర్ణాటకBengaluruబెంగళూరు
5KeralaకేరళThiruvananthapuramతిరువనంతపురం
6Maharashtraమహారాష్ట్రMumbaiముంబై
7Gujaratగుజరాత్Gandhinagarగాంధీనగర్
8Rajasthanరాజస్థాన్Jaipurజైపూర్
9Punjabపంజాబ్Chandigarhచండీగఢ్
10West Bengalపశ్చిమ బెంగాల్Kolkataకోల్‌కతా
11Biharబీహార్Patnaపాట్నా
12OdishaఒడిశాBhubaneswarభువనేశ్వర్
13Madhya Pradeshమధ్యప్రదేశ్Bhopalభోపాల్
14Uttar Pradeshఉత్తరప్రదేశ్Lucknowలక్నో
15Haryanaహర్యానాChandigarhచండీగఢ్
16Assamఅస్సాంDispurదిస్పూర్
17Chhattisgarhఛత్తీస్‌గఢ్Raipurరాయ్‌పూర్
18Jharkhandజార్ఖండ్Ranchiరాంచీ
19GoaగోవాPanajiపనాజీ
20Sikkimసిక్కింGangtokగ్యాంగ్‌టక్
21Manipurమణిపూర్Imphalఇంఫాల్
22MeghalayaమేఘాలయShillongషిల్లాంగ్
23Nagalandనాగాలాండ్Kohimaకోహిమా
24Tripuraత్రిపురAgartalaఅగర్తలా
25MizoramమిజోరంAizawlఐజ్వాల్
26Arunachal Pradeshఅరుణాచల్ ప్రదేశ్Itanagarఇటానగర్
27Uttarakhandఉత్తరాఖండ్Dehradunడెహ్రాడూన్
28Himachal Pradeshహిమాచల్ ప్రదేశ్Shimlaషిమ్లా
29IndiaభారతదేశNew Delhiన్యూఢిల్లీ

100 addition problems

Every ordered pair (a, b) with a and b from 1 to 10, spoken with Telugu number words, so sums run from 2 to 20. IDs are sum-001 to sum-100. Pattern: question "<a> మరియు <b> కలిపితే ఎంత వస్తుంది?" (what do a and b make together?), answer "<a> మరియు <b> కలిపితే <sum> వస్తుంది."

Number words are spelled out (not digits) so the TTS pronounces them naturally. Both orders of each pair appear, which adds variety without new vocabulary.

nTelugunTelugunTelugunTelugu
1ఒకటి6ఆరు11పదకొండు16పదహారు
2రెండు7ఏడు12పన్నెండు17పదిహేడు
3మూడు8ఎనిమిది13పదమూడు18పద్దెనిమిది
4నాలుగు9తొమ్మిది14పదనాలుగు19పందొమ్మిది
5ఐదు10పది15పదిహేను20ఇరవై
Where the questions' correctness comes from The capitals and number words are fixed lists in synthesize_corpus.py, and the sums are computed, so a reference answer cannot be wrong by construction. They are template-generated, not reviewed by a Telugu linguist; a grammatical wrinkle in a phrase would be in the template, not random.

The noisy condition

Zero-mean Gaussian noise is added to the clean waveform at a fixed signal-to-noise ratio:

noise_power = signal_power / 10^(snr_db / 10)
noisy = clean + Normal(0, sqrt(noise_power))
if max(|noisy|) > 1: noisy = noisy / max(|noisy|)     # avoid clipping

At 0 dB, noise power equals signal power. The noise generator is seeded (numpy seed 42), so the same noisy waveform is produced for the same clean waveform.

Why 0 dB and not 8 dB The corpus was first built at 8 dB SNR. Corpus WER there was 0.2913 vs. 0.2928 clean: no measurable bottleneck, so nothing for a fix to address. The noise was raised to 0 dB, which produced a real WER increase (+0.045, CI +0.014 to +0.077). The script's default is still 8 dB (TARGET_SNR_DB = 8.0); the reported results pass --snr-db 0.

File formats

Synthesized corpus folder

corpus_clean/ and corpus_noisy/ use prepare_data.py's sidecar format, one triple per question:

corpus_clean/
  question_cap-001.wav             audio (sample rate = the TTS model's rate)
  question_cap-001.txt             reference transcript = the spoken question
  question_cap-001.response.txt    reference answer
  ...
  question_sum-100.{wav,txt,response.txt}

Evaluator manifest

prepare_data.py --limit 0 turns a folder into data/test_clean.json / data/test_noisy.json plus a .metadata.json. Each row:

{
  "id": "te-000001",
  "audio_path": "../corpus_clean/question_cap-001.wav",
  "ground_truth_transcript": "...",
  "ground_truth_response": "...",
  "response_source": "provided"
}

Clean and noisy are not matched recordings

The noisy corpus is not the clean audio plus noise. The TTS model's duration prediction is not seeded, and the noisy set was regenerated once at the harsher SNR, so each condition is an independent rendering of the same text. Consequences: