Reference

Modules and CLI

Every Python file in the repository, what it exposes, and how to call it. All scripts are run from the repository root. About 1,990 lines of code in 11 modules, plus 8 test files.

ModuleLinesPurpose
asr.py144Whisper ASR wrapper with timing
llm.py96Chat-LLM wrapper with timing
pipeline.py127Composes ASR and LLM; JSON CLI; config loader
denoise.py68Spectral-subtraction front end
evaluate.py394Metrics and the batch evaluation CLI
prepare_data.py201Builds evaluator manifests from folders or tables
synthesize_corpus.py140TTS corpus generator (clean and noisy)
plot_results.py202Headless plots from evaluation outputs
hallucination.py121Correct / abstained / hallucinated classifier
bootstrap.py87Paired bootstrap intervals
verify_task2.py410Setup checks and a mock end-to-end run

asr.py

Whisper-compatible ASR with local audio decoding and synchronized timing. Inputs supported by libsndfile (WAV, FLAC) work without FFmpeg.

Functions

class ASRWrapper

ASRWrapper(model_name="openai/whisper-large-v3", *, device="auto", dtype="auto",
           cache_dir=None, revision="main", language="telugu",
           chunk_length_s=30, batch_size=1, generation=None, denoise=False)

llm.py

class LLMWrapper

LLMWrapper(model_name="Qwen/Qwen2.5-7B-Instruct", *, device="auto", dtype="auto",
           cache_dir=None, revision="main",
           system_prompt="Answer clearly and concisely in Telugu script.",
           max_input_tokens=2048, generation=None)

pipeline.py

python pipeline.py [--config config.yaml] [--audio FILE] [--output FILE]

--audio and --output override the config, resolved from the current directory. Prints the JSON and saves it. Exits with status 1 on failure.

denoise.py

spectral_subtract_denoise(audio, sample_rate, *, noise_percentile=10.0,
                          oversubtraction=1.5, floor=0.05) -> np.ndarray

Returns a denoised float32 copy of a 1-D mono waveform. Validates input and parameters. See the extension page for the algorithm.

evaluate.py

Metric functions (standard library only)

NameWhat it does
normalize_text(text)NFC and collapsed whitespace.
levenshtein_distance(ref, hyp)Unit-cost edit distance over any token sequences, two-row DP.
ErrorRate(edits, reference_units)Frozen dataclass; .rate is None for an empty reference.
transcript_errors(ref, hyp){"wer": ErrorRate, "cer": ErrorRate}
word_error_rate, character_error_rateConvenience wrappers returning the float or None.
response_token_f1(ref, hyp)Multiset word-overlap F1.
real_time_factor(total_s, audio_s)Validated ratio.
audio_duration(path)Duration from file metadata via soundfile.

Dataset and evaluation

CLI

python evaluate.py --dataset DATA.json [--config config.yaml]
                   [--output-dir outputs/evaluation] [--warmup N] [--fail-fast]
FlagMeaning
--dataset (required)Evaluator manifest JSON.
--configConfig file (default: config.yaml next to the script).
--output-dirWhere the four output files go (default outputs/evaluation).
--warmup NUnmeasured paired runs on the first sample before the real pass (the first sample is still evaluated afterwards).
--fail-fastStop on the first failed sample.

The CLI refuses to run if llm.generation.do_sample is true, because the paired comparison needs deterministic decoding. It loads both models once, prints the summary JSON, and exits 1 if any sample failed (partial reports are still saved).

prepare_data.py

Builds the evaluator JSON from a local audio folder (with .txt and .response.txt sidecars) or a CSV, TSV or JSON manifest. Works only with local files; it does not download datasets or detect the language.

python prepare_data.py --source SRC [--output data/test.json] [--limit 100] [--seed 42]
                       [--response-mode require|placeholder]
                       [--audio-column audio_path]
                       [--transcript-column ground_truth_transcript]
                       [--response-column ground_truth_response] [--overwrite]

synthesize_corpus.py

python synthesize_corpus.py [--clean-out corpus_clean] [--noisy-out corpus_noisy]
                            [--snr-db 8.0] [--limit 0] [--skip-clean]

plot_results.py

python plot_results.py --input report.json|samples.csv|wer_vs_quality.csv
                       [--output-dir outputs/plots] [--quality-label "Word overlap F1"]

Matplotlib only, rendered headless. Produces wer_vs_quality.png (both series against ASR WER) and latency_breakdown.png (stacked mean ASR, LLM and overhead, plus the clean-transcript LLM time as a separate bar). JSON input also reports the failed-sample count; CSV input cannot. Undefined points are omitted with counts in the legend; malformed numbers and incomplete latency records are rejected. It accepts only evaluation outputs, not the prepared dataset JSON. Existing plot files in the output directory are replaced.

hallucination.py

python hallucination.py --reports R1.json [R2.json ...] [--output OUT.json]

bootstrap.py

python bootstrap.py --a REF.json --b COMPARE.json [--metric wer|cer]
                    [--resamples 10000] [--seed 0]

paired_bootstrap(edits_a, units_a, edits_b, units_b, *, resamples, seed, level) returns difference (B minus A), ci_low, ci_high, samples. compare_reports(path_a, path_b, metric) pairs rows by sample ID and errors if the two reports do not cover the same IDs.

verify_task2.py

python verify_task2.py [--config config.yaml] [--output-dir outputs/verification]

Checks: required source files exist and parse; installed dependencies match requirements.txt ranges; configuration types and ranges (including Telugu ASR settings and deterministic decoding); device availability; write access to the cache, output and default data, outputs/evaluation, outputs/plots folders. Then it generates exactly three silent dummy WAVs and runs the real SpeechPipeline and evaluate_dataset with injected stand-ins whose outputs and clocks are synthetic, comparing results with fixed expected values for perfect, substitution and deletion cases plus insertion, empty-reference and Unicode-normalization checks.

Outputs: verification.log, checks.json (PASS / FAIL / WARN / UNAVAILABLE with independent setup-readiness and mock-pass flags), summary.md, and a mock/ folder. Exit status 0 when no FAIL or UNAVAILABLE checks remain; warnings (such as an unpinned revision) do not fail the run.

What it does not verify Model availability, chat-template compatibility, memory fit, or any real speech quality. The mock timings are synthetic and must never be quoted as a benchmark. A relevant rule: asr.language must be telugu/te, or null only when the model name contains "telugu".