Downloads · 30 days
17
13% of all-time downloads
BRWA-AI/brwa-qwen3-sorani-endpoint
brwa-qwen3-sorani-endpoint is a automatic speech recognition model from BRWA-AI. Use it when you need speech turned into text. The card lists the license as apache-2.0.
This repository contains the first fine-tuned version of Qwen3-ASR-1.7B specifically adapted for Central Kurdish (Sorani / ckb). This model bridges the gap between advanced Large Multimodal Models (LMMs) and low-resou…
Downloads · 30 days
17
13% of all-time downloads
All-time downloads
127
Public
Parameters
2B
10.1 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors4.1 GB · 100%
From the Hugging Face model README
This repository contains the first fine-tuned version of Qwen3-ASR-1.7B specifically adapted for Central Kurdish (Sorani / ckb). This model bridges the gap between advanced Large Multimodal Models (LMMs) and low-resource Kurdish speech recognition.
I have already done the hard work of teaching it Kurdish. If you want to build an ASR model for a specific domain (Kurdish medical terminology, legal proceedings, or specific regional accents), this model is the perfect starting checkpoint. You no longer need to spend compute resources teaching a base model how to speak and spell in Sorani Kurdish. You can take this model and fine-tune it on a small, domain-specific dataset, and it will adapt rapidly while retaining its core Kurdish language capabilities. <br /> <audio controls> <source src="https://huggingface.co/rzgar/qwen3-asr-sorani-kurdish-ckb-v1/resolve/main/demo_04.wav" type="audio/mp3"> </audio> demo_04.wav : "زۆر دەمێکە زۆر لەوانەی کە بوونە ناسیاوم هەڵیان پێچاوم کە سەر گوروشتەی ژیانی خۆم بنووسمە و بزانن چیم بەسەر هاتووە من وەک دەڵێن چوێلەکە خۆت چی و شۆرباو چی دەمزانی ژیانێکی زۆر قۆڕ و تورە هاتم ڕابواردووە و ڕووی مەجلیسی یارانی نیە " <br/> <audio controls> <source src="https://huggingface.co/rzgar/whisper-large-v3-sorani-kurdish-ckb-v2/resolve/main/demo_01.wav" type="audio/wav"> </audio> demo_01.wav : " لایەکی چاری ٢٠١٧ دەستم بەو ئیشەیەکتە تەکریبانە ٧ مانگ دەبیتەن دەستم پێکردیا و ٧/٧/٢٠١٧ ژێکەم ئیشم بوو کە لەگەڵ ستاف بیکەم و سیویەکی مانگیش ئینشاڵڵا سیویەکی دامانایەوەی سیپاڵەک لەناو بازاڕ بکەین بۆ ڕۆژی هەڵەوین " <br/> <audio controls> <source src="https://huggingface.co/rzgar/qwen3-asr-sorani-kurdish-ckb-v1/resolve/main/demo_02.wav" type="audio/wav"> </audio> demo_02.wav : " لەسەر غاز بەرنامە ئەکا بۆ نموونە لەسەر نەوت بەرنامەکە ناو زانکۆکانی کوردستان پڕە لە دکتۆرا و پرۆفیسۆری ئەو ئیختصاصانە واز لەوانەیەنێ " <br/> <audio controls> <source src="https://huggingface.co/rzgar/qwen3-asr-sorani-kurdish-ckb-v1/resolve/main/demo_03.wav" type="audio/wav"> </audio> demo_03.wav : " لە ڕووداوێکی هاتوچۆی نێوان پاسێک و تەمکەرێکی سووتەمەنی لە زیقار ٢١ کەس گیانیان دەدەست داوە و نزیکەی نۆزاکەسی دێکەش بریندا بوون کە بەشێکیان جۆستایان سووتاوە "
ComfyUI-Qwen3-ASR:
https://github.com/DarioFT/ComfyUI-Qwen3-ASR <br/> Edit nodes.py and add this repo for automatic download - Model repo mappings, line 14
Example 1:
import torch
from qwen_asr import Qwen3ASRModel # pip install qwen-asr || more info https://huggingface.co/Qwen/Qwen3-ASR-1.7B#environment-setup
# Clone the repo,
model = Qwen3ASRModel.from_pretrained(
"./qwen3-asr-sorani-kurdish-ckb-v1",
dtype=torch.bfloat16,
device_map="cuda:0",
)
# Audio file
results = model.transcribe(
audio="./demo_04.wav",
)
print("🎤 Qwen3-ASR Output:")
print("="*40)
print(results[0].text)
print("="*40)
import torch
import librosa
from qwen_asr import Qwen3ASRModel
# Define paths
model_path = "./qwen3-asr-sorani-kurdish-ckb-v1"
audio_path = "./demo_04.wav"
system_prompt = """You are an expert Sorani Kurdish (ckb) transcriptionist.
Transcribe the audio into Sorani Kurdish with perfect orthography.
IMPORTANT: The speaker may use loanwords in Persian or Arabic. if you recognize any,
please transcribe them in their standard writing form."""
print("🔄 Loading model and processor...")
# Load the model wrapper in bfloat16
asr_wrapper = Qwen3ASRModel.from_pretrained(
model_path,
dtype=torch.bfloat16,
device_map="cuda:0",
)
model = asr_wrapper.model
processor = asr_wrapper.processor
print("🎵 Loading audio...")
# Load and resample audio to 16kHz (matches training)
audio_array, sr = librosa.load(audio_path, sr=16000)
print("⚙️ Processing inputs...")
# 4. Build the exact same message structure used in training
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": [{"type": "audio", "audio": audio_array}]},
]
# Apply chat template
text = processor.apply_chat_template([messages], add_generation_prompt=True, tokenize=False)[0]
# Process text and audio into model inputs
inputs = processor(text=text, audio=audio_array, return_tensors="pt").to("cuda:0")
# CRITICAL FIX: Cast all floating-point tensors to bfloat16 to match the model
for k, v in inputs.items():
if torch.is_tensor(v) and v.is_floating_point():
inputs[k] = v.to(torch.bfloat16)
print("🚀 Generating transcription...")
# Generate
with torch.no_grad():
# Record the length of the input prompt so we only decode the NEW tokens
input_len = inputs["input_ids"].shape[1]
# Run generation
output = model.generate(
**inputs,
max_new_tokens=256,
num_beams=5,
do_sample=False,
pad_token_id=processor.tokenizer.pad_token_id,
eos_token_id=processor.tokenizer.eos_token_id,
length_penalty=0.8,
)
if isinstance(output, tuple):
generated_ids = output[0]
elif hasattr(output, 'sequences'):
generated_ids = output.sequences
else:
generated_ids = output
# Slice off the prompt tokens and decode only the generated text
generated_ids = generated_ids[:, input_len:]
result_text = processor.tokenizer.decode(generated_ids[0], skip_special_tokens=True).strip()
def normalize_dialect_to_academic(text: str) -> str:
"""
Maps known dialectal mishearings or hallucinations to standard Academic Sorani Kurdish.
This is highly efficient and preserves the model's perfect grammar.
"""
# Example dictionary of dialectal words or What the model incorrectly hears and replace with preferred word
dialect_map = {
"سیپاڵەک": "فێستیڤاڵ",
"تیشکی یەکەس": "تیشکی ئێکس",
"جۆستا": "جەستە",
"نۆزاکەسی": "نۆزدەکەس",
"تەمکەر": "تەنکەر",
}
# Sort keys by length (descending) to replace longer phrases first
for wrong, correct in sorted(dialect_map.items(), key=lambda x: len(x[0]), reverse=True):
text = text.replace(wrong, correct)
return text
# Apply the normalization
final_text = normalize_dialect_to_academic(result_text)
print("\n🎤 Qwen3-ASR Output (Raw):")
print(result_text)
print("=" * 60)
print("\n✅ Normalized Academic Kurdish:")
print(final_text)
print("=" * 60)