yacht commited on
Commit
0a9a98f
·
verified ·
1 Parent(s): a6b7a6c

Model card; benchmark outputs and scorer; serve/: long recordings cut at pauses, WS /v1/live

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. README.md +279 -1
  2. benchmark/README.md +47 -0
  3. benchmark/chinda_norm.py +114 -0
  4. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_fleurs.jsonl +0 -0
  5. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_gs2.jsonl +0 -0
  6. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_gs2_long.jsonl +0 -0
  7. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_isan.jsonl +0 -0
  8. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_bt10m.jsonl +0 -0
  9. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_bt3m.jsonl +0 -0
  10. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_con123.jsonl +0 -0
  11. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_jbl.jsonl +0 -0
  12. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_lav123.jsonl +0 -0
  13. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_tv_long.jsonl +0 -0
  14. benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_tvspeech.jsonl +0 -0
  15. benchmark/hypotheses/openthai2.0-asr-streaming_320ms_fleurs.jsonl +0 -0
  16. benchmark/hypotheses/openthai2.0-asr-streaming_320ms_gs2.jsonl +0 -0
  17. benchmark/hypotheses/openthai2.0-asr-streaming_320ms_isan.jsonl +0 -0
  18. benchmark/hypotheses/openthai2.0-asr-streaming_320ms_lotus_con123.jsonl +0 -0
  19. benchmark/hypotheses/openthai2.0-asr-streaming_320ms_tvspeech.jsonl +0 -0
  20. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_fleurs.jsonl +0 -0
  21. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_gs2.jsonl +0 -0
  22. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_gs2_long.jsonl +0 -0
  23. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_gs2_long_split.jsonl +0 -0
  24. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_isan.jsonl +0 -0
  25. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_lotus_con123.jsonl +0 -0
  26. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_tv_long.jsonl +0 -0
  27. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_tv_long_split.jsonl +0 -0
  28. benchmark/hypotheses/openthai2.0-asr-streaming_560ms_tvspeech.jsonl +0 -0
  29. benchmark/hypotheses/openthai2.0-asr-streaming_80ms_fleurs.jsonl +0 -0
  30. benchmark/hypotheses/openthai2.0-asr-streaming_80ms_gs2.jsonl +0 -0
  31. benchmark/hypotheses/openthai2.0-asr-streaming_80ms_isan.jsonl +0 -0
  32. benchmark/hypotheses/openthai2.0-asr-streaming_80ms_lotus_con123.jsonl +0 -0
  33. benchmark/hypotheses/openthai2.0-asr-streaming_80ms_tvspeech.jsonl +0 -0
  34. benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_1120ms_lotus_con123.jsonl +0 -0
  35. benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_1120ms_tvspeech.jsonl +0 -0
  36. benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_560ms_lotus_con123.jsonl +0 -0
  37. benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_560ms_tvspeech.jsonl +0 -0
  38. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_fleurs.jsonl +0 -0
  39. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_gs2.jsonl +0 -0
  40. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_gs2_long.jsonl +0 -0
  41. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_isan.jsonl +0 -0
  42. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_bt10m.jsonl +0 -0
  43. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_bt3m.jsonl +0 -0
  44. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_con123.jsonl +0 -0
  45. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_jbl.jsonl +0 -0
  46. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_lav123.jsonl +0 -0
  47. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_tv_long.jsonl +0 -0
  48. benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_tvspeech.jsonl +0 -0
  49. benchmark/hypotheses/typhoon-asr-streaming-0.6b_320ms_fleurs.jsonl +0 -0
  50. benchmark/hypotheses/typhoon-asr-streaming-0.6b_320ms_gs2.jsonl +0 -0
README.md CHANGED
@@ -2,8 +2,21 @@
2
  license: other
3
  license_name: openmdw-1.1
4
  license_link: https://openmdw.ai/license/1-1/
 
5
  language:
6
  - th
 
 
 
 
 
 
 
 
 
 
 
 
7
  extra_gated_heading: "Register to download OpenThai2.0-ASR-Streaming · ลงทะเบียนเพื่อดาวน์โหลด"
8
  extra_gated_description: "Free. Fill in the form once and access is granted at once. · ดาวน์โหลดฟรี กรอกแบบฟอร์มครั้งเดียว ได้รับสิทธิ์ทันที"
9
  extra_gated_prompt: >-
@@ -36,4 +49,269 @@ extra_gated_button_content: "Submit · ส่งข้อมูล"
36
 
37
  # OpenThai2.0-ASR-Streaming
38
 
39
- Model card in preparation.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  license: other
3
  license_name: openmdw-1.1
4
  license_link: https://openmdw.ai/license/1-1/
5
+ base_model: nvidia/nemotron-3.5-asr-streaming-0.6b
6
  language:
7
  - th
8
+ - en
9
+ library_name: nemo
10
+ pipeline_tag: automatic-speech-recognition
11
+ tags:
12
+ - automatic-speech-recognition
13
+ - speech
14
+ - streaming
15
+ - Thai
16
+ - FastConformer
17
+ - Transducer
18
+ - NeMo
19
+ - Nemotron
20
  extra_gated_heading: "Register to download OpenThai2.0-ASR-Streaming · ลงทะเบียนเพื่อดาวน์โหลด"
21
  extra_gated_description: "Free. Fill in the form once and access is granted at once. · ดาวน์โหลดฟรี กรอกแบบฟอร์มครั้งเดียว ได้รับสิทธิ์ทันที"
22
  extra_gated_prompt: >-
 
49
 
50
  # OpenThai2.0-ASR-Streaming
51
 
