Automatic Speech Recognition
Transformers
Uzbek
uzbek
gigaam
ctc
punctuation
Eval Results (legacy)

Access Uzbek ASR (GigaAM fine-tune)

Free for evaluation and non-commercial research. Commercial use requires a written license — contact rustamm.nuriddinov@gmail.com.

Log in or Sign Up to review the conditions and access this model content.

Uzbek ASR — GigaAM-Multilingual CTC fine-tunes

Live demo: stt.rustamnuriddinov.uz · Commercial use, on-prem deployment & custom fine-tuning: rustamm.nuriddinov@gmail.com

Open Uzbek speech recognition with punctuation, fine-tuned from GigaAM-Multilingual (MIT) on 1.6k hours of Uzbek speech.

This repository holds the full ablation ladder — six checkpoints, each one a question that was asked and answered — not just the final weights. The corpus definition and the evaluation set are published alongside it, so every number below can be checked rather than taken on trust:

Results

Two test sets, because one of them flatters everybody.

Spontaneous speech — the number that matters

311 human-verified clips of real Uzbek conversation (benchmark). Corpus-level WER/CER, text lowercased, apostrophes canonicalized, punctuation stripped on both sides.

Model Params WER WER (canonical) CER
large_full_600m + KenLM (this repo, --lm) 600M 11.5% 10.9% 3.4%
large_full_600m (this repo, greedy) 600M 12.2% 11.7% 3.4%
gemini_full_220m + KenLM (this repo, --lm) 220M 12.2% 11.7% 3.8%
gemini_full_220m (this repo, greedy) 220M 13.9% 13.3% 3.8%
gemini_bench_220m (this repo) 220M 14.0% — 3.8%
punct_220m (this repo) 220M 15.0% — 4.1%
base_220m (this repo) 220M 15.5% — 4.5%
GigaAM-large — untuned baseline 600M 16.1% — 5.8%
GigaAM — untuned baseline 220M 17.1% — 5.4%
whisper-large-v3-turbo-uzbek 809M 39.6% — 19.4%

The canonical column joins Uzbek clitics on both sides before scoring — see below for why that is the fairer number. Per-clip predictions for the shipped configurations are in the benchmark repository, so the table can be recomputed line by line.

KenLM decoding takes the same weights from 12.2% to 11.5% without training, and the 220M from 13.9% to 12.2%: the weaker the acoustic model, the more the language model recovers. A 4-gram word model over 387k punctuated training sentences (7.1M words) rescores 256 CTC beams; it mostly fixes one-or-two-letter spelling slips, the largest error category. Weights (alpha 0.2, beta 0) were chosen by 2-fold cross-validation on the benchmark.

Correction (2026-10-17). Earlier versions of this card reported 10.2% / 10.8% with KenLM. That LM's text contained 62 of the 311 benchmark clips: the same YouTube recordings also appear in two other training sources (yt_it, yt_podcasts), which the row-level exclusion did not catch. On those clips the old LM scored 5.8% WER — it had memorised them. The LM is now decontaminated (any sentence sharing a 10-word sequence with a benchmark reference is dropped, with ±25 neighbouring rows), and the numbers above are the honest ones. On the 249 clean clips the new LM is slightly better than the old one (11.42% vs 11.53%). The acoustic models were checked the same way and are unaffected: greedy WER on the 62 clips is higher than on the rest.

Throughput. One RTX 4090, the 1.98-hour set, production code path: 600M greedy 163× realtime, 600M + KenLM 122× (beam search runs on one CPU core), 220M greedy 193×, 220M + KenLM 126×. VRAM: 3.6 GB for 600M, 1.4 GB for 220M. bf16 autocast changed neither speed nor accuracy at this request size.

FLEURS (read speech)

650 samples, 2.13 h. Included for comparability with published results, not because it measures the product.

Model Params WER CER
GigaAM-large — untuned baseline 600M 6.7% 1.2%
base_220m (this repo) 220M 9.4% 1.8%
GigaAM — untuned baseline 220M 9.5% 1.7%
punct_220m (this repo) 220M 9.6% 1.9%
whisper-large-v3-turbo-uzbek 809M 19.6% 4.4%

Read the two tables together and the point of the second one becomes clear: on FLEURS the fine-tune looks like a rounding error, on real speech it is 1.6 points. The 600M checkpoints were never scored on FLEURS — by then the question had stopped being interesting.

Validation

Held-out, speaker-disjoint, punctuated. Same split for every run below, so these are the numbers the ablation was actually steered by.

Run Params Val WER
large_full_600m 600M 10.32%
large_bench_600m 600M 11.08%
gemini_full_220m 220M 11.21%
gemini_bench_220m 220M 11.91%
punct_220m 220M 13.98%

Which checkpoint

Variant Path Params Use it when
large-600m checkpoints/large_full_600m/best.pt 600M accuracy matters — the default
220m checkpoints/gemini_full_220m/best.pt 220M throughput or a smaller GPU matters
220m-no-youtube-llm checkpoints/punct_220m/best.pt 220M you need weights trained only on human-transcribed audio

