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