Qwen3-ASR-0.6B-Khmer-v4
A 0.6B-parameter Khmer automatic speech recognition (ASR) model, fine-tuned from Qwen3-ASR-0.6B on a large Khmer speech corpus with on-the-fly audio augmentation. It transcribes Khmer audio into Khmer script.
- Base model: Qwen3-ASR-0.6B (
qwen3_asr/Qwen3ASRForConditionalGeneration) - Language: Khmer (
km) - Task: Automatic Speech Recognition
- Selected checkpoint: step 68000 (~3.67 epochs). This is the lowest
dev-set
eval_losscheckpoint (0.0407) of the augmented run.
Evaluation
Evaluated on a held-out set of 145 Khmer utterances. The metric is
Character Error Rate (CER), computed whitespace-insensitive (all
whitespace stripped and text NFC-normalized before the character-level edit
distance). We report two variants: raw, and with punctuation removed (Unicode
categories P/S, which covers the Khmer full-stop ។ and other marks that
carry little acoustic signal).
| Metric | This model (step 68000) |
|---|---|
| CER (ws-insensitive) | 7.92% |
| CER (no punctuation) | 5.77% |
| Exact match (no punctuation) | 40.7% |
The raw CER is dominated by the trailing Khmer full-stop
។, which the model often omits; removing punctuation raises exact-match to ~41% and gives a cleaner view of true recognition quality.
Usage
from qwen_asr import Qwen3ASRModel
asr = Qwen3ASRModel.from_pretrained(
"seanghay/Qwen3-ASR-0.6B-Khmer-v4",
max_new_tokens=256,
)
asr.model.eval()
results = asr.transcribe("audio.wav", language="Khmer")
print(results[0].text)
Recommended decoding for longer audio
This is a small (0.6B) model trained on ~30s windows. Feeding a whole long file at once can trigger repetition loops. Pre-split the audio at silence boundaries into ~15s chunks and cap generation length:
from qwen_asr.inference.utils import SAMPLE_RATE, normalize_audios, split_audio_into_chunks
wav = normalize_audios("long_audio.ogg")[0] # mono float32 @ 16 kHz
parts = split_audio_into_chunks(wav, SAMPLE_RATE, max_chunk_sec=15)
chunks = [(c, SAMPLE_RATE) for c, _ in parts]
results = asr.transcribe(chunks, language="Khmer")
text = " ".join(r.text.strip() for r in results if r.text.strip())
print(text)
Training
- Base: Qwen3-ASR-0.6B
- Data: ~592k Khmer speech–text pairs (train) / 1,000 held-out (dev)
- Augmentation: on-the-fly audio augmentation on the train split (p=0.7); eval kept clean
- Epochs: 4 (this checkpoint is step 68000 of 74036, ~3.67 epochs)
- Effective batch size: 32 (per-device 4 × grad-accum 8)
- Learning rate: 2e-5
- Precision: bf16
- Hardware: single 24 GB GPU (RTX 3090)
Limitations
- Repetition loops can occur on long single chunks or acoustically ambiguous segments (dense Khmer–English code-switching). Use ~15s chunking to mitigate.
- Short/silent chunks (< ~1s) may be hallucinated into a common phrase; drop sub-second tail chunks before transcribing.
- Trained primarily on read/short-form Khmer speech; far-field, noisy, or heavily code-switched audio is out of distribution.
- Punctuation (esp. the sentence-final
។) is often omitted.
Files
Inference weights only (model.safetensors, config, tokenizer). Optimizer and
training state are not included, so this repo cannot resume training.