milo-asr / README.md
pluttodk's picture
Update README.md
5e0002c verified
|
Raw
History Blame
11 kB
metadata
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, som er finetunet på CoRal v2-datasættet 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 Hastighed sammenligning Nøjagtighed vs. hastighed


Kom i gang

Installation

pip install qwen-asr transformers torch

Basis brug

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:

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:

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:

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:

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<asr_text>"

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:

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.7BCoRal v2-datasættet. 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

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, 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:

@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:

@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