|
|
--- |
|
|
license: mit |
|
|
datasets: |
|
|
- sixfingerdev/turkish-qa-multi-dialog-dataset |
|
|
- sixfingerdev/Turkish-Knowledge-extraction_topic-summary |
|
|
language: |
|
|
- tr |
|
|
tags: |
|
|
- text-generation-inference |
|
|
--- |
|
|
|
|
|
|
|
|
|
|
|
# 🤖 Türkçe QA Language Model |
|
|
|
|
|
N-gram tabanlı soru-cevap ve metin tamamlama modeli. 21K temiz QA/diyalog verisiyle eğitilmiştir. |
|
|
|
|
|
## 📊 Model Bilgileri |
|
|
|
|
|
- **Model Tipi**: Trigram Language Model + Retrieval |
|
|
- **Dil**: Türkçe |
|
|
- **Parametre Sayısı**: ~45K kelime vocabulary |
|
|
- **Eğitim Verisi**: 21K QA çifti + diyalog |
|
|
- **Model Boyutu**: ~15-30 MB |
|
|
- **Lisans**: MIT |
|
|
|
|
|
## 🎯 Özellikler |
|
|
|
|
|
- ✅ Soru-cevap (Q&A mode) |
|
|
- ✅ Metin tamamlama (Complete mode) |
|
|
- ✅ Hybrid yaklaşım (Retrieval + Generation) |
|
|
- ✅ Repetition penalty |
|
|
- ✅ Temperature ve Top-k kontrolü |
|
|
- ✅ Mobil uyumlu (Pydroid 3) |
|
|
|
|
|
## 📦 Kurulum |
|
|
|
|
|
```bash |
|
|
# Gerekli kütüphaneler (sadece Python stdlib) |
|
|
# Ekstra kurulum gerekmez! |
|
|
``` |
|
|
|
|
|
## 🚀 Hızlı Başlangıç |
|
|
|
|
|
### Temel Kullanım |
|
|
|
|
|
```python |
|
|
import pickle |
|
|
|
|
|
# Modeli yükle |
|
|
with open('qa_lm.pkl', 'rb') as f: |
|
|
data = pickle.load(f) |
|
|
|
|
|
model = QALM() |
|
|
model.trigram = data['trigram'] |
|
|
model.bigram = data['bigram'] |
|
|
model.unigram = data['unigram'] |
|
|
model.qa_pairs = data['qa_pairs'] |
|
|
model.ready = True |
|
|
|
|
|
# Soru sor |
|
|
answer = model.answer( |
|
|
"Python nedir?", |
|
|
max_tokens=50, |
|
|
temperature=0.7, |
|
|
stream=False |
|
|
) |
|
|
print(answer) |
|
|
``` |
|
|
|
|
|
### Tam Örnek (Kopyala-Yapıştır) |
|
|
|
|
|
```python |
|
|
import pickle |
|
|
import random |
|
|
|
|
|
class QALM: |
|
|
def __init__(self): |
|
|
self.trigram = {} |
|
|
self.bigram = {} |
|
|
self.unigram = {} |
|
|
self.qa_pairs = [] |
|
|
self.ready = False |
|
|
|
|
|
def load(self, path='qa_lm.pkl'): |
|
|
with open(path, 'rb') as f: |
|
|
data = pickle.load(f) |
|
|
self.trigram = data['trigram'] |
|
|
self.bigram = data['bigram'] |
|
|
self.unigram = data['unigram'] |
|
|
self.qa_pairs = data['qa_pairs'] |
|
|
self.ready = True |
|
|
print(f"✓ Model yüklendi! ({len(self.qa_pairs)} QA)") |
|
|
|
|
|
def find_similar(self, query): |
|
|
query_tokens = set(query.lower().split()) |
|
|
scores = [] |
|
|
for inp, out in self.qa_pairs: |
|
|
inp_tokens = set(inp.split()) |
|
|
intersection = len(query_tokens & inp_tokens) |
|
|
union = len(query_tokens | inp_tokens) |
|
|
if union > 0: |
|
|
score = intersection / union |
|
|
if score > 0.1: |
|
|
scores.append((inp, out, score)) |
|
|
scores.sort(key=lambda x: x[2], reverse=True) |
|
|
return scores[:3] |
|
|
|
|
|
def predict_next(self, tokens, generated, temperature=0.7, top_k=20): |
|
|
candidates = {} |
|
|
|
|
|
if len(tokens) >= 2: |
|
|
key = (tokens[-2], tokens[-1]) |
|
|
if key in self.trigram: |
|
|
candidates = dict(self.trigram[key]) |
|
|
|
|
|
if not candidates and tokens: |
|
|
if tokens[-1] in self.bigram: |
|
|
candidates = dict(self.bigram[tokens[-1]]) |
|
|
|
|
|
if not candidates: |
|
|
return None |
|
|
|
|
|
recent = set(generated[-10:]) |
|
|
for w in candidates: |
|
|
if w in recent: |
|
|
candidates[w] /= 3 |
|
|
|
|
|
items = list(candidates.items()) |
|
|
weights = [max(c, 0.01) ** (1.0/temperature) for _, c in items] |
|
|
|
|
|
if len(items) > top_k: |
|
|
indexed = sorted(enumerate(weights), key=lambda x: x[1], reverse=True)[:top_k] |
|
|
items = [items[i] for i, _ in indexed] |
|
|
weights = [weights[i] for i, _ in indexed] |
|
|
|
|
|
total = sum(weights) |
|
|
r = random.random() * total |
|
|
cumsum = 0 |
|
|
for (word, _), weight in zip(items, weights): |
|
|
cumsum += weight |
|
|
if r <= cumsum: |
|
|
return word |
|
|
return items[0][0] if items else None |
|
|
|
|
|
def answer(self, query, max_tokens=50, temperature=0.7, top_k=20): |
|
|
similar = self.find_similar(query) |
|
|
|
|
|
if similar and similar[0][2] > 0.3: |
|
|
return similar[0][1] |
|
|
|
|
|
if similar: |
|
|
seed = similar[0][1].split()[:3] |
|
|
else: |
|
|
seed = query.lower().split()[-2:] |
|
|
|
|
|
generated = list(seed) |
|
|
|
|
|
for _ in range(max_tokens): |
|
|
next_word = self.predict_next( |
|
|
generated[-5:], |
|
|
generated, |
|
|
temperature, |
|
|
top_k |
|
|
) |
|
|
if not next_word: |
|
|
break |
|
|
generated.append(next_word) |
|
|
if next_word in '.!?' and len(generated) > 10: |
|
|
break |
|
|
|
|
|
return ' '.join(generated) |
|
|
|
|
|
# Kullanım |
|
|
model = QALM() |
|
|
model.load('qa_lm.pkl') |
|
|
|
|
|
# Soru-Cevap |
|
|
print(model.answer("Python nedir?")) |
|
|
print(model.answer("Türkiye'nin başkenti neresi?")) |
|
|
print(model.answer("Yapay zeka nedir?")) |
|
|
``` |
|
|
|
|
|
## 📝 Kullanım Örnekleri |
|
|
|
|
|
### Q&A Modu |
|
|
|
|
|
```python |
|
|
# Yüksek benzerlikli soru (direkt retrieval) |
|
|
>>> model.answer("Python nedir?", temperature=0.7) |
|
|
"python bir programlama dilidir. kolay öğrenilebilir ve güçlüdür." |
|
|
|
|
|
# Düşük benzerlikli soru (generation) |
|
|
>>> model.answer("Bugün ne yapsam?", temperature=0.8) |
|
|
"bugün hava güzel olacak. dışarı çıkabilirsin." |
|
|
``` |
|
|
|
|
|
### Temperature Kontrolü |
|
|
|
|
|
```python |
|
|
# Düşük (tutarlı) |
|
|
>>> model.answer("Merhaba", temperature=0.3, top_k=5) |
|
|
"merhaba nasılsın?" |
|
|
|
|
|
# Orta (dengeli) |
|
|
>>> model.answer("Merhaba", temperature=0.7, top_k=20) |
|
|
"merhaba ben bir yapay zeka asistanıyım." |
|
|
|
|
|
# Yüksek (yaratıcı) |
|
|
>>> model.answer("Merhaba", temperature=1.2, top_k=50) |
|
|
"merhaba dostum! bugün sana nasıl yardımcı olabilirim?" |
|
|
``` |
|
|
|
|
|
## ⚙️ Parametreler |
|
|
|
|
|
| Parametre | Varsayılan | Açıklama | |
|
|
|-----------|-----------|----------| |
|
|
| `max_tokens` | 50 | Maksimum üretilecek kelime sayısı | |
|
|
| `temperature` | 0.7 | Yaratıcılık (0.1-1.5 arası) | |
|
|
| `top_k` | 20 | Seçilecek en iyi k aday | |
|
|
| `stream` | True | Kelime kelime yazdırma | |
|
|
|
|
|
## 📈 Performans |
|
|
|
|
|
- **Retrieval başarısı**: ~70% (yüksek benzerlikte) |
|
|
- **Generation kalitesi**: Orta (trigram limiti) |
|
|
- **Hız**: ~0.1 saniye/cevap |
|
|
- **RAM kullanımı**: ~50-100 MB |
|
|
|
|
|
## ⚠️ Sınırlamalar |
|
|
|
|
|
- Sadece 21K QA verisi (sınırlı kapsam) |
|
|
- Trigram modeli (5 kelime context) |
|
|
- Uzun bağlam hatırlanamaz |
|
|
- Bazen tekrar edebilir |
|
|
- Wikipedia bilgisi filtrelenmiş |
|
|
|
|
|
## 🎛️ Ayar Önerileri |
|
|
|
|
|
### Tutarlı Cevaplar İçin |
|
|
```python |
|
|
temperature=0.5 |
|
|
top_k=10 |
|
|
max_tokens=30 |
|
|
``` |
|
|
|
|
|
### Yaratıcı Cevaplar İçin |
|
|
```python |
|
|
temperature=1.0 |
|
|
top_k=40 |
|
|
max_tokens=80 |
|
|
``` |
|
|
|
|
|
### Kısa ve Net Cevaplar |
|
|
```python |
|
|
temperature=0.3 |
|
|
top_k=5 |
|
|
max_tokens=20 |
|
|
``` |
|
|
|
|
|
## 🔧 Gelişmiş Kullanım |
|
|
|
|
|
### Batch İşleme |
|
|
|
|
|
```python |
|
|
questions = [ |
|
|
"Python nedir?", |
|
|
"Türkiye'nin başkenti?", |
|
|
"Yapay zeka nasıl çalışır?" |
|
|
] |
|
|
|
|
|
for q in questions: |
|
|
answer = model.answer(q, stream=False) |
|
|
print(f"S: {q}") |
|
|
print(f"C: {answer}\n") |
|
|
``` |
|
|
|
|
|
### Custom Tokenizer |
|
|
|
|
|
```python |
|
|
def clean_query(text): |
|
|
import re |
|
|
text = text.lower() |
|
|
text = re.sub(r'[^a-zçğıöşü\s]', '', text) |
|
|
return text.strip() |
|
|
|
|
|
query = clean_query("PYTHON NEDİR???") |
|
|
answer = model.answer(query) |
|
|
``` |
|
|
|
|
|
## 📚 Eğitim Detayları |
|
|
|
|
|
- **Veri Kaynağı**: merged_dataset.jsonl |
|
|
- **Filtreleme**: Wikipedia makaleleri hariç |
|
|
- **Eğitim Süresi**: ~3-5 dakika |
|
|
- **N-gram**: Trigram (3-kelime) |
|
|
- **Retrieval**: Jaccard similarity |
|
|
|
|
|
## 🐛 Bilinen Sorunlar |
|
|
|
|
|
1. Çok uzun cevaplar tekrar edebilir |
|
|
2. Nadir konularda zayıf performans |
|
|
3. Context window sadece 5 kelime |
|
|
4. Matematik/hesaplama yapamaz |
|
|
|
|
|
## 💡 İpuçları |
|
|
|
|
|
- Kısa sorular daha iyi sonuç verir |
|
|
- `temperature=0.7` dengeli başlangıç |
|
|
- Tekrar varsa `top_k` artır |
|
|
- QA modunda benzerlik %30'un altındaysa üretim modu devreye girer |
|
|
|
|
|
## 📄 Lisans |
|
|
|
|
|
MIT License - Ticari kullanım dahil serbestçe kullanılabilir. |
|
|
|
|
|
## 🤝 Katkı |
|
|
|
|
|
Model açık kaynak prensipleriyle geliştirilmiştir. İyileştirme önerileri memnuniyetle karşılanır. |
|
|
|
|
|
## 📞 İletişim |
|
|
|
|
|
Sorularınız için issue açabilirsiniz. |
|
|
|
|
|
--- |
|
|
|
|
|
**Not**: Bu model eğitim/araştırma amaçlıdır. Production kullanımı için transformer tabanlı modeller önerilir. |