stt_laos_fastconformer_transducer_large

Lao (ພາສາລາວ) speech recognition, fine-tuned from typhoon-ai/typhoon-asr-realtime, a NeMo FastConformer-Transducer (RNNT) checkpoint.

Character error rate 8.44% on a held-out test set of 1,583 clips, with 114M parameters — roughly a third the size of the CTC models that score near it, and faster than all of them.

Results

CER
this model (114M) 8.44%
validation split (1,619 clips) 8.52%

Inference: 0.091 s per clip, the fastest of six Lao ASR models measured on this same test set with the same scorer.

Read CER, not WER. Lao is written without spaces between words, so word-level error rate mostly measures where the model chose to break rather than whether it heard correctly.

A note on how to read that 8.44%: the test references transliterate English into Lao script, while this model — whose base was pretrained on Thai, which includes Latin text — emits real Latin instead. It produces Word ເວີຊັນ 6.0 where a Lao-only model produces ເວີດເວີຊັນ 6 0. Both are intelligible, but character-for-character against a transliterated reference the correct-looking output scores as wrong. Measured by fully correct transcripts it leads the models it trails on CER: 98 exact matches versus 69 and 60 for two larger CTC models.

Compared with our other Lao fine-tunes

Lao ASR fine-tuned model comparison

model params CER
omniASR CTC v2 325M 7.94%
this model 114M 8.44%
XLSR-53 317M 8.82%
Qwen3-ASR 0.78B 11.47%
Whistle 29MB 12.31%

Every row is the same 1,583 held-out clips through the same scorer. That matters more than it sounds: whisper-normalizer's BasicTextNormalizer deletes Lao tone marks, which would improve every number here by roughly a point and make them incomparable with anything scored properly.

This model is within 0.5 points of the best while being a third of its size and the fastest of the five.

Why the vocabulary had to be replaced

The base checkpoint is Thai. Its 2,048-piece SentencePiece vocabulary contains zero Lao pieces (1,985 are Thai), and a Lao round-trip through it fails on 200 of 200 sentences — the script is entirely unseen.

So the vocabulary was replaced wholesale rather than extended:

model.change_vocabulary(new_tokenizer_dir="tokenizer_lao", new_tokenizer_type="bpe")

This discards the joint network and decoder and retrains them from scratch, while the FastConformer encoder keeps its Thai acoustic pretraining. Thai and Lao are acoustically close even though their scripts do not overlap, and that transfer is what makes a 114M model competitive here.

The replacement tokenizer is 1,024 Lao pieces at 2.27 characters per piece, trained with normalization_rule_name="identity". That setting is not optional: SentencePiece's default NFKC normalisation decomposes Lao ligatures — ໜ (U+0EDC) becomes ຫນ, ໝ becomes ຫມ, ຳ (U+0EB3) becomes ໍ + າ — and NFC does not reverse compatibility decompositions, so the damage is permanent. Round-trip accuracy with the default is 87/200; with identity it is 199/200.

Training

epochs 6
batch 8 x 4 grad-accum (effective 32)
learning rate 1e-3, 500 warmup steps
precision bf16-mixed
hardware one NVIDIA GB10 (aarch64, sm_121)
time ~19 min/epoch
peak GPU 15.53 GB
checkpoint selection best WER on validation

Validation error fell monotonically across all six epochs and had not flattened at the end, so a longer schedule would likely improve this further.

Usage

import nemo.collections.asr as nemo_asr

model = nemo_asr.models.ASRModel.restore_from("stt_laos_fastconformer_transducer_large.nemo")
model.eval()
print(model.transcribe(["clip.wav"], batch_size=8)[0].text)

Audio must be 16 kHz mono. Anything else should go through ffmpeg first:

ffmpeg -i input.m4a -ac 1 -ar 16000 clip.wav

This is not a streaming checkpoint

Despite the base model's name, this checkpoint reports att_context_size = [-1, -1] with att_context_style = regular — full context attention. NeMo's cache-aware streaming requires chunked_limited with a finite context window, and forcing limited attention onto a model trained with full context degrades accuracy.

For a live transcript, re-read the whole rolling buffer instead. At a real-time factor around 0.01, a full re-read costs less than the chunk-boundary errors that splicing would introduce, and the text firms up as speech continues.

Known limitations

  • Trained on clips of up to 30 seconds; longer audio should be segmented.
  • Code-switched English is emitted in Latin script, not transliterated into Lao. This is usually what you want, but it will disagree with Lao-transliterated references.
  • Numbers are emitted as digits (6.0), not spelled out.
  • No punctuation restoration or casing beyond what the acoustic model infers.
  • Single-speaker transcription only; diarisation needs a separate model.

Reproducing

The full pipeline — manifest preparation, the Lao tokenizer, the fine-tune, evaluation and the Lao-safe scorer — is published separately, along with the five non-obvious failure modes worth knowing before repeating this (the RNNT loss making maxU the CUDA block size and capping it at 1,024; the SentencePiece normalisation trap above; why BasicTextNormalizer must not be used to score Lao; the numba-cuda CUDA extra needed on Blackwell; and a stub cuFFT in some container images breaking torch.stft).

Licence

Published by AIDC Technology under the AIDCTECH licence — see LICENSE. Derived from typhoon-ai/typhoon-asr-realtime, which is CC BY 4.0; that attribution and its implications are set out in LICENSE.

Downloads last month
17
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for Phonepadith/stt_laos_fastconformer_transducer_large

Space using Phonepadith/stt_laos_fastconformer_transducer_large 1

Evaluation results