Selam arkadaşlar, yine ben.
Bugün bir süredir üzerinde çalıştığım, hem teknik hem de kişisel olarak benim için oldukça önemli bir projeden bahsetmek istiyorum.
Bir Türkçe dil modeli geliştirdim.
Adını da Beyefendi koydum.
Bunu söylerken en başta dürüst olmam gereken bir nokta var: Beyefendi sıfırdan eğitilmiş dev bir temel model değil. Qwen3.5-2B üzerine Türkçe continued pretraining ve supervised fine-tuning uyguladığım, yaklaşık 1,88 milyar parametreli küçük bir model. Amacım da zaten internetteki en büyük modelle yarışmak değildi.
Ben daha pratik bir soru sordum:
Kendi bilgisayarımda eğitebildiğim, ölçebildiğim ve 8 GB sınıfı donanımda çalıştırmayı hedefleyebildiğim küçük bir Türkçe model gerçekten ne kadar iyi olabilir?
Bu soru beni veri seçiminden lisanslara, QLoRA eğitiminden GGUF dönüşümüne, benchmark tasarımından quantization kaynaklı kalite kaybına kadar tahmin ettiğimden çok daha uzun bir yolculuğa çıkardı.
Bu yazıda sadece sonucu değil, o sonuca nasıl ulaştığımı da anlatmak istiyorum.
Her şey 3090 ile başlamadı ama 3090 her şeyi hızlandırdı
Daha önce bana hediye edilen RTX 3090’ın yalnızca bir ekran kartı olmadığını yazmıştım. Benim için yeniden hareket etmeye başlamanın, daha ciddi projelere girişmenin ve yerel yapay zekâ tarafında gerçekten bir şeyler denemenin sembolü olmuştu.
Beyefendi bu düşüncenin en somut çıktılarından biri oldu.
Hazır modelleri indirip çalıştırmak elbette öğretici. Farklı modelleri aynı istemle karşılaştırmak da çok şey gösteriyor. Fakat bir noktadan sonra yalnızca modelleri kullanan kişi olmak istemedim. Verinin nasıl hazırlandığını, eğitimin neden bozulduğunu, küçük bir değişikliğin sonucu nasıl etkilediğini ve bir model dosyasının gerçekten yayımlanmaya hazır olup olmadığını daha yakından görmek istedim.
Kısacası bu defa sadece aracı kullanmak değil, sistemin içine girmek istedim.
Önce doğru temel modeli seçmek gerekiyordu
Küçük model seçimi düşündüğümden daha zor oldu. Çünkü tek mesele parametre sayısı değildi.
Qwen, Gemma, Phi, Ministral, Granite, Salamandra ve LFM ailelerine baktım. Lisans, Türkçe tokenizer verimi, QLoRA uyumluluğu, GGUF ekosistemi ve mevcut sohbet kabiliyeti gibi başlıkları birlikte değerlendirdim.
Sonunda Qwen/Qwen3.5-2B üzerinde karar kıldım.
Model küçük sayılabilecek bir boyuttaydı, Apache-2.0 lisansına sahipti ve kullandığım doğru UTF-8 Türkçe örnekte Qwen3-1.7B’ye göre yaklaşık %9,71 daha az token üretiyordu. Türkçe gibi eklemeli bir dilde tokenizer verimi küçük bir ayrıntı değil. Aynı cümleyi daha az tokenla temsil etmek; bağlam, hız ve bellek tarafında doğrudan avantaj sağlayabiliyor.
Yine de burada önemli bir ayrım var. Qwen3.5-2B zaten post-trained bir sohbet modeli. Dolayısıyla yaptığım continued pretraining deneyi, tamamen ham bir base model üzerinde yapılan klasik CPT deneyi olarak okunmamalı. Bu proje boyunca mümkün olduğunca sonuçları olduğundan büyük göstermemeye çalıştım. Bence bir benchmark tablosundan önce bu tür ayrımların açıkça yazılması gerekiyor.
Büyük veri değil, açıklayabildiğim veri
İlk refleksim daha fazla Türkçe veri bulmaktı. Fakat veri kümelerini inceledikçe “daha fazla” ile “daha iyi”nin aynı şey olmadığını gördüm.
Bazı Türkçe instruction ve chain-of-thought veri kümeleri ilk bakışta oldukça çekiciydi. Ancak veri kartındaki lisans etiketi ile her bir örneğin gerçek kaynağı her zaman aynı açıklıkta değildi. Sentetik çıktıların hangi sağlayıcının koşulları altında üretildiği veya kaynak metinlerin yeniden dağıtım hakkı gibi sorular cevaplanmıyorsa, o veriyi nihai modele eklemek istemedim.
Bu nedenle incelediğim bazı büyük Türkçe kümeleri eğitimden tamamen çıkardım.
Nihai SFT verisini sabit bir Aya revision’ındaki Türkçe kayıtlardan oluşturdum:
Başlangıçta 4.046 Türkçe eğitim kaydı vardı.
Test karantinasıyla eşleşen 39 kayıt çıkarıldı.
19 tam tekrar ve 46 yakın tekrar temizlendi.
Dil filtresinden geçmeyen 5 kayıt elendi.
İki kayıtta kişisel bilgi redaksiyonu yapıldı.
Son durumda 3.877 train, 33 validation ve 27 test kaydı kaldı.
Toplamda yalnızca 3.937 kayıt.
Bu sayı internette gördüğümüz milyonlarca satırlık veri kümelerinin yanında çok küçük görünebilir. Fakat ben bu projede sayıdan önce izlenebilirliği tercih ettim. Hangi verinin eğitime girdiğini, hangisinin neden çıkarıldığını ve benchmark sorularının eğitim setine sızıp sızmadığını bilmek benim için daha değerliydi.
Seneca-TRBench’in 553 sorusunu da aynı nedenle tamamen değerlendirme karantinasında tuttum. Model bu soruları eğitim sırasında görmedi.
Küçük bir continued pretraining deneyi gerçekten işe yaradı mı?
Modeli doğrudan SFT ile eğitmek yerine önce kısa bir Türkçe continued pretraining aşaması eklemenin faydalı olup olmayacağını merak ettim.
Türkçe Vikipedi’nin sabit bir snapshot’ından 512 eğitim pasajı ve farklı makalelerden 64 holdout pasajı hazırladım. Sonra üç kolu karşılaştırdım:
Deney koluVikipedi holdout perplexityTemel model11,66527Yalnızca SFT11,37913CPT → SFT10,86804
CPT → SFT kolu, yalnızca SFT koluna göre perplexity’yi %4,49 düşürdü. Kontrollü küçük benchmarkta Token F1 %30,01den %36,79a, kriter başarısı ise %40,00tan %53,33e çıktı.
Bu sonucu “CPT kesinlikle gerekli” şeklinde okumuyorum. Korpus yalnızca 512 pasajdan oluşuyordu, tek bir ana seed kullandım ve iyileşme proje başında koyduğum %10luk araştırma eşiğinin altında kaldı.
Ama iki farklı ölçüm aynı yönü gösteriyordu.
Bu yüzden nihai eğitim hattını kısa CPT ve ardından SFT olarak seçtim. Bazen küçük bir deney kesin cevap vermez ama bir sonraki adım için yeterince iyi bir yön işareti verir. Burada olan tam olarak buydu.
49 dakikalık ana eğitim
Nihai SFT koşusunu RTX 3090 üzerinde QLoRA ile yaptım.
Kullandığım temel reçete şöyleydi:
4-bit NF4 ve double quantization
LoRA rank 16, alpha 32
512 token maksimum uzunluk
Micro-batch 1, gradient accumulation 8
Completion-only loss
2e-4learning rate1 epoch ve toplam 484 adım
Eğitim yaklaşık 49 dakika 17 saniye sürdü. Train loss 2,24406, eval loss 2,34028 oldu. Tepe ayrılmış CUDA belleği yaklaşık 4,88 GB, tepe reserved bellek ise yaklaşık 5,22 GB ölçüldü.
Ayrıca 7,5 GiB süreç tavanı altında tek optimizer adımlık ayrı bir smoke test yaptım. Model yüklendi, eğitim adımını attı ve değerlendirmeyi tamamladı.
Fakat burada yine önemli bir dürüstlük payı var: Bu testler 24 GB RTX 3090 üzerinde yapıldı. Bellek kullanımını sınırlamam, tam eğitimi fiziksel bir 8 GB kartta tamamladığım anlamına gelmiyor. “8 GB sınıfını hedefliyor” diyebilirim; “her 8 GB kartta kesin çalışır” diyemem.
İlk ciddi benchmark: küçük ama öğretici
Eğitimden sonra önce proje için hazırladığım 15 örnekli küçük Türkçe test setini kullandım.
Bu set büyük bir akademik benchmark değil. Genel model üstünlüğü iddiası kurmaya da yetmez. Fakat temel model, eğitilmiş Beyefendi ve benzer boyuttaki bağımsız bir rakibi aynı protokolde karşılaştırmak için yararlıydı.
ModelExact MatchToken F1Kriter başarısıToken/snQwen3.5-2B base NF4%6,67%19,61%46,6714,82Beyefendi merged NF4%33,33%48,15%53,3314,75Qwen3-1.7B NF4%0,00%12,43%40,0015,35
En sevindiğim nokta hızın neredeyse aynı kalması oldu. Beyefendi’nin Token F1 skoru base modele göre %19,61den %48,15e çıkarken üretim hızı 14,82 token/sn’den 14,75 token/sn’ye geldi.
Yine de 15 örnek yalnızca bir sinyaldir. Bu tabloya bakıp Beyefendi’nin bütün küçük modellerden daha iyi olduğunu söylemek yanlış olur. Benim çıkarımım daha sınırlı: uyguladığım eğitim, seçtiğim Türkçe görevlerde base modelin davranışını ölçülebilir biçimde değiştirdi.
Şimdilik söyleyebileceğim güçlü cümle bu.
553 soruluk Seneca-TRBench ne söyledi?
Daha geniş bir kontrol için 553 soruluk Seneca-TRBench’i kullandım.
Model / biçimExact MatchToken F1MCQToken/snQwen3.5-2B base NF4%15,91%18,00%54,9612,51Beyefendi final adapter NF4%20,43%23,26%61,839,11Beyefendi F16 GGUF%21,34%25,49%60,3135,34Beyefendi Q4_K_M GGUF%19,53%22,56%54,2047,16
Adapter bileşimi, base modele göre MCQ skorunda yaklaşık 6,87 puanlık mutlak artış gösterdi. F16 GGUF ise Token F1 ve Exact Match tarafında tablonun en iyi sonucunu verdi.
Bu dört satırın hepsini tek bir hız ligi gibi okumamak gerekiyor. Transformers ve Ollama farklı backend’ler, üretim sınırları da tamamen aynı değil. Fakat aynı Ollama hattındaki F16 ve Q4 karşılaştırması bana çok daha ilginç bir şey gösterdi.
Küçültmek her zaman kazanmak değildi.
Q4 daha küçük ve hızlıydı, ama bir şeyler kayboldu
Birleştirilmiş modeli iki GGUF biçimine dönüştürdüm:
BiçimDosya boyutuSeneca Token F1Seneca MCQF163,78 GB%25,49%60,31Q4_K_M1,27 GB%22,56%54,20
Q4_K_M doğal olarak çok daha küçüktü ve aynı Ollama benchmarkında daha hızlıydı. İlk bakışta bunu varsayılan sürüm yapmak mantıklı görünüyordu.
Sonra gerçek cevaplara baktım.
8 GB hedefini yaklaşık olarak sınamak için 24 GB kartta model yüklenmeden önceki GPU kullanımını çıkardım ve yalnızca iş yükünün ek tepesini ölçtüm. F16 yaklaşık 4.059 MiB, Q4_K_M ise 1.661 MiB ek tepe kullandı. İkisi de 8.192 MiB bütçenin altında kaldı.
Fakat semantik testte sonuç değişti:
F16; 2K, 4K ve 8K çok turlu testlerin üçünü de geçti.
Q4_K_M yalnızca 4K testini geçti.
Q4 kısa testte Türkiye’nin başkentini İstanbul olarak söyledi.
Q4, 8K çok turlu testte istenen hatırlama ve biçim davranışını da tam karşılamadı.
Bu, projenin benim için en önemli derslerinden biriydi.
Benchmark ortalamasına ve dosya boyutuna bakarak Q4’ü rahatlıkla “başarılı” ilan edebilirdim. Runtime çalışıyordu, bellek kullanımı düşüktü ve hız daha yüksekti. Fakat birkaç basit Türkçe cevap, tablonun gizlediği problemi ortaya çıkardı.
Bazen model çalışır ama doğru çalışmaz.
Bu ikisi aynı şey değil.
Bu nedenle mevcut durumda tercihim şöyle:
Kalite ve düşük ölçülmüş VRAM dengesi için merged Transformers NF4
Yerel GGUF güvenilirliği için F16
En küçük ve hızlı deneysel seçenek olarak Q4_K_M
Q4 sürümünü kalite onaylı varsayılan model olarak görmüyorum.
Beyefendi en kısa zamanda açık kaynak olacak
Teknik olarak model dosyaları, GGUF çıktıları, checksum’lar ve yeniden üretme adımları hazır.
Şu anda son paketleme ve yayımlama adımlarını tamamlıyorum. Beyefendi’yi en kısa zamanda Hugging Face’e yükleyeceğim ve proje açık kaynak olarak herkesin erişimine açılacak.
Amacım yalnızca model ağırlıklarını paylaşmak değil. Kullanılan veri hattını, eğitim reçetesini, benchmark sonuçlarını ve modelin sınırlamalarını da açık biçimde yayımlamak istiyorum. Böylece isteyen herkes modeli kendi bilgisayarında deneyebilecek, sonuçları inceleyebilecek ve projeye katkıda bulunabilecek.
İlk açık kaynak sürümde en güvenilir seçenekleri öne çıkarmayı planlıyorum. Transformers NF4 kalite ve bellek dengesi için, F16 GGUF ise yerel kullanım için ana seçenek olacak. Q4_K_M sürümünü de deneysel niteliği ve ölçtüğüm kalite gerilemesi açıkça belirtilerek ele alacağım.
Kısacası Beyefendi çok yakında Hugging Face’te olacak. Bu proje kapalı bir deney olarak kalmayacak; en kısa zamanda tamamen açık kaynak hâle gelecek.
Bu projeden geriye ne kaldı?
Başlangıçta küçük bir Türkçe model yapmak istiyordum.
Sonunda veri lisanslarını okudum, tekrar ve contamination taramaları yazdım, QLoRA eğitimi yaptım, adapter birleştirdim, GGUF ürettim, Ollama ve llama.cpp ile testler çalıştırdım, iki ayrı benchmark setinde ölçüm aldım ve quantization’ın gerçek cevapları nasıl bozabildiğini gördüm.
Ortaya mükemmel bir model çıkmadı.
Ama ölçebildiğim bir model çıktı.
Nerede güçlendiğini, nerede gerilediğini ve hangi iddiaları henüz kuramayacağımı bildiğim bir model çıktı.
Bence bu, yalnızca iyi görünen bir demo hazırlamaktan daha değerli.
Beyefendi’nin bugünkü özeti benim için şu:
Küçük bir model eğitmek mümkün. Onu gerçekten anlamak ise eğitim bittikten sonra başlıyor.
Bir sonraki adım modeli Hugging Face’e yüklemek, açık kaynak sürümü yayımlamak ve gerçek kullanıcıların farklı donanımlarda aldığı sonuçları görmek olacak.
Bu proje 3090’ın bana verdiği momentumla başladı. Şimdi ise önümde yeni bir soru bıraktı:
Bir sonraki sürümde neyi daha iyi yapabilirim?
Sanırım asıl oyun da burada başlıyor.
Şimdilik kendinize iyi bakın.
I.S.A