Türkçe konuşmayı metne çeviren ve üzerinde LLM tabanlı işlemler yapabilen multimodal bir model.
┌─────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐
│ Ses │ ──► │ Whisper Encoder │ ──► │ Audio Projector │ ──► │ Turkish LLM │ ──► Metin
│ (Audio) │ │ (1280 dim) │ │ (1280 → 4096) │ │ (4096 dim) │
└─────────┘ └─────────────────┘ └─────────────────┘ └─────────────┘
(Frozen) (Eğitildi) (LoRA + Merge)
1# ============================================================================
2# 🎤 TURKISH ASR + LLM FULL PIPELINE
3# ============================================================================
4
5!pip install -q bitsandbytes
6
7import torch
8import torch.nn as nn
9import librosa
10import numpy as np
11from transformers import WhisperProcessor, WhisperModel, AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
12from huggingface_hub import hf_hub_download
13from IPython.display import Audio, display
14from google.colab import drive
15
16drive.mount('/content/drive')
17
18REPO_ID = "Cosmobillian/turkish-asr-whisper-llm"
19DEVICE = "cuda"
20
21class AudioProjector(nn.Module):
22 def __init__(self):
23 super().__init__()
24 self.proj = nn.Sequential(
25 nn.Linear(1280, 4096),
26 nn.GELU(),
27 nn.Linear(4096, 4096),
28 nn.LayerNorm(4096)
29 )
30 def forward(self, x):
31 return self.proj(x)
32
33print("📥 Modeller yükleniyor...")
34
35whisper_processor = WhisperProcessor.from_pretrained(REPO_ID, subfolder="whisper")
36whisper_model = WhisperModel.from_pretrained(REPO_ID, subfolder="whisper", torch_dtype=torch.float16, device_map="auto")
37whisper_model.eval()
38print("✓ Whisper")
39
40llm_tokenizer = AutoTokenizer.from_pretrained(REPO_ID, subfolder="llm")
41if llm_tokenizer.pad_token is None:
42 llm_tokenizer.pad_token = llm_tokenizer.eos_token
43
44bnb_config = BitsAndBytesConfig(load_in_4bit=True, bnb_4bit_quant_type="nf4", bnb_4bit_compute_dtype=torch.float16)
45llm_model = AutoModelForCausalLM.from_pretrained(REPO_ID, subfolder="llm", quantization_config=bnb_config, device_map="auto", trust_remote_code=True)
46llm_model.eval()
47print("✓ LLM")
48
49projector_path = hf_hub_download(REPO_ID, "audio_projector.pt")
50projector = AudioProjector()
51projector.load_state_dict(torch.load(projector_path, map_location=DEVICE)['state_dict'])
52projector = projector.to(DEVICE).to(torch.float16).eval()
53print("✓ Projector")
54print("✅ Tüm modeller hazır!")
1@torch.no_grad()
2def speech_to_text(audio_path):
3 """Ses dosyasını transkripte çevirir"""
4 audio, sr = librosa.load(audio_path, sr=16000, mono=True)
5 if np.abs(audio).max() > 0:
6 audio = audio / np.abs(audio).max()
7
8 inputs = whisper_processor(audio, sampling_rate=16000, return_tensors="pt")
9 audio_features = inputs.input_features.to(DEVICE, dtype=torch.float16)
10
11 with torch.amp.autocast('cuda', dtype=torch.float16):
12 audio_embeds = whisper_model.encoder(audio_features).last_hidden_state
13 projected = projector(audio_embeds)
14 prompt = llm_tokenizer("Transkript:", return_tensors="pt").input_ids.to(DEVICE)
15 prompt_embeds = llm_model.get_input_embeddings()(prompt)
16 inputs_embeds = torch.cat([projected, prompt_embeds], dim=1)
17
18 outputs = llm_model.generate(
19 inputs_embeds=inputs_embeds,
20 max_new_tokens=256,
21 do_sample=False,
22 pad_token_id=llm_tokenizer.pad_token_id,
23 eos_token_id=llm_tokenizer.eos_token_id
24 )
25 text = llm_tokenizer.decode(outputs[0], skip_special_tokens=True)
26
27 return text.split("Transkript:")[-1].strip() if "Transkript:" in text else text
28
29# Kullanım
30transcript = speech_to_text("ses.wav")
31print(transcript)
1@torch.no_grad()
2def text_to_text(prompt, max_tokens=512):
3 """LLM ile metin işleme (özet, analiz, soru-cevap vb.)"""
4 inputs = llm_tokenizer(prompt, return_tensors="pt").to(DEVICE)
5
6 with torch.amp.autocast('cuda', dtype=torch.float16):
7 outputs = llm_model.generate(
8 **inputs,
9 max_new_tokens=max_tokens,
10 do_sample=True,
11 temperature=0.7,
12 top_p=0.9,
13 pad_token_id=llm_tokenizer.pad_token_id,
14 eos_token_id=llm_tokenizer.eos_token_id
15 )
16
17 response = llm_tokenizer.decode(outputs[0], skip_special_tokens=True)
18 if prompt in response:
19 response = response.replace(prompt, "").strip()
20 return response
1def full_pipeline(audio_path, task="özet"):
2 """
3 Tam pipeline: Ses → Transkript → LLM Analiz
4
5 task seçenekleri:
6 - "özet": Transkripti özetle
7 - "analiz": İçerik analizi yap
8 - "düzelt": Yazım hatalarını düzelt
9 - "başlık": Başlık öner
10 - "anahtar": Anahtar kelimeler çıkar
11 - "duygu": Duygu analizi yap
12 """
13
14 # Adım 1: Transkript
15 transcript = speech_to_text(audio_path)
16
17 # Adım 2: LLM işlem
18 prompts = {
19 "özet": f"Aşağıdaki metni kısaca özetle:\n\n{transcript}\n\nÖzet:",
20 "analiz": f"Aşağıdaki metni analiz et:\n\n{transcript}\n\nAnaliz:",
21 "düzelt": f"Yazım hatalarını düzelt:\n\n{transcript}\n\nDüzeltilmiş:",
22 "başlık": f"Başlık öner:\n\n{transcript}\n\nBaşlık:",
23 "anahtar": f"Anahtar kelimeler:\n\n{transcript}\n\nKelimeler:",
24 "duygu": f"Duygu analizi:\n\n{transcript}\n\nDuygu:"
25 }
26
27 prompt = prompts.get(task, f"{task}\n\nMetin: {transcript}\n\nCevap:")
28 result = text_to_text(prompt)
29
30 return {"transcript": transcript, "llm_output": result}
31
32# Kullanım
33result = full_pipeline("ses.wav", task="özet")
34print(result["transcript"])
35print(result["llm_output"])
1def ask_about_audio(audio_path, question):
2 """Ses içeriği hakkında soru sor"""
3
4 transcript = speech_to_text(audio_path)
5
6 prompt = f"""Transkript: {transcript}
7
8Soru: {question}
9
10Cevap:"""
11
12 return text_to_text(prompt)
13
14# Kullanım
15answer = ask_about_audio("ses.wav", "Konuşmacı ne anlatıyor?")
16print(answer)
Cosmobillian/turkish-asr-whisper-llm/
├── whisper/ # Whisper encoder + processor
│ ├── config.json
│ ├── model.safetensors
│ ├── preprocessor_config.json
│ └── ...
├── llm/ # Merged LLM (LoRA değil, full weights)
│ ├── config.json
│ ├── model.safetensors
│ ├── tokenizer.json
│ └── ...
├── audio_projector.pt # Projector weights
├── config.json # Model config
└── README.md
1AudioProjector(
2 Linear(1280, 4096), # Whisper dim → LLM dim
3 GELU(), # Aktivasyon
4 Linear(4096, 4096), # Ek dönüşüm
5 LayerNorm(4096) # Normalizasyon
6)