← Tüm yazılar

REHBER

Yerel LLM seçerken Türkçe için nelere bakılır

Kurum kendi sunucusunda çalıştıracağı açık ağırlıklı modeli Türkçe için seçerken tokenizer’dan bağlam penceresine, quantization’dan donanım planına kadar hangi kriterleri, hangi yöntemle ölçmeli. Sonuç tablosu değil, ölçüm yöntemi.

Kendi sunucusunda çalışacak açık ağırlıklı bir model seçerken, karşılaştırma tablolarına bakmak ilk akla gelen yöntem. Ancak bu tabloların neredeyse tamamı İngilizce görevler üzerinde kuruludur ve Türkçe’ye dair söyledikleri dolaylıdır. Türkçe sondan eklemeli bir dil; bir yüzey kelimesi tipik olarak bir kök ve ona eklenen bir ek zinciridir. Bu yapı, tokenizer’dan bağlam penceresine, oradan VRAM planına kadar zincirin her halkasını etkiler. Bu yazı hangi modelin Türkçe’de nasıl davrandığına dair bir sonuç sunmaz; bunun yerine kendi kurumunuzda ölçebileceğiniz kriterleri ve her birinin nasıl ölçüleceğini anlatır. Sonuç tablosunu üretecek olan sizsiniz, çünkü ölçüm kendi metinleriniz ve kendi görevleriniz üzerinde anlamlıdır.

1. Tokenizer: aynı cümle kaç token

Tokenizer, model ailesinin Türkçe ile ilk temas noktasıdır ve ölçmesi en kolay kriterdir. Ölçülecek metrik literatürde fertility adıyla geçer: kelime başına düşen ortalama alt-kelime (subword) sayısı. Bu değer tokenizer ailesine ve metnin kendisine göre değişir; dışarıdan bir referans sayı almak yerine hesabı kendi metninizle yapın.

BPE veya WordPiece gibi standart tokenizer’lar dilbilimsel olarak anlamlı morfemleri değil, eğitim korpusunda sık geçen ortografik alt-dizileri optimize eder. Türkçe’de kök ve ek zinciri tek bir yüzey kelimesinde birleştiği için bu ayrışma morfem sınırlarıyla örtüşmez (arXiv:2502.07057). Pratik sonucu şudur: aynı anlamı taşıyan bir Türkçe metin, İngilizce karşılığına göre daha fazla token’a bölünebilir. Bu doğrudan iki şeyi etkiler — token başına ücretlendirilen ya da token başına bellek harcayan her yerde maliyet, ve sabit bir bağlam penceresine sığdırabildiğiniz gerçek içerik miktarı.

Ölçüm için kurumun kendi metninden temsili bir örnek yeterlidir: sözleşme metni, destek kaydı, teknik doküman, e-posta gövdesi — hangisi production’da işlenecekse o. Aday modellerin tokenizer’larını aynı dosya üzerinde çalıştırıp oranı karşılaştırın.

python
from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("<model-repo>")

with open("ornek-kurum-metni.txt", encoding="utf-8") as f:
    metin = f.read()

kelime = len(metin.split())
token = len(tok(metin, add_special_tokens=False)["input_ids"])

print(f"kelime    : {kelime}")
print(f"token     : {token}")
print(f"fertility : {token / kelime:.2f}")

Model kartlarında sözlük boyutu genellikle yazılıdır; örneğin Gemma 3 teknik raporu (arXiv:2503.19786) Gemini 2.0 ile paylaşılan SentencePiece tokenizer’ından ve 262 bin girdilik bir sözlükten söz eder; aynı tokenizer rakamları ayrı token’lara böler, boşlukları korur ve byte düzeyinde kodlama kullanır. Sözlük boyutu tek başına bir gösterge değildir: aynı sözlük boyutu farklı eğitim korpuslarında farklı Türkçe davranışı üretir. Sözlük boyutunu bir ipucu olarak not edin, kararı fertility ölçümüne bırakın.

2. Eğitim verisinde Türkçe: beyanın ne kadar spesifik olduğuna bakın

Bir modelin Türkçe’yi ne kadar gördüğünü doğrudan öğrenmenin yolu yoktur; elinizde yalnızca model kartı ve teknik rapor beyanları vardır. Bu beyanların çözünürlüğü modelden modele değişir. Meta, Llama 3 için ön eğitim verisinin %5’ten fazlasının, 30’dan fazla dili kapsayan yüksek kaliteli İngilizce dışı veriden oluştuğunu ve bu dillerde İngilizce ile aynı performansı beklemediğini açıkça yazar. Qwen3 teknik raporu (arXiv:2505.09388) 36 trilyon token ve 119 dil/lehçe kapsamı bildirir. Google’ın Gemma 3 model kartı 140’tan fazla dil içeren eğitim verisinden söz ederken, teknik raporun kendisi kesin bir dil sayısı vermez, yalnızca çokdilli payın artırıldığını belirtir.

