Views
No views yet
| Model | FLEURS (clean) | DDD-Kenya (held-out, diverse) | afri-voices (held-out, naturalistic) | vLLM-servable |
|---|---|---|---|---|
| base Qwen3-ASR-1.7B | 1.008 (Arabic script) | — | — | yes |
| MMS-1b-all | 0.453 | — | — | no |
| This model | 0.552 / 0.189 | 0.385 / 0.129 | 1.05–1.14 / 0.59–0.70 | yes |
no_repeat_ngram_size=3, repetition_penalty=1.0 (no_repeat helps modestly on hard audio; a
repetition_penalty > 1 backfires into hallucination — verified).so_so + shunyalabs/somali-speech-dataset + badrex/afri-voices-somali-speech +
DDD-Kenya/Somali-ASR-Subset-68H (4 arrow shards). ~5,900 clips, LoRA r=16 all-linear, 3,500 steps.pip install -U qwen-asr1from qwen_asr import Qwen3ASRModel
2
3model = Qwen3ASRModel.from_pretrained(
4 "chrullis/Qwen3-ASR-1.7B-Somali",
5 dtype="bfloat16", device_map="cuda:0", max_new_tokens=128,
6)
7result = model.transcribe(audio="clip.wav", language="so") # path, URL, or (np.ndarray, sr)
8print(result[0].text)1import torch, types
2import torch.nn as nn
3from peft import PeftModel
4from qwen_asr import Qwen3ASRModel
5from qwen_asr.core.transformers_backend.modeling_qwen3_asr import Qwen3ASRForConditionalGeneration
6from qwen_asr.core.transformers_backend.processing_qwen3_asr import Qwen3ASRProcessor
7
8BASE = "Qwen/Qwen3-ASR-1.7B"
9ADAPTER = "chrullis/Qwen3-ASR-1.7B-Somali-LoRA"
10
11# 1) load base, apply + merge the LoRA into the decoder ("thinker")
12top = Qwen3ASRForConditionalGeneration.from_pretrained(BASE, dtype=torch.bfloat16)
13tok_emb = max((m for m in top.thinker.modules() if isinstance(m, nn.Embedding)),
14 key=lambda e: e.num_embeddings)
15top.thinker.get_input_embeddings = types.MethodType(lambda self: tok_emb, top.thinker) # qwen-asr quirk
16top.thinker = PeftModel.from_pretrained(top.thinker, ADAPTER).merge_and_unload()
17
18# 2) keep decoding greedy (sampling makes transcribe ramble), then save a usable model dir
19gc = top.generation_config
20gc.do_sample = False; gc.temperature = None; gc.top_p = None; gc.top_k = None
21gc.no_repeat_ngram_size = 3
22top.save_pretrained("somali_merged")
23Qwen3ASRProcessor.from_pretrained(BASE).save_pretrained("somali_merged")
24
25# 3) load the merged dir for transcription
26model = Qwen3ASRModel.from_pretrained("somali_merged", dtype="bfloat16",
27 device_map="cuda:0", max_new_tokens=128)
28print(model.transcribe(audio="clip.wav", language="so")[0].text)no_repeat_ngram_size=3, repetition_penalty=1.0 (already set in this repo's
generation_config.json). A repetition_penalty > 1 backfires into hallucination — do not raise it./v1/audio/transcriptions endpoint:1pip install vllm # install on an ext4 filesystem; some encrypted homes break flashinfer's long filenames
2vllm serve chrullis/Qwen3-ASR-1.7B-Somali \
3 --served-model-name qwen3-asr-somali \
4 --dtype float16 --gpu-memory-utilization 0.80 --max-model-len 40961curl -s http://localhost:8000/v1/audio/transcriptions \
2 -F file=@clip.wav -F model=qwen3-asr-somali -F language=so -F response_format=json1from openai import OpenAI
2client = OpenAI(base_url="http://localhost:8000/v1", api_key="x")
3print(client.audio.transcriptions.create(model="qwen3-asr-somali",
4 file=open("clip.wav","rb"), language="so").text)