Open weights
OpenThai 2.0 ASR Streaming
An open model that writes Thai speech down while people are still talking.
- Parameters0.64billion
- LicenceOpenMDW-1.1
- Text behind the voice80–1120ms
- FLEURS, characters wrong8.47%
Download the weightsRead the launch post
Released 12 November 2026 by iApp Technology, as open weights on Hugging Face.
What it does
- Writes while people speakText arrives 80, 320, 560 or 1120 ms behind the voice. You choose when you decode; the same weights serve every setting, and a longer wait is a little more accurate.
- Any lengthThe included server cuts long recordings at pauses and decodes each piece on its own, as iApp's hosted service does, so a recording of an hour or more decodes in constant memory. We tested files of up to 87 minutes.
- Thai script, or English words in EnglishWith the
th-THprompt everything comes out in Thai script. Withth-mix, English words a speaker says come out in Latin letters. - Who said whatThe included server can label speakers in a meeting, with NVIDIA's open diarization model.
- GPU or CPUOne NVIDIA H100 decodes files about 257 times faster than real time and keeps up with about 20 live streams. A laptop-class CPU with 8 threads keeps up with a live stream.
- The model behind OpenThai ASR RealtimeiApp's hosted live speech-to-text service runs this model; see OpenThai ASR Realtime.
Measured
- 560 ms
- 1120 ms
- By latency
- Whole recordings
Character error rate in %, lower is better, at 560 ms. We decoded every model ourselves with the same NeMo streaming script and the same settings: Typhoon ASR Streaming 0.6B as released, and with the 4-gram language model its authors publish for it.
| Test set | Clips | OpenThai 2.0 ASR Streaming | Typhoon ASR Streaming 0.6B | Typhoon ASR Streaming 0.6B + its 4-gram LM | Difference, ours − Typhoon |
|---|---|---|---|---|---|
| FLEURS, read speech | 1,021 | 8.47 | 11.28 | 11.73 | −2.82 [−3.15, −2.48], ours lower |
| GigaSpeech2 test, YouTube | 8,823 | 15.35 | 16.33 | 16.62 | −0.98 [−1.31, −0.58], ours lower |
| TVSpeech, TV and YouTube talk | 570 | 12.41 | 10.84 | 11.05 | +1.57 [+0.90, +2.52], Typhoon lower |
| LOTUSDIS meetings, conference microphone | 5,516 | 20.77 | 28.91 | 29.02 | −8.15 [−8.88, −7.46], ours lower |
| Isan dialect | 500 | 34.90 | 34.15 | 35.79 | +0.75 [−0.21, +1.69], tie |
- Both sides of every comparison are written the same way before scoring: numbers made equal, spaces and punctuation removed. Differences are ours minus Typhoon ASR Streaming 0.6B, with a 95% paired bootstrap interval that resamples whole videos, recordings, speakers or meetings; an interval that includes zero is a tie. Bold marks an error rate lower than the other model's with 95% confidence.
- TVSpeech is Typhoon ASR Streaming 0.6B's own benchmark. LOTUSDIS: we trained on other meetings from the same rooms and microphones, and some speakers appear in both, so that row favours us. FLEURS: we trained on its training and development splits, not its test split. Both models trained on the GigaSpeech2 training split. We did not train on Isan, and Typhoon ASR Streaming 0.6B's published training data lists none.
- Our released file carries a blank offset of −1.0 chosen on development data. Given the same treatment, Typhoon ASR Streaming 0.6B's best offset on the same development data is -2.0, and its error becomes FLEURS, read speech 11.63, GigaSpeech2 test, YouTube 15.26, TVSpeech, TV and YouTube talk 10.68, LOTUSDIS meetings, conference microphone 26.71, Isan dialect 33.87.
Character error rate in %, lower is better, at 1120 ms. We decoded every model ourselves with the same NeMo streaming script and the same settings: Typhoon ASR Streaming 0.6B as released, and with the 4-gram language model its authors publish for it.
| Test set | Clips | OpenThai 2.0 ASR Streaming | Typhoon ASR Streaming 0.6B | Typhoon ASR Streaming 0.6B + its 4-gram LM | Difference, ours − Typhoon |
|---|---|---|---|---|---|
| FLEURS, read speech | 1,021 | 8.36 | 11.32 | 11.64 | −2.96 [−3.31, −2.65], ours lower |
| GigaSpeech2 test, YouTube | 8,823 | 15.23 | 16.18 | 16.44 | −0.95 [−1.35, −0.49], ours lower |
| TVSpeech, TV and YouTube talk | 570 | 12.14 | 10.70 | 11.18 | +1.45 [+0.77, +2.46], Typhoon lower |
| LOTUSDIS meetings, conference microphone | 5,516 | 20.30 | 28.23 | 28.64 | −7.93 [−8.66, −7.24], ours lower |
| Isan dialect | 500 | 34.49 | 33.73 | 35.68 | +0.76 [−0.28, +1.86], tie |
- Both sides of every comparison are written the same way before scoring: numbers made equal, spaces and punctuation removed. Differences are ours minus Typhoon ASR Streaming 0.6B, with a 95% paired bootstrap interval that resamples whole videos, recordings, speakers or meetings; an interval that includes zero is a tie. Bold marks an error rate lower than the other model's with 95% confidence.
- TVSpeech is Typhoon ASR Streaming 0.6B's own benchmark. LOTUSDIS: we trained on other meetings from the same rooms and microphones, and some speakers appear in both, so that row favours us. FLEURS: we trained on its training and development splits, not its test split. Both models trained on the GigaSpeech2 training split. We did not train on Isan, and Typhoon ASR Streaming 0.6B's published training data lists none.
- Our released file carries a blank offset of −1.0 chosen on development data. Given the same treatment, Typhoon ASR Streaming 0.6B's best offset on the same development data is -2.0, and its error becomes FLEURS, read speech 11.63, GigaSpeech2 test, YouTube 15.26, TVSpeech, TV and YouTube talk 10.68, LOTUSDIS meetings, conference microphone 26.71, Isan dialect 33.87.
| Test set | 80 ms | 320 ms | 560 ms | 1120 ms |
|---|---|---|---|---|
| FLEURS, read speech | 8.73 / 11.78 | 8.53 / 11.67 | 8.47 / 11.28 | 8.36 / 11.32 |
| GigaSpeech2 test, YouTube | 16.64 / 17.75 | 15.53 / 16.64 | 15.35 / 16.33 | 15.23 / 16.18 |
| TVSpeech, TV and YouTube talk | 13.06 / 11.44 | 12.54 / 10.84 | 12.41 / 10.84 | 12.14 / 10.70 |
| LOTUSDIS meetings, conference microphone | 26.12 / 34.35 | 21.79 / 29.49 | 20.77 / 28.91 | 20.30 / 28.23 |
| Isan dialect | 35.84 / 35.37 | 34.72 / 34.65 | 34.90 / 34.15 | 34.49 / 33.73 |
Character error rate in %, ours / Typhoon ASR Streaming 0.6B. Latency is the length of the audio chunk the model waits for: 80 ms is the shortest. Typhoon ASR Streaming 0.6B's model card counts only the look-ahead, so its "1040 ms" is the 1120 ms setting here.
Whole recordings at 560 ms. Each file joins every clip of one video or recording, in order, with one second of silence between clips. "One stream" decodes a file in one pass, as NeMo's script does; "cut at pauses" decodes it as the included server does, in pieces cut where nobody speaks for 0.7 s, each decoded on its own. Both models went through the same code, Typhoon ASR Streaming 0.6B at its released settings.
| Test set | Files | One stream | Cut at pauses | ||||
|---|---|---|---|---|---|---|---|
| OpenThai 2.0 ASR Streaming | Typhoon ASR Streaming 0.6B | Difference, ours − Typhoon | OpenThai 2.0 ASR Streaming | Typhoon ASR Streaming 0.6B | Difference, ours − Typhoon | ||
| TVSpeech, whole videos (0.5–47 min) | 18 | 23.54 | 11.07 | +12.47 [+7.49, +17.08], Typhoon lower | 12.66 | 10.84 | +1.82 [+1.16, +2.74], Typhoon lower |
| GigaSpeech2 test, whole recordings (5–87 min) | 31 | 23.10 | 30.07 | −6.97 [−12.06, −2.63], ours lower | 13.53 | 14.42 | −0.88 [−1.34, −0.41], ours lower |
Decoded as one stream, our model loses words after a pause of near-silence: the longer and quieter the pause, the more it drops. Typhoon ASR Streaming 0.6B does not. Cut at pauses, ours scores about as well as clip by clip, or better. The included server and iApp's hosted OpenThai ASR Realtime both cut at pauses.
In short, at 560 ms this model makes fewer errors than Typhoon ASR Streaming 0.6B on read speech (FLEURS 8.47% against 11.28%), YouTube clips (GigaSpeech2 15.35% against 16.33%) and meetings (LOTUSDIS, a set that favours us). It makes more on TV talk shows (TVSpeech 12.41% against 10.84%), and the two tie on the Isan dialect. Decode whole recordings in pieces cut at pauses, as the included server does; the "Whole recordings" tab shows why.
Run it
- NeMo, files
- Server, live streams
- ONNX, on a CPU
Install NVIDIA NeMo (Speech) as the model card describes, then decode a list of 16 kHz mono files with NeMo's streaming script. This is how every number on this page was measured.
hf download iapp/OpenThai2.0-ASR-Streaming --local-dir OpenThai2.0-ASR-Streaming
echo '{"audio_filepath": "a.wav", "duration": 8.8, "text": ""}' > in.jsonl
python <NeMo Speech>/examples/asr/asr_cache_aware_streaming/speech_to_text_cache_aware_streaming_infer.py \
model_path=OpenThai2.0-ASR-Streaming/openthai2.0-asr-streaming_bias-1.0.nemo \
dataset_manifest=in.jsonl output_path=out att_context_size="[56,6]" \
target_lang=th-TH strip_lang_tags=true rnnt_decoding.greedy.max_symbols_per_step=2
att_context_size sets the latency: [56,0] 80 ms, [56,3] 320 ms, [56,6] 560 ms, [56,13] 1120 ms. target_lang=th-mix writes English words in Latin letters.
The repository includes a small server: POST /v1/transcribe for files and a WebSocket, /v1/live, for live audio of any length, which it cuts at pauses (/v1/stream takes one short utterance), with modes for standard speech, conversation and meetings.
cd OpenThai2.0-ASR-Streaming/serve
CHINDA_DEVICE=cuda python -m uvicorn app:app --port 18081
curl -F file=@a.wav -F mode=conversation http://127.0.0.1:18081/v1/transcribe
The WebSocket takes 16 kHz 16-bit mono PCM and answers with the text so far, then the final text. The model card has a complete client.
An ONNX export runs with ONNX Runtime alone, on a CPU, with no Python or PyTorch; it is the build Chinda Bot downloads for its microphone button. It comes in full precision (2.45 GB of weights) and int8 (0.88 GB), both at 560 ms. For full precision:
hf download iapp/OpenThai2.0-ASR-Streaming-ONNX encoder.onnx.data openthai2.0-asr-streaming-fp32.asr.zip --local-dir OpenThai2.0-ASR-Streaming-ONNX
cd OpenThai2.0-ASR-Streaming-ONNX && unzip openthai2.0-asr-streaming-fp32.asr.zip
The full-precision files give the same text as the model above, token for token, on the clips we checked, and on an Apple M3 Max CPU they read 3.5 seconds of speech in 0.16 seconds. The int8 files have not been measured on real speech; use full precision when in doubt. The repository's card describes the encoder's and the decoder's inputs and outputs, for writing your own decoding loop.
Tested with NeMo Speech cf724ac, PyTorch 2.13 and Python 3.12.
Prefer a hosted service? OpenThai ASR Realtime runs this model behind a WebSocket API, and Chinda ASR Pro v2 is iApp's more accurate service for recordings.
Limits
- Long recordings. Decoded as one stream, it drops words after quiet pauses. TVSpeech's videos, rebuilt with one second of silence between clips, score 23.54% that way and 12.66% cut at pauses. The included server cuts at pauses for you.
- TV and YouTube talk. Typhoon ASR Streaming 0.6B is more accurate on TVSpeech. Part of the gap is hesitation sounds such as เอ่อ, which TVSpeech's transcripts keep and this model leaves out; most of the rest is English words.
- English words. With
th-THthey come out in Thai script. Withth-mix, 13.7% of TVSpeech's English words come out in Latin letters, against 16.1% for Typhoon ASR Streaming 0.6B. - Dialects. Central Thai only. On Isan it gets 34.9% of characters wrong, about the same as Typhoon ASR Streaming 0.6B.
- Distance from the microphone. On LOTUSDIS meetings at 1120 ms, the conference microphone gives 20.3% errors and the far channels bt3m and bt10m 56.5% and 53.5%.
- Not measured: telephone audio (8 kHz). Not included: a custom vocabulary for names.
Training
12,373 hours of Thai speech and 961 hours of English. 10,400 of the Thai hours are YouTube audio from the GigaSpeech2 training split, with its automatic transcripts; the rest is human-transcribed: the Thai Dialect Corpus (Central Thai only), iApp's own recordings, Common Voice, WanJuan-SiLu, THAI SER, LOTUSDIS, the Som TTS dataset, NECTEC's LOTUS and TSync, Thai Elderly Speech, Gowajee and the FLEURS training splits. NVIDIA's tokenizer was extended with Thai pieces and the decoder was trained afresh on it, starting from NVIDIA's encoder. 115,000 optimizer steps saw about 30,700 hours of audio. Every setting, including the blank offset stored in the released file, was chosen on development sets; no clip of any test set above was trained on. The sources, hours and recipe are in the model card.
Licence
OpenMDW License Agreement, version 1.1, the licence of its base model. OpenThai 2.0 ASR Streaming is a Thai fine-tune of NVIDIA Nemotron 3.5 ASR Streaming 0.6B; NVIDIA's licence and original model card are included unchanged in the repository.
Built on NVIDIA Nemotron.
Built by iApp Technology. Trained and evaluated on NVIDIA H100 GPUs provided by Siam AI Corporation.