Bu üç örnekte ortak olan nokta şu: hiçbiri Türkçe’nin yüzde kaç olduğunu ayrı ayrı açıklamaz. Açıklanan şey ya dil sayısıdır ya da İngilizce dışı toplam orandır. Dolayısıyla “kaç dil destekliyor” sorusu tek başına ayırt edici değildir; daha ayırt edici olan, beyanın hangi çözünürlükte verildiği ve model kartında Türkçe’nin adının değerlendirilmiş diller arasında geçip geçmediğidir. Bu bilgi bir sonuç değil, ölçüm planınıza girdi olmalıdır: beyan ne kadar belirsizse, kendi değerlendirme setinizin ağırlığı o kadar artar.

3. Quantization ve donanım: aritmetiği önce yapın

Quantization seçimi, kalite ile VRAM arasındaki ayar düğmesidir ve ağırlık tarafı tamamen deterministik olarak hesaplanır. FP16’da parametre başına 2 bayt düşer. llama.cpp’nin quantize dokümantasyonundaki Llama-3.1-8B ölçümleri bu ilişkiyi somut kılar: F16 14,96 GiB, Q8_0 (8,5 bit/ağırlık) 7,95 GiB, Q4_K_M (4,89 bit/ağırlık) 4,58 GiB. Kendi modeliniz için aynı hesabı parametre sayısı ile bit/ağırlık değerinden doğrudan yapabilirsiniz. Q4_K_M homojen bir 4-bit format değildir; k-quant ailesinden karma bir formattır ve bazı tensörleri daha yüksek hassasiyette saklar.

Kalite tarafı ise deterministik değildir ve genel bir yüzde ile ifade edilemez. Bu yüzden quantization seviyesini kendi değerlendirme setiniz üzerinde ölçün: aynı soru setini FP16, Q8 ve Q4 çıktılarıyla çalıştırıp farkın sizin görevinizde anlamlı olup olmadığına bakın. Türkçe için özellikle işe yarayan bir ayrıntı var: llama.cpp’nin `llama-imatrix` aracı, kalibrasyon verisi üzerinden bir önem matrisi hesaplar ve `llama-quantize --imatrix` bu matrisi niceleme sırasında kullanır. Kalibrasyon verisini siz seçtiğiniz için, nicelemeyi Türkçe metinle kalibre etmek teknik olarak mümkündür.

Ağırlıklar toplam VRAM’in yalnızca bir bileşenidir. İkinci bileşen KV cache’tir ve dizi uzunluğu ile doğrusal büyür; uzun bağlamda genellikle asıl darboğaz burasıdır. Formül mimari parametrelerinden doğrudan hesaplanır.

python
def kv_cache_bayt(katman, kv_head, head_boyutu, dizi, batch=1, bayt=2):
    # bayt: BF16/FP16 icin 2, FP8 icin 1
    # bastaki 2 carpani K ve V icindir
    return 2 * katman * kv_head * head_boyutu * dizi * batch * bayt

# 80 katman, 8 KV head, 128 boyutlu head, BF16
print(kv_cache_bayt(80, 8, 128, 1) / 1e6)        # ~0.33 MB / token
print(kv_cache_bayt(80, 8, 128, 128_000) / 1e9)  # ~42 GB
print(kv_cache_bayt(80, 8, 128, 1_000_000) / 1e9)  # ~328 GB

Grouped-Query Attention, KV head sayısını query head sayısının altına indirerek bu maliyeti küçültür; 64 query head’e karşı 8 KV head yapılandırması, tam çok başlı dikkate göre sekiz kat azalma verir. Mimarinin kendisi de belirleyicidir: Gemma 3 teknik raporu, yayınlanan yapılandırmada her global katmana beş local katman düşen bir örüntü ve local katmanlarda 1024 tokenlik kayan pencere kullandığını, bu sayede yalnızca global katmanların uzun bağlama baktığını belirtir. Pratik sonucu şu: KV cache büyümesi katmanların çoğunda pencere boyutuyla sınırlanır, dizi uzunluğuyla değil. Planlama kuralı sade: toplam VRAM ≈ ağırlıklar + KV cache + aktivasyon ve çalışma alanı. İlk iki kalem, model ve bağlam seçiminiz belliyken kalem kağıtla çıkar.