The remaining checkpoints (base_220m, gemini_bench_220m, large_bench_600m) are ablation stages, kept so the ladder below is auditable.

Language model. lm/uz-4gram-2026-10-17.bin (KenLM binary, 180 MB), lm/uz-4gram-2026-10-17.unigrams.txt, and .json with the corpus hash and decontamination settings. Decoding: beam 256, alpha 0.2, beta 0.0 for both sizes (2-fold cross-validation; held-out 11.11% and 12.26%). The uz-4gram-2026-10-16 files are kept only so *-0.2.0 tags stay reproducible — do not use them.

Release tags. Each production version is an immutable tag — pin it instead of main:

Tag Weights Decoding WER
uzasr-large-v0.2.1 large_full_600m KenLM (decontaminated) 11.5%
uzasr-large-0.2.0 large_full_600m KenLM, leaked LM — superseded 10.2%*
uzasr-large-0.1.0 large_full_600m greedy 12.2%
uzasr-base-v0.2.1 gemini_full_220m KenLM (decontaminated) 12.2%
uzasr-base-0.2.0 gemini_full_220m KenLM, leaked LM — superseded 10.8%*
uzasr-base-0.1.0 gemini_full_220m greedy 13.9%

Usage

pip install torch transformers huggingface_hub soundfile numpy
wget https://huggingface.co/rustam1221/uzbek-asr-gigaam/raw/main/inference.py

python inference.py interview.mp3
python inference.py interview.mp3 --variant 220m --device cpu

pip install pyctcdecode kenlm          # optional, for --lm
python inference.py interview.mp3 --lm
from inference import UzbekAsr

asr = UzbekAsr.from_hub("large-600m", lm=True)
print(asr.transcribe("interview.mp3"))
# Assalomu alaykum, bugungi suhbatimizda ta'lim tizimi haqida gaplashamiz.

inference.py is standalone: it downloads the checkpoint, rebuilds the extended CTC head, restores the punctuation vocabulary, splits audio past the model's 30 s limit at its quietest point, and applies sentence-start capitalization. ffmpeg must be on PATH — any audio or video container works.

How it was built

Why GigaAM and not Whisper

Whisper is the obvious starting point and it was the wrong one for Uzbek. On spontaneous speech the best available Uzbek Whisper fine-tune (whisper-large-v3-turbo-uzbek) scores 39.6% WER, against 16.1% for the untuned GigaAM-large. Fine-tuning cannot close a gap that size; the base model choice decided the outcome before any training ran.

GigaAM-Multilingual is character-level CTC, which also made punctuation cheap — see below — and its MIT license allows the fine-tuned weights to be licensed commercially.

Punctuation as four extra CTC rows

Most Uzbek ASR output is an unpunctuated lowercase stream, which is close to unusable as a product. Instead of bolting on a separate punctuation-restoration model, . , ? ! were added directly to the CTC vocabulary: the head's output convolution gains four rows, initialized to zero weight and bias −8, so the new symbols start effectively silent and the warm-started model does not regress while it learns them.

Every punctuation run therefore reports two validation numbers: WER with symbols, and WER with symbols stripped. The second one is the regression guard, and it held — 8.26% before the punctuation phase, 8.03% after. The model learned to punctuate for free, from prosody, and got slightly better at words while doing it.

Sentence-start capitalization is then a deterministic rule over the punctuation (inference.py), not something the model has to spend capacity on.

The ablation ladder

Each run warm-starts from the one above it. Validation is the held-out speaker-disjoint split of the training corpus.

Run Params Warm start Training data Steps Val WER
base_220m 220M GigaAM 220M 916 h, punctuation stripped 13,000 / 14,000 8.26%¹
punct_220m 220M base_220m 795 h punctuated 3,500 / 4,000 13.98% (8.03% stripped)
gemini_bench_220m 220M punct_220m + 120 h LLM-transcribed YouTube 3,500 / 4,000 11.91%
gemini_full_220m 220M gemini_bench_220m + 660 h LLM-transcribed YouTube 5,500 / 8,000 11.21%
large_bench_600m 600M GigaAM-large 600M 795 h + 120 h 4,000 / 4,000 11.08%
large_full_600m 600M large_bench_600m 795 h + 660 h 6,000 / 8,000 10.32%

¹ not comparable with the rows below — that run had no punctuation in its targets.

All runs: character-level CTC, bf16, SpecAugment (2 frequency masks × 8 bins, 2 time masks × 5%), AdamW with weight decay 0.01, gradient clipping at 1.0, cosine schedule after warmup, fixed seed, on a single RTX 4090 16 GB. Batches are measured in audio-seconds rather than utterances so step size stays constant across a corpus with 0.5–30 s clips: 480 audio-seconds per step for the 220M runs, 468 for the 600M run.