52
+ Streaming Thai speech-to-text with 0.64B parameters. It writes Thai speech down while people are still talking, 80 to 1120 ms behind the voice, from one model with four latency settings. It is a Thai fine-tune of NVIDIA **Nemotron 3.5 ASR Streaming 0.6B**, made by iApp Technology, and it is the model behind iApp's hosted [OpenThai ASR Realtime](https://iapp.co.th/docs/speech/speech-to-text/realtime) service.
53
+
54
+ **Built on NVIDIA Nemotron.** The base model is NVIDIA's [`nvidia/nemotron-3.5-asr-streaming-0.6b`](https://huggingface.co/nvidia/nemotron-3.5-asr-streaming-0.6b), released under the OpenMDW License Agreement, version 1.1. That licence is included as [`LICENSE`](LICENSE), and NVIDIA's original model card and sub-cards are kept unchanged in [`nvidia/`](nvidia/).
55
+
56
+ | | |
57
+ |---|---|
58
+ | Architecture | Cache-aware streaming FastConformer encoder + RNN-Transducer decoder, prompt-conditioned (NeMo `EncDecRNNTBPEModelWithPrompt`) |
59
+ | Parameters | 640.4 million |
60
+ | Latency settings | 80, 320, 560 and 1120 ms (`att_context_size` `[56,0]`, `[56,3]`, `[56,6]`, `[56,13]`), chosen at decode time |
61
+ | Language prompts | `th-TH`: everything in Thai script. `th-mix`: English words in Latin letters |
62
+ | Tokenizer | 14,988 pieces: NVIDIA's 13,087 multilingual pieces and 1,901 new Thai pieces |
63
+ | Training data | 12,373 hours of Thai speech and 961 hours of English (LibriSpeech) |
64
+ | Licence | OpenMDW-1.1 |
65
+
66
+ ## Results
67
+
68
+ ![OpenThai2.0-ASR-Streaming against Typhoon ASR Streaming 0.6B (as released and with its 4-gram LM) and the Nemotron base: average character error rate and FLEURS, GigaSpeech2, TVSpeech, LOTUSDIS and Isan at 560 ms](https://huggingface.co/datasets/iapp/OpenThai2.0-model-card-assets/resolve/main/openthai2-asr-streaming-benchmark.png)
69
+
70
+ We compared it with [Typhoon ASR Streaming 0.6B](https://huggingface.co/typhoon-ai/typhoon-asr-streaming-nemotron-0.6b), the other open Thai model built on the same NVIDIA base. We decoded both ourselves, on public test sets, with the same script and settings.
71
+
72
+ - At 560 ms this model makes fewer errors on read speech (FLEURS: 8.47% of characters wrong, against 11.28%), on YouTube clips (GigaSpeech2: 15.35% against 16.33%) and in meetings (LOTUSDIS: 20.77% against 28.91%, a set that favours us).
73
+ - Typhoon makes fewer errors on TV talk shows (TVSpeech, its own benchmark: 10.84% against 12.41%). The two tie on the Isan dialect.
74
+ - Typhoon's 4-gram language model raises its English-word recall, as its card says, but adds errors on every set here.
75
+ - On whole recordings, decode in pieces cut at pauses, as the included server does. Decoded as one stream, this model drops words after quiet pauses.
76
+
77
+ **560 ms** (`att_context_size` `[56,6]`), character error rate in %, lower is better:
78
+
79
+ | test set | size | OpenThai2.0-ASR-Streaming | Typhoon ASR Streaming 0.6B | Typhoon + its 4-gram LM | ours − Typhoon, 95% interval |
80
+ |---|---|---:|---:|---:|---|
81
+ | FLEURS test, read speech | 1,021 clips | **8.47** | 11.28 | 11.73 | −2.82 [−3.15, −2.48], ours lower |
82
+ | GigaSpeech2 test, YouTube | 8,823 clips, 32 recordings | **15.35** | 16.33 | 16.62 | −0.98 [−1.31, −0.58], ours lower |
83
+ | TVSpeech, TV and YouTube talk | 570 clips, 18 videos | 12.41 | **10.84** | 11.05 | +1.57 [+0.90, +2.52], Typhoon lower |
84
+ | LOTUSDIS meetings, conference microphone ¹ | 5,516 turns, 11 meetings | **20.77** | 28.91 | 29.02 | −8.15 [−8.88, −7.46], ours lower |
85
+ | Isan dialect | 500 clips | 34.90 | 34.15 | 35.79 | +0.75 [−0.21, +1.69], tie |
86
+
87
+ **1120 ms** (`att_context_size` `[56,13]`), character error rate in %, lower is better:
88
+
89
+ | test set | size | OpenThai2.0-ASR-Streaming | Typhoon ASR Streaming 0.6B | Typhoon + its 4-gram LM | ours − Typhoon, 95% interval |
90
+ |---|---|---:|---:|---:|---|
91
+ | FLEURS test, read speech | 1,021 clips | **8.36** | 11.32 | 11.64 | −2.96 [−3.31, −2.65], ours lower |
92
+ | GigaSpeech2 test, YouTube | 8,823 clips, 32 recordings | **15.23** | 16.18 | 16.44 | −0.95 [−1.35, −0.49], ours lower |
93
+ | TVSpeech, TV and YouTube talk | 570 clips, 18 videos | 12.14 | **10.70** | 11.18 | +1.45 [+0.77, +2.46], Typhoon lower |
94
+ | LOTUSDIS meetings, conference microphone ¹ | 5,516 turns, 11 meetings | **20.30** | 28.23 | 28.64 | −7.93 [−8.66, −7.24], ours lower |
95
+ | Isan dialect | 500 clips | 34.49 | 33.73 | 35.68 | +0.76 [−0.28, +1.86], tie |
96
+
97
+ Bold: lower than the other model in that row with 95% confidence (paired bootstrap, see below).
98
+
99
+ **Whole recordings**, 560 ms. Each file joins every clip of one video or recording, in order, with one second of silence between clips. *One stream* decodes the file in one pass, as NeMo's script does; *cut at pauses* decodes it the way [`serve/`](serve/) does, in pieces cut where nobody speaks for 0.7 s, each decoded on its own (both models through the same code, Typhoon at its released settings).
100
+
101
+ | test set | size | one stream: ours | one stream: Typhoon | ours − Typhoon, 95% interval | cut at pauses: ours | cut at pauses: Typhoon | ours − Typhoon, 95% interval |
102
+ |---|---|---:|---:|---|---:|---:|---|
103
+ | TVSpeech, whole videos (0.5–47 min) | 18 files | 23.54 | **11.07** | +12.47 [+7.49, +17.08], Typhoon lower | 12.66 | **10.84** | +1.82 [+1.16, +2.74], Typhoon lower |
104
+ | GigaSpeech2 test, whole recordings (5–87 min) ² | 31 files | **23.10** | 30.07 | −6.97 [−12.06, −2.63], ours lower | **13.53** | 14.42 | −0.88 [−1.34, −0.41], ours lower |
105
+
106
+ Decoded as one stream, this model loses words after a pause of near-silence: the longer and quieter the pause, the more it drops (see [Limits](#limits)). Cut at pauses, it comes back near its clip-by-clip error on TVSpeech (12.66 whole against 12.41 clip by clip) and below it on GigaSpeech2 (13.53 against 15.35).
107
+
108
+ **By latency**, character error rate in %, ours / Typhoon (as released):
109
+
110
+ | test set | 80 ms | 320 ms | 560 ms | 1120 ms |
111
+ |---|---:|---:|---:|---:|
112
+ | FLEURS test, read speech | 8.73 / 11.78 | 8.53 / 11.67 | 8.47 / 11.28 | 8.36 / 11.32 |
113
+ | GigaSpeech2 test, YouTube | 16.64 / 17.75 | 15.53 / 16.64 | 15.35 / 16.33 | 15.23 / 16.18 |
114
+ | TVSpeech, TV and YouTube talk | 13.06 / 11.44 | 12.54 / 10.84 | 12.41 / 10.84 | 12.14 / 10.70 |
115
+ | LOTUSDIS meetings, conference microphone | 26.12 / 34.35 | 21.79 / 29.49 | 20.77 / 28.91 | 20.30 / 28.23 |
116
+ | Isan dialect | 35.84 / 35.37 | 34.72 / 34.65 | 34.90 / 34.15 | 34.49 / 33.73 |
117
+
118
+ **Typhoon with a tuned blank offset.** Our released file stores a blank offset of −1.0, chosen on a development set. Typhoon's best offset on the same development set is −2.0. With it, at 560 ms:
119
+
120
+ | test set | ours | Typhoon, offset −2.0 | ours − Typhoon, 95% interval |
121
+ |---|---:|---:|---|
122
+ | FLEURS test, read speech | 8.47 | 11.63 | −3.17 [−3.50, −2.83], ours lower |
123
+ | GigaSpeech2 test, YouTube | 15.35 | 15.26 | +0.10 [−0.38, +0.63], tie |
124
+ | TVSpeech, TV and YouTube talk | 12.41 | 10.68 | +1.73 [+1.14, +2.61], Typhoon lower |
125
+ | LOTUSDIS meetings, conference microphone | 20.77 | 26.71 | −5.94 [−6.50, −5.41], ours lower |
126
+ | Isan dialect | 34.90 | 33.87 | +1.03 [+0.24, +1.91], Typhoon lower |
127
+
128
+ **English words** on TVSpeech at 560 ms: the share of the reference's English words written in Latin letters (recall), the share of written English words that are right (precision), and their F1; exact match, ignoring case.
129
+
130
+ | | recall | precision | F1 |
131
+ |---|---:|---:|---:|
132
+ | ours, `th-mix` | 13.7 | 22.6 | 17.0 |
133
+ | ours, `th-TH` | 0.5 | 75.0 | 0.9 |
134
+ | Typhoon | 16.1 | 30.6 | 21.1 |
135
+ | Typhoon + 4-gram | 18.9 | 29.0 | 22.9 |
136
+
137
+ **By the method of the public Thai ASR Leaderboard** (pilot 2026.10: spoken-form normalisation, six weighted groups), 1120 ms. This is our own measurement, not an entry on that board.
138
+
139
+ | | FLEURS | Isan | TVSpeech | GigaSpeech2 | close mics | far mics | weighted |
140
+ |---|---:|---:|---:|---:|---:|---:|---:|
141
+ | OpenThai2.0-ASR-Streaming | 8.29 | 33.85 | 11.90 | 15.08 | 22.44 | 54.99 | 22.15 |
142
+ | Typhoon ASR Streaming 0.6B | 11.20 | 33.30 | 10.59 | 16.18 | 30.72 | 72.11 | 26.25 |
143
+ | Typhoon + 4-gram | 11.54 | 35.26 | 11.07 | 16.44 | 31.07 | 73.05 | 26.91 |
144
+
145
+ How we measured:
146
+ - Every model was decoded by us with NeMo's cache-aware streaming script (`speech_to_text_cache_aware_streaming_infer.py`), greedy, `max_symbols_per_step=2`, prompt `th-TH` (with NeMo's default of 10 instead, Typhoon's error moves by at most 0.06 points on FLEURS, TVSpeech and GigaSpeech2). Typhoon is [`typhoon-ai/typhoon-asr-streaming-nemotron-0.6b`](https://huggingface.co/typhoon-ai/typhoon-asr-streaming-nemotron-0.6b) as released, and with its paired 4-gram ([`...-0.6b-ngram`](https://huggingface.co/typhoon-ai/typhoon-asr-streaming-nemotron-0.6b-ngram), weight 0.5, as its card says).
147
+ - Both sides are normalised the same way before scoring: Thai digits and spoken numbers made equal, spaces removed; then true edit distance over all characters of a set.
148
+ - Intervals are 95% paired bootstrap intervals that resample whole videos (TVSpeech), recordings (GigaSpeech2), speakers (Isan), meetings (LOTUSDIS) or files (joined sets). An interval that includes zero is a tie.
149
+ - Latency is the audio chunk the model waits for, (right context + 1) × 80 ms. Typhoon's card counts only the look-ahead, so its "1040 ms" is the 1120 ms setting here.
150
+ - ¹ We trained on other LOTUSDIS meetings from the same rooms and microphones, and some speakers appear in both, so that row favours us. TVSpeech is Typhoon's own benchmark. We trained on FLEURS's training and development splits, not its test split. Both models trained on GigaSpeech2's training split.
151
+ - ² GigaSpeech2 test recording 26 is left out of the joined set: its transcripts do not match its audio (about 70% errors for every model). It stays in the 8,823-clip set above, as published.
152
+
153
+ ## Use
154
+
155
+ There are two files. Use the first unless you run the reference server.
156
+
157
+ | file | for |
158
+ |---|---|
159
+ | `openthai2.0-asr-streaming_bias-1.0.nemo` | NeMo's streaming script and your own code. The blank offset −1.0 that every number above uses is stored in the file. |
160
+ | `openthai2.0-asr-streaming_raw.nemo` | The reference server in [`serve/`](serve/), which sets the blank offset per mode itself. |
161
+
162
+ Both need NVIDIA NeMo (Speech) with cache-aware streaming and `EncDecRNNTBPEModelWithPrompt`. We tested NeMo Speech at commit `cf724ac`, PyTorch 2.13 and Python 3.12:
163
+
164
+ ```bash
165
+ uv venv asr --python 3.12 && source asr/bin/activate
166
+ uv pip install torch==2.13.0 --index-url https://download.pytorch.org/whl/cu130 # or the CPU wheel
167
+ uv pip install Cython packaging
168
+ uv pip install --extra-index-url https://download.pytorch.org/whl/cu130 --index-strategy unsafe-best-match \
169
+ "nemo-toolkit[asr] @ git+https://github.com/NVIDIA-NeMo/Speech.git@cf724ac337d1ebc7d0dda1e23fb80916f52927a5"
170
+ hf download iapp/OpenThai2.0-ASR-Streaming --local-dir OpenThai2.0-ASR-Streaming
171
+ ```
172
+
173
+ ### Transcribe files with NeMo's streaming script
174
+
175
+ This is exactly how every benchmark number on this page was produced. Audio must be 16 kHz mono.
176
+
177
+ ```bash
178
+ echo '{"audio_filepath": "a.wav", "duration": 8.8, "text": ""}' > in.jsonl # one line per file
179
+ python <NeMo Speech>/examples/asr/asr_cache_aware_streaming/speech_to_text_cache_aware_streaming_infer.py \
180
+ model_path=OpenThai2.0-ASR-Streaming/openthai2.0-asr-streaming_bias-1.0.nemo \
181
+ dataset_manifest=in.jsonl output_path=out batch_size=32 \
182
+ att_context_size="[56,6]" target_lang=th-TH strip_lang_tags=true \
183
+ rnnt_decoding.greedy.max_symbols_per_step=2
184
+ # result: out/streaming_out_*.json, one line per file, field "pred_text"
185
+ ```
186
+
187
+ - `att_context_size`: `[56,0]` 80 ms, `[56,3]` 320 ms, `[56,6]` 560 ms, `[56,13]` 1120 ms.
188
+ - `target_lang`: `th-TH`, or `th-mix` to write English words in Latin letters.
189
+ - `max_symbols_per_step=2` stops rare repetition loops at no cost in accuracy.
190
+ - **The script decodes each file as one stream.** Cut long recordings at pauses first, or use the reference server below, which does it for you. In one stream, a pause of near-silence makes the model drop some of the speech that follows (see [Limits](#limits)).
191
+ - Use `dataset_manifest=`; with `audio_file=` this NeMo commit prints the text and then stops with an error.
192
+ - Do not use NeMo's `model.transcribe()` for this model: at this commit its data loader ignores `target_lang`, so it stops with `Unknown prompt key: 'None'`, and its default prompt mode would use the language-agnostic prompt for about half of the clips.
193
+
194
+ ### Reference server: files and live streams
195
+
196
+ [`serve/`](serve/) is a small FastAPI service around the model: `POST /v1/transcribe` for files and `WS /v1/live` for live audio, with three modes and optional speaker labels. It runs on a GPU or a CPU. Both cut long audio at pauses, the way iApp's hosted service does. A file longer than 30 seconds is cut where nobody speaks for 0.7 s and each piece is decoded on its own; the response lists them in `segments`. The exception is a file with speaker labels, which is still decoded as one stream. A live stream sends a final text each time the speaker pauses.
197
+
198
+ ```bash
199
+ uv pip install fastapi uvicorn python-multipart websockets
200
+ cd OpenThai2.0-ASR-Streaming/serve
201
+ CHINDA_DEVICE=cuda CHINDA_PRELOAD=1 python -m uvicorn app:app --port 18081 # CPU: leave out CHINDA_DEVICE
202
+ curl -F file=@a.wav -F mode=standard http://127.0.0.1:18081/v1/transcribe
203
+ ```
204
+
205
+ | `mode` | for | what it does |
206
+ |---|---|---|
207
+ | `standard` (default) | read speech, news, lectures, dictation | blank offset −1.0; clips under 2 s decoded again at −2.5; empty output decoded again at −4.0 |
208
+ | `conversation` | YouTube, social media, casual talk | blank offset −2.0; empty output decoded again at −4.0 |
209
+ | `meeting` | several people in a room | blank offset −1.0, and speaker labels from [`nvidia/Nemotron-3-Diarization`](https://huggingface.co/nvidia/Nemotron-3-Diarization) (downloaded on first use) |
210
+
211
+ Other fields: `lang` (`th-TH` or `th-mix`) and `latency_ms` (80, 320, 560 or 1120). Each mode's settings were chosen on development data and then measured once on test data.
212
+
213
+ Live stream over WebSocket (audio as 16 kHz mono 16-bit PCM):
214
+
215
+ ```python
216
+ import json, soundfile as sf
217
+ from websockets.sync.client import connect
218
+ x = sf.read("a.wav", dtype="float32")[0] # 16 kHz mono
219
+ pcm = (x.clip(-1, 1) * 32767).astype("<i2").tobytes() # 16-bit PCM, as a microphone gives it
220
+ with connect("ws://127.0.0.1:18081/v1/live") as ws:
221
+ ws.send(json.dumps({"mode": "standard", "lang": "th-TH", "latency_ms": 560})); ws.recv()
222
+ for i in range(0, len(pcm), 16000): # 0.5 s chunks
223
+ ws.send(pcm[i:i + 16000])
224
+ ws.send("end")
225
+ while (m := json.loads(ws.recv()))["type"] != "done":
226
+ if m["type"] == "partial":
227
+ print("partial:", m["text"]) # the sentence so far
228
+ elif m["type"] == "final":
229
+ print("final:", m["display_text"]) # one per pause
230
+ ```
231
+
232
+ The same code without a server (run inside `serve/`):
233
+
234
+ ```python
235
+ from chinda_asr import ChindaASR, MODES, load_audio
236
+ from chinda_realtime import transcribe_long
237
+ asr = ChindaASR(device="cuda") # or "cpu"
238
+ print(asr.transcribe("a.wav", policy=MODES["conversation"], lang="th-TH")["display_text"]) # a clip
239
+ print(transcribe_long(asr, load_audio("talk.wav"), policy=MODES["standard"])["display_text"]) # a long recording
240
+ ```
241
+
242
+ All fields, environment variables and error codes: [`serve/README.md`](serve/README.md). The service has no authentication; keep it on localhost or behind your own gateway.
243
+
244
+ **Speed.** On one NVIDIA H100, files decode about 257 times faster than real time, and one copy of the model keeps up with about 20 live streams at 560 ms. On a laptop-class CPU with 8 threads, files decode about 4 times faster than real time and live streams keep up at 560 and 320 ms, with about 6.5 GB of memory.
245
+
246
+ ## What the output looks like
247
+
248
+ - Thai words are not separated by spaces, and there is almost no punctuation.
249
+ - Numbers usually come out as digits.
250
+ - Hesitation sounds such as เอ่อ and อ่า are usually left out, and so are words a speaker repeats.
251
+ - With `th-mix`, English words a speaker says are written in Latin letters (`online`, `GDP`); with `th-TH` they are written in Thai script.
252
+
253
+ ## Training
254
+
255
+ **Data.** 12,373 hours of Thai speech and 961 hours of English.
256
+
257
+ | source | hours | transcripts |
258
+ |---|---:|---|
259
+ | [GigaSpeech2](https://huggingface.co/datasets/speechcolab/gigaspeech2), Thai training split, YouTube | 10,400 | automatic (GigaSpeech2's own) |
260
+ | [Thai Dialect Corpus (Porjai)](https://github.com/SLSCU/thai-dialect-corpus), Central Thai only | 695 | human |
261
+ | iApp's own recordings: podcasts, talk shows, live streams and voice-actor recordings | 446 | human |
262
+ | [Common Voice](https://commonvoice.mozilla.org/th), Thai | 408 | human |
263
+ | WanJuan-SiLu, Thai | 201 | human |
264
+ | THAI SER (VISTEC-depa) | 86 | human |
265
+ | [LOTUSDIS](https://arxiv.org/abs/2509.18722), training split | 64 | human |
266
+ | [PyThaiNLP Som TTS dataset](https://huggingface.co/datasets/pythainlp/som_tts_dataset) | 21 | human |
267
+ | NECTEC LOTUS, TSync-1 and TSync-2 | 17 | human |
268
+ | [Thai Elderly Speech](https://github.com/VISAI-DATAWOW/Thai-Elderly-Speech-dataset) | 14 | human |
269
+ | [Gowajee](https://github.com/ekapolc/gowajee_corpus) | 14 | human |
270
+ | [FLEURS](https://huggingface.co/datasets/google/fleurs), Thai training and development splits | 8 | human |
271
+ | [LibriSpeech](https://www.openslr.org/12), English | 961 | human |
272
+
273
+ - The `th-mix` prompt was trained on the same Thai audio, with Thai-script spellings of English words changed to Latin letters by a language model whose every edit was checked character by character against the original transcript.
274
+ - No clip of any test set above was used in training.
275
+ - It is a Central Thai model: the Thai Dialect Corpus's Korat, Kham Mueang and Pattani Malay splits were left out on purpose.
276
+
277
+ **Recipe.**
278
+ - NVIDIA's tokenizer was extended with Thai pieces, and the decoder and joint network were trained from scratch on the new vocabulary; the encoder and the language-prompt layer start from NVIDIA's weights.
279
+ - 115,000 optimizer steps of 960 seconds of audio each (about 30,700 hours of audio seen), AdamW, cosine learning-rate schedule, 32-bit precision, FastEmit λ 0.01:
280
+ - 79,000 steps at peak learning rate 1e-3 (5,000 warm-up steps);
281
+ - 4,000 steps at 1e-4 on a mix weighted towards conversational speech;
282
+ - 20,000 steps at 1e-4 that add the `th-mix` prompt;
283
+ - three further 4,000-step passes at 1e-4 that refine conversational speech and the English word list.
284
+ - The blank offset −1.0 and every mode's setting were chosen on development sets, never on the test sets reported above.
285
+
286
+ ## Limits
287
+
288
+ - **Long recordings decoded as one stream.** After a pause of near-silence the model drops some of the speech that follows, and the longer and quieter the pause, the more it drops. We rebuilt TVSpeech's videos by joining their clips, and decoded each file as one stream at 560 ms. With no gap between clips, 13.2% of characters were wrong. Gaps of 0.3, 0.5 and 1 s of silence raised that to 16.3%, 19.2% and 23.5%; 1 s gaps of room-level noise (−50 dB) gave 15.3%. Typhoon gives 11.1% on the same files. Cut recordings at pauses before decoding: the included server and iApp's hosted service do this, and the same files then score 12.66% (Typhoon 10.84%).
289
+ - **Conversational TV and YouTube talk.** On TVSpeech, Typhoon's own benchmark, Typhoon ASR Streaming 0.6B makes fewer errors than this model (10.84% against 12.41% at 560 ms). Hesitation sounds such as เอ่อ explain part of the gap: TVSpeech's transcripts keep them and this model leaves them out, and removing them from both sides shrinks the gap from 1.57 to 1.15 points. The rest is almost all in clips with English words: on the 353 clips without any, the gap is then 0.19 points.
290
+ - **English words.** With `th-TH`, English words come out in Thai script. With `th-mix`, only some come out in Latin letters: 13.7% of the English words in TVSpeech's transcripts at 560 ms, against 16.1% for Typhoon.
291
+ - **Dialects.** It is a Central Thai model. On the Isan test set it gets 34.90% of characters wrong, about the same as Typhoon. We did not train on Isan, and Typhoon's published training data lists none.
292
+ - **Far microphones.** Accuracy falls sharply with distance. On LOTUSDIS meetings at 1120 ms, the conference microphone in the middle of the table gives 20.30% errors, and the two far channels (bt10m and bt3m) 53.49% and 56.50%. Typhoon is worse on all of them (28.23%, 69.81% and 74.41%). Use a microphone near the speakers, or each person's own track.
293
+ - **Very short clips.** Clips under about one second sometimes come out empty. The server's `standard` mode decodes clips under 2 s a second time with a lower blank offset, which fixes most of them.
294
+ - **Telephone audio.** It was not trained on 8 kHz phone audio and we have not measured it there.
295
+ - **Names and rare words.** There is no custom vocabulary in this release; names are spelled from how they sound.
296
+ - **Overlapping speech.** The model writes one stream of text. When two people talk at once, it usually writes only the louder one. Speaker labels in `serve/` come from a separate diarization model and can be wrong on short turns.
297
+
298
+ ## Licence and attribution
299
+
300
+ Released under the **OpenMDW License Agreement, version 1.1** ([`LICENSE`](LICENSE)), the licence of its base model. OpenThai2.0-ASR-Streaming is a Thai fine-tune of NVIDIA Nemotron 3.5 ASR Streaming 0.6B. NVIDIA's original model card and its bias, explainability, privacy and safety sub-cards are in [`nvidia/`](nvidia/), unchanged.
301
+
302
+ - "Nemotron" is a trademark of NVIDIA Corporation, used here only to name the base model. This release is not affiliated with or endorsed by NVIDIA.
303
+ - `serve/chinda_asr.py` adapts the decode loop of NVIDIA NeMo's `speech_to_text_cache_aware_streaming_infer.py` (Apache-2.0).
304
+ - Speaker labels in `serve/` use `nvidia/Nemotron-3-Diarization` (OpenMDW-1.1), which is downloaded from Hugging Face, not redistributed here.
305
+
306
+ Built by iApp Technology. Trained and evaluated on NVIDIA H100 GPUs provided by Siam AI Corporation.
307
+
308
+ ## Citation
309
+
310
+ ```bibtex
311
+ @misc{iapp2026openthaiasrstreaming,
312
+ title = {OpenThai2.0-ASR-Streaming: streaming Thai speech recognition},
313
+ author = {{iApp Technology}},
314
+ year = {2026},
315
+ url = {https://huggingface.co/iapp/OpenThai2.0-ASR-Streaming}
316
+ }
317
+ ```
benchmark/README.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Benchmark outputs and scorer
2
+
3
+ Every number on the model card can be checked from this folder. We decoded every system ourselves, and here are the per-clip outputs and the scorer we used.
4
+
5
+ ## What is here
6
+
7
+ | path | contents |
8
+ |---|---|
9
+ | `hypotheses/<system>_<ms>ms_<set>.jsonl` | one line per clip: `{"id", "pred_text"}`, the system's output |
10
+ | `hypotheses/<system>_560ms_<set>_split.jsonl` | the joined long recordings (`tv_long`, `gs2_long`) decoded in pieces cut at pauses, as `serve/` does (`chinda_realtime.transcribe_long`), both models through the same code |
11
+ | `ids/<set>.jsonl` | one line per clip: `{"id", "cluster"}`, the clips of each test set and the group the bootstrap resamples |
12
+ | `make_refs.py` | rebuilds the reference transcripts from the public datasets, keyed by the same ids |
13
+ | `score.py` | character error rate, and the paired difference of two systems with a 95% bootstrap interval |
14
+ | `chinda_norm.py`, `num_norm.py` | the normalisation `score.py` applies to both sides |
15
+
16
+ Systems: `openthai2.0-asr-streaming` (this model, `th-TH` prompt), `openthai2.0-asr-streaming_th-mix` (`th-mix` prompt), `typhoon-asr-streaming-0.6b` (Typhoon ASR Streaming 0.6B as released) and `typhoon-asr-streaming-0.6b_4gram` (the same with its published 4-gram language model, weight 0.5).
17
+
18
+ We do not redistribute the reference transcripts, because the datasets carry their own terms (GigaSpeech2 is gated). `make_refs.py` downloads only the transcript files and writes them in the format `score.py` reads.
19
+
20
+ ## Test sets and ids
21
+
22
+ | set | source | id | cluster |
23
+ |---|---|---|---|
24
+ | `fleurs` | `google/fleurs`, `th_th` test | audio file name | the clip |
25
+ | `tvspeech` | `typhoon-ai/TVSpeech`, test | row index | YouTube video |
26
+ | `gs2` | `speechcolab/gigaspeech2`, Thai test | segment id (`0-0`) | recording |
27
+ | `isan` | `typhoon-ai/thai-dialect-isan-dataset`, test | dataset id | speaker |
28
+ | `lotus_con123`, `lotus_lav123`, `lotus_jbl`, `lotus_bt3m`, `lotus_bt10m` | `nectec/LOTUSDIS`, test: the same 5,516 turns on five devices (conference microphone, lapel microphones, speakerphone and the two far channels) | chunk file name | meeting |
29
+ | `tv_long` | TVSpeech, each video's clips joined in row order with 1 s of silence | video id | the file |
30
+ | `gs2_long` | GigaSpeech2 test, each recording's segments joined in segment order with 1 s of silence; recording 26 left out because its transcripts do not match its audio | recording id | the file |
31
+
32
+ ## Score
33
+
34
+ ```bash
35
+ pip install huggingface_hub pyarrow pythainlp==5.3.5 editdistance
36
+ python make_refs.py --out refs/ # GigaSpeech2: accept its gate on Hugging Face first
37
+ python score.py refs/tvspeech.jsonl hypotheses/openthai2.0-asr-streaming_560ms_tvspeech.jsonl \
38
+ hypotheses/typhoon-asr-streaming-0.6b_560ms_tvspeech.jsonl
39
+ ```
40
+
41
+ With one hypothesis file, `score.py` prints its character error rate. With two, it also prints the difference A − B with a 95% interval from 1,000 bootstrap resamples of whole clusters (seed 1). An interval that includes zero is a tie.
42
+
43
+ `make_refs.py` cleans the FLEURS and GigaSpeech2 transcripts the way our benchmark references were cleaned when we built them: ASCII punctuation except `?` and `!` removed (decimal points too), curly quotes, dashes and `…` removed, lower case, and PyThaiNLP's `normalize`. The other sets are used as published.
44
+
45
+ Normalisation in `score.py`, the same for reference and output: Thai digits become Arabic digits, curly quotes become straight ones, `ำ` is decomposed, spoken Thai numbers become digits (on whole words found by PyThaiNLP's `newmm`), and then every space is removed. The error rate is the edit distance over all characters of a set, divided by the number of reference characters.
46
+
47
+ To score the joined long recordings with your own system, build the audio the same way: the clips of one video or recording, in order, with exactly one second of digital silence between them, 16 kHz mono.
benchmark/chinda_norm.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """ChindaASR v1 frozen text normalizer (2026-09-01).
3
+
4
+ Apply IDENTICALLY to training targets and every CER reference at scoring time.
5
+ Verified against the stock nemotron-3.5-asr-streaming-0.6b SentencePiece tokenizer
6
+ (data/tokenizer/tokenizer.model, vocab 13087, unk_id 0, nmt_nfkc):
7
+ - Arabic digits 0-9 encode WITHOUT <unk> -> Thai digits are mapped, not verbalized.
8
+ - nmt_nfkc decomposes U+0E33 (sara am) -> U+0E4D U+0E32 (nikhahit + sara aa),
9
+ matching unicodedata.normalize('NFKC', 'ำ'). We pre-decompose so text round-trips.
10
+ - Corpus chars that encode to <unk> (from full-corpus scan, see DATA_REPORT.md):
11
+ Thai digits U+0E50-0E59 (mapped to 0-9); ฯ ฦ ๎ ( ) : % ` / Gujarati ન ા and
12
+ invalid Thai codepoints U+0E00,0E3B,0E3C,0E3E,0E61,0E69,0E6A (all dropped).
13
+ """
14
+ import re
15
+ import unicodedata
16
+
17
+ THAI_DIGITS = {ord('๐') + i: str(i) for i in range(10)} # U+0E50..U+0E59 -> 0..9
18
+
19
+ CHAR_MAP = {
20
+ '‘': "'", '’': "'", # curly single quotes -> ASCII
21
+ '“': '"', '”': '"', # curly double quotes -> ASCII
22
+ '–': '-', '—': '-', '―': '-', # en/em/horizontal dash -> hyphen
23
+ '฿': 'บาท', # ฿ -> baht (spoken form)
24
+ 'ำ': 'ํา', # ำ -> ํ + า (matches tokenizer nmt_nfkc)
25
+ 'เเ': 'แ', # เเ -> แ (handled via str.replace below)
26
+ }
27
+
28
+ # Corpus characters that encode to <unk> under the stock tokenizer: DROP.
29
+ # (Decided per char; all are non-lexical or garbage. Counts logged by build script.)
30
+ UNK_DROP = set(
31
+ 'ฯฦ๎' # paiyannoi, lu, yamakkan
32
+ '():%`/' # ASCII punctuation absent from the vocab
33
+ '฀฻฼฾๡๩๪' # invalid Thai codepoints
34
+ 'ના' # stray Gujarati
35
+ )
36
+
37
+ ZERO_WIDTH = set('​‌‍⁠­')
38
+
39
+ _WS = re.compile(r'\s+')
40
+
41
+ def _is_thai(ch: str) -> bool:
42
+ return 'ก' <= ch <= '๛'
43
+
44
+ def normalize(text: str, lang: str = 'th') -> str:
45
+ """Frozen ChindaASR v1 normalizer. lang='en' skips Thai-specific rules."""
46
+ # 1. NFC + strip zero-width
47
+ t = unicodedata.normalize('NFC', text)
48
+ t = ''.join(c for c in t if c not in ZERO_WIDTH)
49
+ # 2. curly quotes/dashes -> ASCII (both langs)
50
+ for k in ('‘', '’', '“', '”', '–', '—', '―'):
51
+ t = t.replace(k, CHAR_MAP[k])
52
+ if lang.startswith('th'):
53
+ # 3. เเ -> แ
54
+ t = t.replace('เเ', 'แ')
55
+ # 4. Thai digits -> Arabic
56
+ t = t.translate(THAI_DIGITS)
57
+ # 5. ฿ -> บาท
58
+ t = t.replace('฿', 'บาท')
59
+ # 6. decompose sara am (ำ -> ํา) to match tokenizer nmt_nfkc
60
+ t = t.replace('ำ', 'ํา')
61
+ # 7. drop chars that are <unk> under the stock tokenizer
62
+ t = ''.join(c for c in t if c not in UNK_DROP)
63
+ # 8. lowercase Latin
64
+ t = t.lower()
65
+ # 9. collapse whitespace
66
+ t = _WS.sub(' ', t).strip()
67
+ if lang.startswith('th'):
68
+ # 10. delete spaces flanked by Thai chars on BOTH sides; keep Latin/digit spacing
69
+ out = []
70
+ n = len(t)
71
+ for i, c in enumerate(t):
72
+ if c == ' ' and 0 < i < n - 1 and _is_thai(t[i - 1]) and _is_thai(t[i + 1]):
73
+ continue
74
+ out.append(c)
75
+ t = ''.join(out)
76
+ t = _WS.sub(' ', t).strip()
77
+ return t
78
+
79
+
80
+ class RoundTripChecker:
81
+ """Assert normalized text encodes with ZERO <unk> and decodes back to itself."""
82
+ def __init__(self, model_file: str):
83
+ import sentencepiece as spm
84
+ self.sp = spm.SentencePieceProcessor(model_file=model_file)
85
+ self.unk = self.sp.unk_id()
86
+
87
+ def check(self, normalized_text: str):
88
+ ids = self.sp.encode(normalized_text)
89
+ has_unk = self.unk in ids
90
+ decoded = self.sp.decode(ids)
91
+ return (not has_unk) and decoded == normalized_text, ids
92
+
93
+ def assert_ok(self, normalized_text: str):
94
+ ok, ids = self.check(normalized_text)
95
+ if not ok:
96
+ bad = [self.sp.id_to_piece(i) for i in ids]
97
+ raise AssertionError(f'round-trip failed for {normalized_text!r}: {bad}')
98
+ return ids
99
+
100
+
101
+ if __name__ == '__main__':
102
+ import sys
103
+ tests = [
104
+ ('น้ำเเข็ง ๕๐ ฿', 'th'),
105
+ ('สวัสดี ครับ hello World 123', 'th'),
106
+ ('ฯลฯ ทดสอบ​', 'th'),
107
+ ("“Quoted” — dashed", 'en'),
108
+ ]
109
+ for s, lg in tests:
110
+ print(repr(s), '->', repr(normalize(s, lg)))
111
+ if len(sys.argv) > 1:
112
+ rt = RoundTripChecker(sys.argv[1])
113
+ for s, lg in tests:
114
+ print(repr(normalize(s, lg)), rt.check(normalize(s, lg))[0])
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_fleurs.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_gs2.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_gs2_long.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_isan.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_bt10m.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_bt3m.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_con123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_jbl.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_lotus_lav123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_tv_long.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_1120ms_tvspeech.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_320ms_fleurs.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_320ms_gs2.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_320ms_isan.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_320ms_lotus_con123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_320ms_tvspeech.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_fleurs.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_gs2.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_gs2_long.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_gs2_long_split.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_isan.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_lotus_con123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_tv_long.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_tv_long_split.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_560ms_tvspeech.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_80ms_fleurs.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_80ms_gs2.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_80ms_isan.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_80ms_lotus_con123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_80ms_tvspeech.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_1120ms_lotus_con123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_1120ms_tvspeech.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_560ms_lotus_con123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/openthai2.0-asr-streaming_th-mix_560ms_tvspeech.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_fleurs.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_gs2.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_gs2_long.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_isan.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_bt10m.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_bt3m.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_con123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_jbl.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_lotus_lav123.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_tv_long.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_1120ms_tvspeech.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_320ms_fleurs.jsonl ADDED
The diff for this file is too large to render. See raw diff
 
benchmark/hypotheses/typhoon-asr-streaming-0.6b_320ms_gs2.jsonl ADDED
The diff for this file is too large to render. See raw diff