Donanım planını hedef bağlam uzunluğu üzerinden yapın, model boyutu üzerinden değil. 128K bağlamda çalışacak bir kurulumda KV cache, ağırlıkların büyüklüğüne yaklaşabilir ya da onu aşabilir.

4. Bağlam penceresi: beyan edilen uzunluk ile kullanılabilir uzunluk

Model kartında yazan bağlam uzunluğu bir üst sınırdır, bir garanti değildir. NVIDIA araştırmacılarının geliştirdiği RULER benchmark’ı (arXiv:2404.06654) bu ayrımı ölçülebilir hale getiriyor. RULER dört görev kategorisi kullanır: retrieval (genişletilmiş needle-in-a-haystack varyantları), multi-hop tracing (değişken izleme), aggregation ve distraktör belgelerle soru-cevap. “Etkin bağlam uzunluğu”nu ise modelin bir performans eşiğinin üzerinde kalabildiği maksimum bağlam boyutu olarak tanımlar. Çalışmanın temel bulgusu, 32K veya üzeri bağlam beyan eden modellerin ancak yarısının 32K’da tatmin edici performansı koruyabildiği; modellerin sade needle testinde neredeyse tam sonuç verirken daha karmaşık görevlerde uzunlukla birlikte belirgin şekilde bozulduğu yönünde.

İkinci ayrıntı, pencerenin nasıl elde edildiğidir. Qwen3-8B model kartı, modelin doğal olarak 32.768 token desteklediğini ve YaRN ile 131.072 tokene kadar doğrulandığını yazar. Aynı kart bir uyarı da içerir: statik YaRN uygulamasında ölçekleme faktörü girdi uzunluğundan bağımsız sabit kalır ve bu, kısa metinlerdeki performansı etkileyebilir. Bu nedenle uzatma yalnızca gerçekten uzun bağlam gerektiğinde açılmalıdır.

json
{
  "rope_scaling": {
    "rope_type": "yarn",
    "factor": 4.0,
    "original_max_position_embeddings": 32768
  }
}

Üçüncü ayrıntı servis katmanıdır. Ollama’nın resmi dokümantasyonu varsayılan bağlam uzunluğunun VRAM’e göre ölçeklendiğini belirtir: 24 GiB altında 4K, 24–48 GiB arasında 32K, 48 GiB ve üzerinde 256K. Yani model 128K destekliyor olsa bile çalıştırma katmanı varsayılanı 4K’ya indirebilir. Değerlendirmeye başlamadan önce, servis katmanının o an gerçekten hangi bağlam uzunluğuyla çalıştığını doğrulayın; aksi halde modeli değil, varsayılan yapılandırmayı ölçmüş olursunuz.

5. Talimat takibi ve Türkçe sistem promptu

Kurumsal kullanımda modelden beklenen şey çoğu zaman bilgi değil, biçimdir: yalnızca geçerli JSON döndürmek, en fazla üç madde yazmak, verilen alan adlarının dışına çıkmamak, kaynak metinde olmayan bir şey eklememek. Bunu ölçmenin yerleşik yöntemi IFEval’dir (arXiv:2311.07911): 25 tür “doğrulanabilir talimat” tanımlar ve talimatları, yanıtın bir dil modeliyle değil programatik bir kontrol fonksiyonuyla denetlenebileceği şekilde tasarlar.

Türkçe için burada somut bir boşluk var. IFEval’i çokdilli hale getiren M-IFEval çalışması (arXiv:2502.04688, Findings of ACL: NAACL 2025) Fransızca, Japonca ve İspanyolca’yı kapsar; Türkçe içermez. Aynı çalışma, sekiz model üzerinde performansın diller ve talimat türleri arasında geniş ölçüde değiştiğini bildiriyor. Yani İngilizce talimat takibi sonucundan Türkçe’ye çıkarım yapmak dayanaksızdır ve Türkçe için hazır bir standart ölçüm de yoktur. Buna karşılık IFEval’in tasarım fikri taşınabilir: kendi Türkçe talimat setinizi, her talimatın karşılığında bir kontrol fonksiyonu yazabilecek şekilde kurun.

python
import json

def en_az_madde(cevap, n=5):
    return sum(1 for s in cevap.splitlines() if s.strip().startswith("- ")) >= n

def gecerli_json(cevap):
    try:
        json.loads(cevap)
        return True
    except json.JSONDecodeError:
        return False

def turkce_karakter_korunmus(cevap):
    return any(ch in cevap for ch in "çğıöşüÇĞİÖŞÜ")

KONTROLLER = {
    "en_az_5_madde": en_az_madde,
    "gecerli_json": gecerli_json,
    "turkce_karakter": turkce_karakter_korunmus,
}