large_full_600m was stopped at step 6,000 of a planned 8,000. The published checkpoint is the best validation point reached; the last two thousand steps were never run, so the 600M line is a floor rather than a converged result.

What the ladder showed

FLEURS does not measure this task. After the base fine-tune, FLEURS said 9.4% against the baseline's 9.5% — no gain worth reporting. On spontaneous speech the same checkpoint went from 17.1% to 15.5%. FLEURS is read audiobook-style speech; if it had been the only benchmark, the entire training run would have looked like a waste. This is why the spontaneous benchmark was built before the training budget was spent.

Data returns saturate fast, and cheaply-measured. LLM-transcribed YouTube speech was the obvious way to buy in-domain data. Rather than train on all 660 hours and find out, a 120-hour capped run went first: it bought 1.0 WER point. The full 660 hours then bought roughly 0.1 more on the benchmark. Five and a half times the data, a twentieth of the gain — the cap experiment paid for itself several times over.

Capacity picked up where data stopped. With 220M saturated, 600M was the remaining lever, and it moved the number the data no longer could: 13.9% → 12.2% on spontaneous speech, 1.7 points, against the ~0.1 points the last 540 hours of data had bought. Note also that the 600M model reached 11.08% validation WER in 4,000 steps from the raw base model — better than the 220M ladder managed in 22,000. And it did that without finishing: the run stopped at 6,000 of 8,000 steps.

Part of the remaining gap was measurement, not recognition. Uzbek clitics (da, ku, chi, mi, …) are written both joined and separated in real text, and neither spelling is wrong. Scoring them as errors charged the model 0.6 WER points for an orthographic convention. Canonicalizing both sides before scoring is the honest measurement; it was worth checking, and it was worth knowing that it explained only 0.6 points rather than the 3–4 first estimated.

Training data

916 hours of training audio across seven public corpora — UzbekVoice, Uzbek Speech Corpus, Common Voice, FLEURS, and three YouTube collections (974 h including the validation and test splits) — plus roughly 660 hours of LLM-transcribed spontaneous YouTube speech. Filtering, text normalization, speaker-disjoint splitting and the exact row-level manifests are documented in uzbek-asr-train-manifests.

The 315 benchmark rows are excluded from training and the exclusion was verified — zero leaked rows.

Limitations

  • large_full_600m is not converged — the run stopped at 6,000 of 8,000 planned steps, so 12.2% is a floor, not a limit.
  • 11.5% is not yet at the target. The goal is 10% WER on spontaneous speech; 1.5 points remain. Finishing the 600M run, more LM text, and better handling of overlapping speech are the open levers.
  • The error tail is overlapping speech. The worst 30 benchmark clips carry 24% of all errors, and they are 25–30 s multi-speaker segments where turns overlap. Half the substitution errors are within two characters of the reference — spoken-form spelling variants rather than misheard words.
  • Proper nouns stay lowercase. Only sentence-start capitalization is applied; a named-entity layer is not implemented.
  • Comma placement follows written grammar, inherited from the training transcripts, and does not always match the speaker's pauses.
  • Code-switching into Russian and English is the weakest category after overlap: roughly 7% of substitutions.
  • No streaming. Decoding runs over whole utterances (up to 30 s per chunk); a streaming decoder is open.

Repository layout

checkpoints/<run>/best.pt   weights, plus the run config and vocabulary
configs/<run>.yaml          the exact training config each run used
lm/uz-4gram-<date>.*        KenLM binary, unigrams and corpus metadata
inference.py                standalone transcription script
requirements.txt

Each best.pt carries the full training config, step count, best validation WER and character vocabulary, so a checkpoint is self-describing — the configs/ files are extracted from the checkpoints themselves, which is how the 600M configs survived the loss of the training machine.

License and provenance

Weights are released under the Uzbek ASR Commercial License — see LICENSE.md. Free for evaluation and non-commercial research; any commercial use requires a written license agreement. Contact: rustamm.nuriddinov@gmail.com · live demo: https://stt.rustamnuriddinov.uz

Base model: GigaAM-Multilingual by GigaChat Team (ai-sage), MIT License — its copyright notice is reproduced in LICENSE.md.

Citation

@misc{uzbek_asr_gigaam,
  title  = {Uzbek ASR: GigaAM-Multilingual CTC fine-tunes with punctuation},
  author = {Nuriddinov, Rustamjon},
  year   = {2026},
  url    = {https://huggingface.co/rustam1221/uzbek-asr-gigaam}
}
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for rustam1221/uzbek-asr-gigaam

Finetuned
(4)
this model
Quantizations
1 model

Datasets used to train rustam1221/uzbek-asr-gigaam

Space using rustam1221/uzbek-asr-gigaam 1

Evaluation results

  • WER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    10.200
  • CER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    3.260
  • WER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    12.240
  • CER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    3.370
  • WER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    10.780
  • CER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    3.470
  • WER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    13.880
  • CER on Uzbek Spontaneous Speech ASR Benchmark
    self-reported
    3.770