pluttodk commited on
Commit
1097072
·
verified ·
1 Parent(s): 87ec8f0

Upload README.md with huggingface_hub

Browse files
Files changed (1) hide show
  1. README.md +67 -276
README.md CHANGED
@@ -10,6 +10,7 @@ tags:
10
  - asr
11
  - speech-to-text
12
  - coral
 
13
  - streaming
14
  datasets:
15
  - alexandrainst/coral
@@ -30,128 +31,88 @@ model-index:
30
  split: test
31
  metrics:
32
  - type: wer
33
- value: 18.47
34
  name: WER
35
  - type: cer
36
- value: 7.86
37
  name: CER
38
  ---
39
 
40
- # Milo-ASR: Dansk talegenkendelses model
41
 
42
- **Milo-ASR** er en dansk ASR-model bygget oven på [Qwen3-ASR-1.7B](https://huggingface.co/Qwen/Qwen3-ASR-1.7B), som er finetunet [CoRal v2-datasættet](https://huggingface.co/datasets/alexandrainst/coral) for at blive god til dansk.
43
 
44
- ## Kort fortalt
45
 
46
- | Feature | Værdi |
47
- |---------|-------|
48
- | **WER på CoRal v2** | 18,47% (14% bedre end hviske-v3-conversation) |
49
- | **CER på CoRal v2** | 7,86% (11% bedre end hviske-v3-conversation) |
50
- | **Real-Time Factor** | 0,087 (43% hurtigere end hviske-v3-conversation) |
51
- | **Modelstørrelse** | ~1,7B parametre |
52
 
53
- ### Hvad Milo-ASR kan (nedarvet fra Qwen3-ASR)
54
 
55
- - **Streaming/realtidstransskription** via vLLM backend
56
- - **Sanggenkendelse** – Milo-ASR kan transskribere tale i lyd med baggrundsmusik
57
- - **Tidsstempler ordniveau** via forced alignment
58
- - **30+ sprog** (optimeret til dansk)
59
- - **Op til 20 minutter pr. kald** du behøver ikke hakke lyden op i småbidder
 
 
60
 
61
- ---
62
-
63
- ## Sammenligning med andre modeller
64
-
65
- ### CoRal v2 testsæt (9.123 eksempler, ~17,3 timer)
66
 
67
- | Model | WER | CER | RTF | Gennemløb | Parametre |
68
- |-------|-----|-----|-----|-----------|-----------|
69
- | **Milo-ASR** | **18,47%** | **7,86%** | **0,087** | **1,69 eks./s** | ~1,7B |
70
- | hviske-v2 (Whisper Large v2) | 12,74% | 4,94% | 0,154 | 0,95 eks./s | ~1,5B |
71
- | hviske-v3-conversation (Whisper Large v3) | 21,47% | 8,79% | 0,153 | 0,95 eks./s | ~2B |
72
- | Whisper Large v3 Turbo | 38,54% | 13,73% | 0,064 | 2,29 eks./s | ~0,8B |
73
- | Qwen3-ASR-1.7B (base) | 46,03% | 18,85% | 0,100 | 1,46 eks./s | ~1,7B |
74
 
75
- **Milo-ASR vs. hviske-v3-conversation (Whisper Large v3):**
76
- - **14% lavere** Word Error Rate (18,47% vs. 21,47%)
77
- - **11% lavere** Character Error Rate (7,86% vs. 8,79%)
78
- - **43% hurtigere** inferens (RTF: 0,087 vs. 0,153)
79
- - **15% færre** parametre (~1,7B vs. ~2B)
80
 
81
- > **Bemærk:** hviske-v2 (Whisper Large v2) klarer sig bedre end Milo-ASR på WER og CER. Til gengæld er Milo-ASR næsten dobbelt så hurtig (RTF 0,087 vs. 0,154), så hvis hastighed er vigtig for dig, er Milo-ASR det oplagte valg.
82
 
83
- ### Sammenligningsplots
84
-
85
- ![WER sammenligning](plots/wer_comparison.png)
86
- ![Hastighed sammenligning](plots/rtf_comparison.png)
87
- ![Nøjagtighed vs. hastighed](plots/accuracy_vs_speed.png)
88
 
89
  ---
90
 
91
- ## Kom i gang
92
-
93
- ### Installation
94
 
95
  ```bash
96
  pip install qwen-asr transformers torch
97
  ```
98
 
99
- ### Basis brug
100
-
101
  ```python
102
  from qwen_asr import Qwen3ASRModel
103
 
104
- # Indlæs Milo-ASR
105
  model = Qwen3ASRModel.from_pretrained(
106
  "pluttodk/Milo-ASR",
107
  dtype="bfloat16",
108
  device_map="cuda:0",
109
  )
110
 
111
- # Transskriber en dansk lydfil
112
  results = model.transcribe(
113
- audio="sti/til/dansk_lyd.wav",
114
  language="Danish",
115
  )
116
 
117
  print(results[0].text)
118
  ```
119
 
120
- ---
121
-
122
- ## Avanceret brug
123
-
124
- ### Batch-transskription
125
-
126
- Kør flere filer på én gang:
127
 
128
  ```python
129
- from qwen_asr import Qwen3ASRModel
130
-
131
- model = Qwen3ASRModel.from_pretrained(
132
- "pluttodk/Milo-ASR",
133
- dtype="bfloat16",
134
- device_map="cuda:0",
135
- max_inference_batch_size=16,
136
- )
137
-
138
- audio_filer = ["lyd1.wav", "lyd2.wav", "lyd3.wav"]
139
- results = model.transcribe(
140
- audio=audio_filer,
141
- language="Danish",
142
- )
143
 
144
- for i, result in enumerate(results):
145
- print(f"Fil {i+1}: {result.text}")
146
  ```
147
 
148
- ### Transskription med tidsstempler
149
-
150
- Få tidsstempler på ordniveau via forced aligner:
151
 
152
  ```python
153
- from qwen_asr import Qwen3ASRModel
154
-
155
  model = Qwen3ASRModel.from_pretrained(
156
  "pluttodk/Milo-ASR",
157
  forced_aligner="Qwen/Qwen3-ForcedAligner-0.6B",
@@ -160,7 +121,7 @@ model = Qwen3ASRModel.from_pretrained(
160
  )
161
 
162
  results = model.transcribe(
163
- audio="sti/til/lyd.wav",
164
  language="Danish",
165
  return_time_stamps=True,
166
  )
@@ -169,206 +130,56 @@ for item in results[0].time_stamps.items:
169
  print(f"{item.start_time:.2f}s - {item.end_time:.2f}s: {item.text}")
170
  ```
171
 
172
- ### Streaming i realtid (vLLM backend)
173
-
174
- Hvis du vil have live transskription, fx fra en mikrofon:
175
 
176
  ```python
177
- from qwen_asr import Qwen3ASRModel
178
-
179
  model = Qwen3ASRModel.LLM(
180
  model="pluttodk/Milo-ASR",
181
  gpu_memory_utilization=0.8,
182
  )
183
 
184
- state = model.init_streaming_state(
185
- language="Danish",
186
- chunk_size_sec=2.0,
187
- )
188
-
189
- import numpy as np
190
 
191
- def lyd_stream():
192
- """Erstat med din faktiske lydstream fra mikrofon."""
193
- for chunk in audio_chunks:
194
- yield np.array(chunk, dtype=np.float32)
195
-
196
- for lyd_chunk in lyd_stream():
197
- state = model.streaming_transcribe(lyd_chunk, state)
198
- print(f"Løbende transskription: {state.text}")
199
 
200
  state = model.finish_streaming_transcribe(state)
201
- print(f"Endelig transskription: {state.text}")
202
- ```
203
-
204
- ### Direkte brug med Transformers
205
-
206
- Vil du have fuld kontrol over modellen, kan du bruge Transformers direkte:
207
-
208
- ```python
209
- from transformers import AutoModel, AutoProcessor
210
- import torch
211
- import librosa
212
-
213
- model = AutoModel.from_pretrained(
214
- "pluttodk/Milo-ASR",
215
- trust_remote_code=True,
216
- torch_dtype=torch.bfloat16,
217
- device_map="cuda:0",
218
- )
219
- processor = AutoProcessor.from_pretrained(
220
- "pluttodk/Milo-ASR",
221
- trust_remote_code=True,
222
- )
223
-
224
- audio, sr = librosa.load("sti/til/lyd.wav", sr=16000, mono=True)
225
-
226
- messages = [
227
- {"role": "system", "content": ""},
228
- {"role": "user", "content": [{"type": "audio", "audio": audio}]},
229
- ]
230
-
231
- text = processor.apply_chat_template(
232
- messages,
233
- add_generation_prompt=True,
234
- tokenize=False
235
- )
236
- text = text + "language Danish<asr_text>"
237
-
238
- inputs = processor(text=[text], audio=[audio], return_tensors="pt", padding=True)
239
- inputs = inputs.to(model.device).to(model.dtype)
240
-
241
- output_ids = model.generate(**inputs, max_new_tokens=512)
242
- transskription = processor.batch_decode(
243
- output_ids[:, inputs["input_ids"].shape[1]:],
244
- skip_special_tokens=True,
245
- )[0]
246
-
247
- print(transskription)
248
- ```
249
-
250
- ### Sang og baggrundsmusik
251
-
252
- Milo-ASR kan håndtere lyd med sang eller baggrundsmusik:
253
-
254
- ```python
255
- from qwen_asr import Qwen3ASRModel
256
-
257
- model = Qwen3ASRModel.from_pretrained(
258
- "pluttodk/Milo-ASR",
259
- dtype="bfloat16",
260
- device_map="cuda:0",
261
- )
262
-
263
- results = model.transcribe(
264
- audio="sti/til/sang.wav",
265
- language="Danish", # eller None for automatisk sproggenkendelse
266
- )
267
-
268
- print(results[0].text)
269
  ```
270
 
271
  ---
272
 
273
- ## Om modellen
274
 
275
- ### Beskrivelse
276
 
277
- Milo-ASR er lavet ved at finetunet [Qwen3-ASR-1.7B](https://huggingface.co/Qwen/Qwen3-ASR-1.7B)[CoRal v2-datasættet](https://huggingface.co/datasets/alexandrainst/coral). Resultatet er en model, der er skarp til dansk tale og samtidig hurtig nok til at bruges i produktionsmiljøer og realtidsapplikationer.
 
278
 
279
- - **Udviklet af:** Mathias Oliver Valdbjørn Rønnelund
280
- - **Modeltype:** Encoder-decoder talegenkendelses model
281
- - **Sprog:** Dansk (primært), med nedarvet flersproget understøttelse
282
- - **Licens:** OpenRAIL
283
- - **Finetunet fra:** [Qwen/Qwen3-ASR-1.7B](https://huggingface.co/Qwen/Qwen3-ASR-1.7B)
284
-
285
- ### Arkitektur
286
-
287
- | Komponent | Specifikation |
288
- |-----------|--------------|
289
- | Audio Encoder | 24-lags transformer (1024 hidden dim, 16 attention heads) |
290
- | Text Decoder | 28-lags transformer (2048 hidden dim, 16 attention heads) |
291
- | Parametre i alt | ~1,7 milliarder |
292
- | Præcision | bfloat16 |
293
- | Lydinput | 16kHz mono WAV |
294
 
295
  ---
296
 
297
- ## Træning
298
-
299
- ### Træningsdata
300
-
301
- Milo-ASR er finetunet på [CoRal v2-datasættet](https://huggingface.co/datasets/alexandrainst/coral), som er et dansk talekorpus med:
302
- - Mange forskellige danske talere på tværs af alder, køn og dialekter
303
- - Varierende optagelseskvalitet og lydmiljøer
304
- - Naturlig samtaletale
305
- - Oplæst tale
306
-
307
- ### Træningsopsætning
308
-
309
- **Tilgang:** Supervised Fine-Tuning (SFT) med chat template-formatering
310
 
311
- **Forbehandling:**
312
- - Lyd resamplet til 16kHz mono
313
- - Chat template anvendt med systemprompt, lydinput og måltransskription
314
- - Prefix masking modellen kun trænes på transskriptionstokens
315
-
316
- **Hyperparametre:**
317
-
318
- | Parameter | Værdi |
319
- |-----------|-------|
320
- | Basismodel | Qwen/Qwen3-ASR-1.7B |
321
- | Læringsrate | 2e-5 |
322
- | Batchstørrelse (per device) | 8 |
323
- | Gradient accumulation steps | 4 |
324
- | Effektiv batchstørrelse | 32 |
325
- | Epoker | 3 |
326
- | Warmup ratio | 0,1 |
327
- | Weight decay | 0,01 |
328
- | Max gradient norm | 1,0 |
329
- | Præcision | bfloat16 |
330
- | Optimizer | AdamW |
331
- | LR scheduler | Lineært fald |
332
- | Træningsskridt i alt | 23.448 |
333
-
334
- **Hardware:** NVIDIA GPU'er (~25GB GPU-hukommelse per device)
335
 
336
  ---
337
 
338
- ## Evaluering
339
-
340
- ### Testdata
341
-
342
- Milo-ASR er evalueret på CoRal v2-testsættet:
343
- - **9.123 eksempler**
344
- - **~17,3 timers** lyd
345
- - Bred repræsentation af danske talere og optagelsesforhold
346
-
347
- ### Metrikker
348
-
349
- | Metrik | Beskrivelse |
350
- |--------|-------------|
351
- | **WER** | Word Error Rate – andelen af forkert transskriberede ord (lavere er bedre) |
352
- | **CER** | Character Error Rate – andelen af forkert transskriberede tegn (lavere er bedre) |
353
- | **RTF** | Real-Time Factor – forholdet mellem procestid og lydvarighed (under 1,0 = hurtigere end realtid) |
354
-
355
- ### Resultater
356
-
357
- | Model | WER | CER | RTF | Gennemløb | Parametre |
358
- |-------|-----|-----|-----|-----------|-----------|
359
- | **Milo-ASR** | **18,47%** | **7,86%** | **0,087** | **1,69 eks./s** | ~1,7B |
360
- | hviske-v2 (Whisper Large v2) | 12,74% | 4,94% | 0,154 | 0,95 eks./s | ~1,5B |
361
- | hviske-v3-conversation (Whisper Large v3) | 21,47% | 8,79% | 0,153 | 0,95 eks./s | ~2B |
362
- | Whisper Large v3 Turbo | 38,54% | 13,73% | 0,064 | 2,29 eks./s | ~0,8B |
363
- | Qwen3-ASR-1.7B (base) | 46,03% | 18,85% | 0,100 | 1,46 eks./s | ~1,7B |
364
-
365
- Milo-ASR slår hviske-v3-conversation med 14% på WER og 11% på CER, og er samtidig 43% hurtigere. Sammenlignet med den utrænede Qwen3-ASR-1.7B basismodel falder WER fra 46,03% til 18,47% – et klart tegn på, at finetuning på CoRal v2 gør en stor forskel.
366
-
367
- ---
368
-
369
- ## Citér modellen
370
-
371
- Bruger du Milo-ASR i dit projekt, må du meget gerne citere:
372
 
373
  ```bibtex
374
  @misc{Milo-ASR,
@@ -380,27 +191,7 @@ Bruger du Milo-ASR i dit projekt, må du meget gerne citere:
380
  }
381
  ```
382
 
383
- Og gerne også basismodellen og datasættet:
384
-
385
- ```bibtex
386
- @article{qwen3asr,
387
- title={Qwen3-ASR Technical Report},
388
- author={Qwen Team},
389
- journal={arXiv preprint arXiv:2601.21337},
390
- year={2025}
391
- }
392
-
393
- @dataset{coral,
394
- title={CoRal: A Danish Speech Corpus},
395
- author={Alexandra Institute},
396
- year={2024},
397
- url={https://huggingface.co/datasets/alexandrainst/coral}
398
- }
399
- ```
400
-
401
- ---
402
-
403
- ## Tak til
404
 
405
- - [Qwen-teamet](https://github.com/QwenLM) for Qwen3-ASR basismodellen
406
- - [Alexandra Instituttet](https://alexandra.dk/) for CoRal v2-datasættet
 
10
  - asr
11
  - speech-to-text
12
  - coral
13
+ - podcast
14
  - streaming
15
  datasets:
16
  - alexandrainst/coral
 
31
  split: test
32
  metrics:
33
  - type: wer
34
+ value: 23.24
35
  name: WER
36
  - type: cer
37
+ value: 11.17
38
  name: CER
39
  ---
40
 
41
+ # Milo-ASR: Dansk ASR Model
42
 
43
+ **Milo-ASR** er en dansk speech-to-text model baseret på [Qwen3-ASR-1.7B](https://huggingface.co/Qwen/Qwen3-ASR-1.7B), finetuned til at forstå dansk - både oplæst tale og samtaler/podcasts.
44
 
45
+ Modellen er trænet på [CoRal v2](https://huggingface.co/datasets/alexandrainst/coral) + danske podcast-data, så den klarer sig godt på tværs af domæner. De fleste andre modeller er kun gode til enten det ene eller det andet.
46
 
47
+ ## Resultater
 
 
 
 
 
48
 
49
+ ### CoRal v2 (oplæst tale, 10.370 samples)
50
 
51
+ | Model | WER | CER |
52
+ |-------|-----|-----|
53
+ | hviske-v2 (Whisper v2) | **17.40%** | **7.96%** |
54
+ | hviske-v3 (Whisper v3) | 21.62% | 9.22% |
55
+ | **Milo-ASR** | 23.24% | 11.17% |
56
+ | Whisper v3 Turbo | 40.35% | 15.51% |
57
+ | Qwen3-ASR base | 46.28% | 19.78% |
58
 
59
+ ### Podcast (samtaler, 500 samples)
 
 
 
 
60
 
61
+ | Model | WER | CER |
62
+ |-------|-----|-----|
63
+ | **Milo-ASR** | **21.82%** | **15.64%** |
64
+ | hviske-v2 (Whisper v2) | 50.67% | 38.31% |
65
+ | Whisper v3 Turbo | 67.03% | 45.98% |
66
+ | Qwen3-ASR base | 67.52% | 47.71% |
67
+ | hviske-v3 (Whisper v3) | 67.65% | 50.12% |
68
 
69
+ Milo-ASR er den eneste model der klarer begge domæner godt. podcasts er den **2.3x bedre** end næstbedste model (hviske-v2).
 
 
 
 
70
 
71
+ ### Plots
72
 
73
+ ![CoRal v2 WER](plots/wer_comparison.png)
74
+ ![Podcast WER](plots/wer_comparison_podcast.png)
75
+ ![CoRal vs Podcast](plots/dual_domain_wer.png)
76
+ ![Speed](plots/accuracy_vs_speed.png)
 
77
 
78
  ---
79
 
80
+ ## Quick Start
 
 
81
 
82
  ```bash
83
  pip install qwen-asr transformers torch
84
  ```
85
 
 
 
86
  ```python
87
  from qwen_asr import Qwen3ASRModel
88
 
 
89
  model = Qwen3ASRModel.from_pretrained(
90
  "pluttodk/Milo-ASR",
91
  dtype="bfloat16",
92
  device_map="cuda:0",
93
  )
94
 
 
95
  results = model.transcribe(
96
+ audio="path/to/danish_audio.wav",
97
  language="Danish",
98
  )
99
 
100
  print(results[0].text)
101
  ```
102
 
103
+ ### Batch Transcription
 
 
 
 
 
 
104
 
105
  ```python
106
+ audio_files = ["audio1.wav", "audio2.wav", "audio3.wav"]
107
+ results = model.transcribe(audio=audio_files, language="Danish")
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
+ for r in results:
110
+ print(r.text)
111
  ```
112
 
113
+ ### Timestamps
 
 
114
 
115
  ```python
 
 
116
  model = Qwen3ASRModel.from_pretrained(
117
  "pluttodk/Milo-ASR",
118
  forced_aligner="Qwen/Qwen3-ForcedAligner-0.6B",
 
121
  )
122
 
123
  results = model.transcribe(
124
+ audio="path/to/audio.wav",
125
  language="Danish",
126
  return_time_stamps=True,
127
  )
 
130
  print(f"{item.start_time:.2f}s - {item.end_time:.2f}s: {item.text}")
131
  ```
132
 
133
+ ### Streaming (vLLM)
 
 
134
 
135
  ```python
 
 
136
  model = Qwen3ASRModel.LLM(
137
  model="pluttodk/Milo-ASR",
138
  gpu_memory_utilization=0.8,
139
  )
140
 
141
+ state = model.init_streaming_state(language="Danish", chunk_size_sec=2.0)
 
 
 
 
 
142
 
143
+ for audio_chunk in audio_stream():
144
+ state = model.streaming_transcribe(audio_chunk, state)
145
+ print(state.text)
 
 
 
 
 
146
 
147
  state = model.finish_streaming_transcribe(state)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  ```
149
 
150
  ---
151
 
152
+ ## Træningsdetaljer
153
 
154
+ Modellen er finetuned i to stages:
155
 
156
+ 1. **Stage 1**: Qwen3-ASR-1.7B finetuned på CoRal v2 (~250K samples, 3 epochs, lr=2e-5)
157
+ 2. **Stage 2**: Fortsat fra stage 1 checkpoint på podcast + Azure podcast data (~141K samples, 8 epochs, lr=1e-5, cosine schedule)
158
 
159
+ | Parameter | Stage 2 |
160
+ |-----------|---------|
161
+ | Learning rate | 1e-5 |
162
+ | Batch size | 8 (x4 grad acc = 32 effective) |
163
+ | Epochs | 8 |
164
+ | LR scheduler | Cosine |
165
+ | Warmup ratio | 0.1 |
166
+ | Weight decay | 0.01 |
167
+ | Precision | bfloat16 |
168
+ | Training steps | 35,560 |
 
 
 
 
 
169
 
170
  ---
171
 
172
+ ## Ting nedarvet fra Qwen3-ASR
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
+ - Streaming/real-time via vLLM
175
+ - Sang detection (baggrundsmusik)
176
+ - Word-level timestamps
177
+ - 30+ sprog (dansk optimeret)
178
+ - Op til 20 min audio pr. request
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
 
180
  ---
181
 
182
+ ## Citation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
183
 
184
  ```bibtex
185
  @misc{Milo-ASR,
 
191
  }
192
  ```
193
 
194
+ ## Acknowledgements
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
 
196
+ - [Qwen Team](https://github.com/QwenLM) for Qwen3-ASR
197
+ - [Alexandra Institute](https://alexandra.dk/) for CoRal v2