Sistem promptunun dili de ayrı bir değişkendir. Aynı talimat setini iki kez çalıştırın: bir kez Türkçe sistem promptuyla, bir kez İngilizce sistem promptu ve Türkçe kullanıcı girdisiyle. İkisi arasındaki fark, ilerideki prompt mimarinizi doğrudan belirler ve bu ölçüm birkaç saatlik iştir.

6. Kendi değerlendirme setinizi kurmak

Yukarıdaki kriterlerin hepsi tek bir noktada birleşir: kurumun kendi dokümanlarından üretilmiş bir soru-cevap seti. Mevcut Türkçe altyapılar bu seti kurarken yön verir. Cetvel (arXiv:2508.16431, Koç Üniversitesi KUIS-AI), yedi kategoride 23 görevden oluşan ve `lm-evaluation-harness` üzerine kurulu birleşik bir Türkçe değerlendirme çatısıdır; 70B’ye kadar 33 açık ağırlıklı model üzerinde çalıştırılmıştır. Çalışmanın metodolojik gözlemlerinden biri, dilbilgisi hatası düzeltme ve metinden çıkarmalı soru-cevap (extractive QA) görevlerinin modeller arasında ayrım yapmakta özellikle ayırt edici olduğudur — bu, kendi setinizde hangi görev tiplerine ağırlık vereceğinize dair kullanışlı bir işaret. TR-MMLU (arXiv:2501.00593) ise 280.000 soruluk bir havuzdan seçilmiş, 62 bölümde 6.200 çoktan seçmeli soru sunar. Ek olarak OpenLLM Turkish Leaderboard ve `lm-evaluation-harness`in Türkçe’ye uyarlanmış çatalı mevcuttur.

Bu setler genel yetenek için referans noktasıdır; sizin işinizi ölçmezler. Kendi setiniz için pratik bir çerçeve: production’da gerçekten gelen soru tiplerinden 100–200 örnek toplayın, her biri için beklenen yanıtı ya da kabul kriterini kurum içi uzmanla yazın, soruları görev tipine göre etiketleyin (metinden çıkarmalı soru-cevap, özetleme, biçim dönüştürme, sınıflandırma), ve cevapların içinde geçmesi gereken referans ifadeleri ayrıca not edin. Cetvel makalesinin altını çizdiği bir nokta, makine çevirisiyle üretilmiş benchmark’ların kültürel içerik açısından eksik kaldığıdır; İngilizce bir seti otomatik çeviriden geçirmek yerine örnekleri Türkçe kaynaklardan toplayın.

Değerlendirme setini yazılı hale getirmenin bir yan kazancı var: set bir kez kurulduğunda model değişimi, quantization değişimi ve prompt değişimi aynı ölçekle karşılaştırılabilir hale gelir. Set olmadan her karar baştan değerlendirilir.

Toparlarsak: tokenizer fertility’sini kendi metninizle ölçün, model kartındaki dil beyanının çözünürlüğünü not edin, quantization ile VRAM arasındaki ilişkiyi aritmetikle kurup kalite tarafını kendi setinizde sınayın, beyan edilen bağlam penceresini RULER’ın tarif ettiği türden görevlerle ve servis katmanının gerçek yapılandırmasıyla birlikte doğrulayın, talimat takibini programatik kontrol fonksiyonlarıyla Türkçe üzerinde ölçün, ve donanımı ağırlıklar artı KV cache formülünden planlayın. Bu adımların hiçbiri bir model sıralaması üretmez — üretmesi de gerekmez. Ürettiği şey, kendi kurumunuzun yükü altında hangi yapılandırmanın gereksinimlerinizi karşıladığını gösteren, tekrar edilebilir bir ölçüm zeminidir. Model tercihleri iki yılda birkaç kez değişir; ölçüm zemini kalır.

Kaynaklar

  • Meta — Introducing Meta Llama 3 (eğitim verisinde İngilizce dışı oran ve dil sayısı beyanı)
  • Qwen3 Technical Report — arXiv:2505.09388 (36 trilyon token, 119 dil ve lehçe)
  • Gemma 3 Technical Report — arXiv:2503.19786 (tokenizer, sözlük boyutu, local/global katman oranı, kayan pencere)
  • Tokenization Standards for Linguistic Integrity: Turkish as a Benchmark — arXiv:2502.07057
  • llama.cpp — quantize aracı dokümantasyonu (Llama-3.1-8B için bit/ağırlık ve dosya boyutu tablosu)

Diğer yazılar

Bir sisteminiz mi var, kurulacak mı?

Sunum gerekmez. 20 dakika. Sonrası size kalmış.