--- license: openrail language: - da base_model: Qwen/Qwen3-ASR-1.7B tags: - automatic-speech-recognition - danish - qwen - asr - speech-to-text - coral - streaming datasets: - alexandrainst/coral library_name: transformers pipeline_tag: automatic-speech-recognition metrics: - wer - cer model-index: - name: milo-asr results: - task: type: automatic-speech-recognition name: Speech Recognition dataset: type: alexandrainst/coral name: CoRal v2 Test split: test metrics: - type: wer value: 18.47 name: WER - type: cer value: 7.86 name: CER --- # Milo-ASR: Dansk talegenkendelses model **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 på [CoRal v2-datasættet](https://huggingface.co/datasets/alexandrainst/coral) for at blive god til dansk. ## Kort fortalt | Feature | Værdi | |---------|-------| | **WER på CoRal v2** | 18,47% (14% bedre end hviske-v3-conversation) | | **CER på CoRal v2** | 7,86% (11% bedre end hviske-v3-conversation) | | **Real-Time Factor** | 0,087 (43% hurtigere end hviske-v3-conversation) | | **Modelstørrelse** | ~1,7B parametre | ### Hvad Milo-ASR kan (nedarvet fra Qwen3-ASR) - **Streaming/realtidstransskription** via vLLM backend - **Sanggenkendelse** – Milo-ASR kan transskribere tale i lyd med baggrundsmusik - **Tidsstempler på ordniveau** via forced alignment - **30+ sprog** (optimeret til dansk) - **Op til 20 minutter pr. kald** – du behøver ikke hakke lyden op i småbidder --- ## Sammenligning med andre modeller ### CoRal v2 testsæt (9.123 eksempler, ~17,3 timer) | Model | WER | CER | RTF | Gennemløb | Parametre | |-------|-----|-----|-----|-----------|-----------| | **Milo-ASR** | **18,47%** | **7,86%** | **0,087** | **1,69 eks./s** | ~1,7B | | hviske-v2 (Whisper Large v2) | 12,74% | 4,94% | 0,154 | 0,95 eks./s | ~1,5B | | hviske-v3-conversation (Whisper Large v3) | 21,47% | 8,79% | 0,153 | 0,95 eks./s | ~2B | | Whisper Large v3 Turbo | 38,54% | 13,73% | 0,064 | 2,29 eks./s | ~0,8B | | Qwen3-ASR-1.7B (base) | 46,03% | 18,85% | 0,100 | 1,46 eks./s | ~1,7B | **Milo-ASR vs. hviske-v3-conversation (Whisper Large v3):** - **14% lavere** Word Error Rate (18,47% vs. 21,47%) - **11% lavere** Character Error Rate (7,86% vs. 8,79%) - **43% hurtigere** inferens (RTF: 0,087 vs. 0,153) - **15% færre** parametre (~1,7B vs. ~2B) > **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. ### Sammenligningsplots ![WER sammenligning](plots/wer_comparison.png) ![Hastighed sammenligning](plots/rtf_comparison.png) ![Nøjagtighed vs. hastighed](plots/accuracy_vs_speed.png) --- ## Kom i gang ### Installation ```bash pip install qwen-asr transformers torch ``` ### Basis brug ```python from qwen_asr import Qwen3ASRModel # Indlæs Milo-ASR model = Qwen3ASRModel.from_pretrained( "pluttodk/Milo-ASR", dtype="bfloat16", device_map="cuda:0", ) # Transskriber en dansk lydfil results = model.transcribe( audio="sti/til/dansk_lyd.wav", language="Danish", ) print(results[0].text) ``` --- ## Avanceret brug ### Batch-transskription Kør flere filer på én gang: ```python from qwen_asr import Qwen3ASRModel model = Qwen3ASRModel.from_pretrained( "pluttodk/Milo-ASR", dtype="bfloat16", device_map="cuda:0", max_inference_batch_size=16, ) audio_filer = ["lyd1.wav", "lyd2.wav", "lyd3.wav"] results = model.transcribe( audio=audio_filer, language="Danish", ) for i, result in enumerate(results): print(f"Fil {i+1}: {result.text}") ``` ### Transskription med tidsstempler Få tidsstempler på ordniveau via forced aligner: ```python from qwen_asr import Qwen3ASRModel model = Qwen3ASRModel.from_pretrained( "pluttodk/Milo-ASR", forced_aligner="Qwen/Qwen3-ForcedAligner-0.6B", dtype="bfloat16", device_map="cuda:0", ) results = model.transcribe( audio="sti/til/lyd.wav", language="Danish", return_time_stamps=True, ) for item in results[0].time_stamps.items: print(f"{item.start_time:.2f}s - {item.end_time:.2f}s: {item.text}") ``` ### Streaming i realtid (vLLM backend) Hvis du vil have live transskription, fx fra en mikrofon: ```python from qwen_asr import Qwen3ASRModel model = Qwen3ASRModel.LLM( model="pluttodk/Milo-ASR", gpu_memory_utilization=0.8, ) state = model.init_streaming_state( language="Danish", chunk_size_sec=2.0, ) import numpy as np def lyd_stream(): """Erstat med din faktiske lydstream fra mikrofon.""" for chunk in audio_chunks: yield np.array(chunk, dtype=np.float32) for lyd_chunk in lyd_stream(): state = model.streaming_transcribe(lyd_chunk, state) print(f"Løbende transskription: {state.text}") state = model.finish_streaming_transcribe(state) print(f"Endelig transskription: {state.text}") ``` ### Direkte brug med Transformers Vil du have fuld kontrol over modellen, kan du bruge Transformers direkte: ```python from transformers import AutoModel, AutoProcessor import torch import librosa model = AutoModel.from_pretrained( "pluttodk/Milo-ASR", trust_remote_code=True, torch_dtype=torch.bfloat16, device_map="cuda:0", ) processor = AutoProcessor.from_pretrained( "pluttodk/Milo-ASR", trust_remote_code=True, ) audio, sr = librosa.load("sti/til/lyd.wav", sr=16000, mono=True) messages = [ {"role": "system", "content": ""}, {"role": "user", "content": [{"type": "audio", "audio": audio}]}, ] text = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=False ) text = text + "language Danish" inputs = processor(text=[text], audio=[audio], return_tensors="pt", padding=True) inputs = inputs.to(model.device).to(model.dtype) output_ids = model.generate(**inputs, max_new_tokens=512) transskription = processor.batch_decode( output_ids[:, inputs["input_ids"].shape[1]:], skip_special_tokens=True, )[0] print(transskription) ``` ### Sang og baggrundsmusik Milo-ASR kan håndtere lyd med sang eller baggrundsmusik: ```python from qwen_asr import Qwen3ASRModel model = Qwen3ASRModel.from_pretrained( "pluttodk/Milo-ASR", dtype="bfloat16", device_map="cuda:0", ) results = model.transcribe( audio="sti/til/sang.wav", language="Danish", # eller None for automatisk sproggenkendelse ) print(results[0].text) ``` --- ## Om modellen ### Beskrivelse Milo-ASR er lavet ved at finetunet [Qwen3-ASR-1.7B](https://huggingface.co/Qwen/Qwen3-ASR-1.7B) på [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. - **Udviklet af:** Mathias Oliver Valdbjørn Rønnelund - **Modeltype:** Encoder-decoder talegenkendelses model - **Sprog:** Dansk (primært), med nedarvet flersproget understøttelse - **Licens:** OpenRAIL - **Finetunet fra:** [Qwen/Qwen3-ASR-1.7B](https://huggingface.co/Qwen/Qwen3-ASR-1.7B) ### Arkitektur | Komponent | Specifikation | |-----------|--------------| | Audio Encoder | 24-lags transformer (1024 hidden dim, 16 attention heads) | | Text Decoder | 28-lags transformer (2048 hidden dim, 16 attention heads) | | Parametre i alt | ~1,7 milliarder | | Præcision | bfloat16 | | Lydinput | 16kHz mono WAV | --- ## Træning ### Træningsdata Milo-ASR er finetunet på [CoRal v2-datasættet](https://huggingface.co/datasets/alexandrainst/coral), som er et dansk talekorpus med: - Mange forskellige danske talere på tværs af alder, køn og dialekter - Varierende optagelseskvalitet og lydmiljøer - Naturlig samtaletale - Oplæst tale ### Træningsopsætning **Tilgang:** Supervised Fine-Tuning (SFT) med chat template-formatering **Forbehandling:** - Lyd resamplet til 16kHz mono - Chat template anvendt med systemprompt, lydinput og måltransskription - Prefix masking så modellen kun trænes på transskriptionstokens **Hyperparametre:** | Parameter | Værdi | |-----------|-------| | Basismodel | Qwen/Qwen3-ASR-1.7B | | Læringsrate | 2e-5 | | Batchstørrelse (per device) | 8 | | Gradient accumulation steps | 4 | | Effektiv batchstørrelse | 32 | | Epoker | 3 | | Warmup ratio | 0,1 | | Weight decay | 0,01 | | Max gradient norm | 1,0 | | Præcision | bfloat16 | | Optimizer | AdamW | | LR scheduler | Lineært fald | | Træningsskridt i alt | 23.448 | **Hardware:** NVIDIA GPU'er (~25GB GPU-hukommelse per device) --- ## Evaluering ### Testdata Milo-ASR er evalueret på CoRal v2-testsættet: - **9.123 eksempler** - **~17,3 timers** lyd - Bred repræsentation af danske talere og optagelsesforhold ### Metrikker | Metrik | Beskrivelse | |--------|-------------| | **WER** | Word Error Rate – andelen af forkert transskriberede ord (lavere er bedre) | | **CER** | Character Error Rate – andelen af forkert transskriberede tegn (lavere er bedre) | | **RTF** | Real-Time Factor – forholdet mellem procestid og lydvarighed (under 1,0 = hurtigere end realtid) | ### Resultater | Model | WER | CER | RTF | Gennemløb | Parametre | |-------|-----|-----|-----|-----------|-----------| | **Milo-ASR** | **18,47%** | **7,86%** | **0,087** | **1,69 eks./s** | ~1,7B | | hviske-v2 (Whisper Large v2) | 12,74% | 4,94% | 0,154 | 0,95 eks./s | ~1,5B | | hviske-v3-conversation (Whisper Large v3) | 21,47% | 8,79% | 0,153 | 0,95 eks./s | ~2B | | Whisper Large v3 Turbo | 38,54% | 13,73% | 0,064 | 2,29 eks./s | ~0,8B | | Qwen3-ASR-1.7B (base) | 46,03% | 18,85% | 0,100 | 1,46 eks./s | ~1,7B | 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. --- ## Citér modellen Bruger du Milo-ASR i dit projekt, må du meget gerne citere: ```bibtex @misc{Milo-ASR, author = {Rønnelund, Mathias Oliver Valdbjørn}, title = {Milo-ASR: Danish ASR Model based on Qwen3-ASR}, year = {2025}, publisher = {HuggingFace}, url = {https://huggingface.co/pluttodk/Milo-ASR} } ``` Og gerne også basismodellen og datasættet: ```bibtex @article{qwen3asr, title={Qwen3-ASR Technical Report}, author={Qwen Team}, journal={arXiv preprint arXiv:2601.21337}, year={2025} } @dataset{coral, title={CoRal: A Danish Speech Corpus}, author={Alexandra Institute}, year={2024}, url={https://huggingface.co/datasets/alexandrainst/coral} } ``` --- ## Tak til - [Qwen-teamet](https://github.com/QwenLM) for Qwen3-ASR basismodellen - [Alexandra Instituttet](https://alexandra.dk/) for CoRal v2-datasættet