fast-ukrainian-asr β€” Ukrainian speech recognition, 220M, CTC

A Ukrainian recogniser built by adapting GigaAM's multilingual SSL encoder, tuned for telephone audio and small enough to run in real time on a CPU.

It is not the most accurate Ukrainian model in every setting β€” Whisper large-v3 is clearly better on spontaneous speech, and the numbers below say so. What it does is recognise read and telephone speech more accurately than either Whisper large-v3 or the Whisper Ukrainian fine-tunes, while running on CPU faster than Whisper runs on a GPU, and losing almost nothing when the audio comes down a phone line.

Results

Scored with a single normalizer across all systems (Whisper emits punctuation and capitals this model never produces, so raw-string WER would measure formatting). Telephony = G.711 band-limit, 16k->8k->16k, mu-law, applied ONCE and shared byte-identically by every system. Ukrainian-tagged rows only.

model cv10 clean/tel rs-test clean/tel test-y clean/tel 1500 utts
this model 9.64 / 10.59 28.03 / 28.65 26.28 / 28.67 576 s (CPU)
whisper-large-v3-turbo-uk fine-tune 10.91 / 13.59 22.96 / 23.56 23.47 / 28.24 772 s (GPU)
whisper-large-v3 13.85 / 17.42 16.96 / 19.27 20.90 / 28.06 1051 s (GPU)
Qwen3-ASR 79.4 / 82.2 78.8 / 77.2 88.4 / 84.2 225 s (GPU)

Read the third column before deploying this. On spontaneous speech (rs-test, test-y) Whisper large-v3 is 5-11 points better. This model was trained on broadcast and read speech; it has not seen much conversational audio, and it shows.

The telephony column is the reason it exists. Clean -> phone costs this model +0.95 WER on cv10; it costs Whisper large-v3 +3.57. Telephony augmentation during training buys that, and for a phone product it matters more than a better clean number.

Qwen3-ASR does not support Ukrainian at all β€” its 30-language list has no entry for it, so it transcribes Ukrainian speech into Russian orthography. The row is included so nobody repeats the experiment.

Scope: Ukrainian only

Deliberately monolingual. On Russian utterances it scores ~89% WER and always will: the vocabulary is 38 Ukrainian characters with no Russian-only letters. If your audio is mixed Russian/Ukrainian β€” as much Ukrainian evaluation data quietly is β€” use a multilingual model.

Training

  • Backbone: GigaAM multilingual_ssl (220M, 16 layers, d_model 768), an SSL encoder pretrained on 2M hours across 70+ languages with no Ukrainian.
  • Stage 1: 350 h β€” Yehor/broadcast-speech-uk (309 h) + Common Voice 22 Ukrainian (41 h), 8 epochs, batch 16, lr 1e-4, charwise CTC head, 38 classes.
  • Stage 2: telephony adaptation, 4 epochs at lr 3e-5, 60% of training clips degraded through the phone path, validation 100% degraded so checkpoint selection ranks on what production serves.

Common Voice's train and other splits only: its validated pool shares 1,326 sentences with the cv10 evaluation set and test shares 396, so training on those would quietly contaminate the benchmark. 146 rows containing Latin/Cyrillic homoglyphs (i typed for Ρ–) were repaired rather than dropped.

Usage

import gigaam
model = gigaam.load_model("fast-ukrainian-asr.ckpt", device="cpu")   # or "cuda"
print(model.transcribe("call.wav"))

longform.py handles files longer than ~20 s by energy-based segmentation. server.py exposes an OpenAI-compatible /v1/audio/transcriptions endpoint. Audio must be 16 kHz mono; 8 kHz telephone audio should be upsampled, not fed at its native rate.

Limitations

  • Spontaneous/conversational speech is its weakest case (see the table).
  • No punctuation or capitalisation β€” CTC over 38 characters.
  • No Russian, by design.
  • Numbers are transcribed as words, not digits.
Downloads last month
16
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support

Datasets used to train asfberlin/fast-ukrainian-asr