Karakter, Sözcük, Subword: Tokenization Tasarım Baskıları ve Karar Matrisi
Tokenization tasarım uzayı: karakter-level (UTF-8, byte), sözcük-level (whitespace, morfoloji), subword (BPE, WordPiece, Unigram). Her seçimin matematiksel ve pragmatik trade-off'ları, OOV problemi, vocabulary size karar matrisi, multilingual zorlukları, Türkçe karakteristikleri.
Şükrü Yusuf KAYA
55 dakikalık okuma
Orta🔤 LLM'in 'dili'nin doğuşu
Tokenization, modern LLM'in en az anlaşılan ama en kritik karar noktası. Yanlış tokenizer → milyarlarca parameter israfı. Bu ders tasarım uzayını tam keşfediyor: niye karakter-level yetmedi, niye sözcük-level başarısız, niye subword kazandı. 55 dakika sonra: tokenization seçiminin LLM eğitimini, inference cost'unu, multilingual coverage'ını nasıl şekillendirdiğini tam kavrayacaksın.
Ders Haritası#
- Tokenization'ın temel sorusu
- Karakter-level: UTF-8, byte, avantaj/dezavantaj
- Sözcük-level: whitespace tokenization sınırları
- OOV (Out-of-Vocabulary) problemi
- Morfolojik dillerin (Türkçe) zorluğu
- Subword approach: BPE/WordPiece/Unigram doğuşu
- Vocabulary size trade-off matrisi
- Multilingual tokenization
- Modern karar: niye herkes subword'e geçti
- Tasarım karar matrisi
1. Tokenization'ın Temel Sorusu#
LLM girdi olarak discrete sequence alır:
"Merhaba dünya" → [token_id_1, token_id_2, ...]
Bu çeviri tokenization. Soru: bir "token" ne kadar büyük olmalı?
Üç ana yaklaşım#
| Yaklaşım | Token örneği | Vocab boyutu |
|---|---|---|
| Karakter | 'M', 'e', 'r', 'h', 'a', 'b', 'a' | ~100-256 |
| Sözcük | 'Merhaba' (tek token) | ~50K-500K+ |
| Subword | 'Mer', 'ha', 'ba' (parçalar) | ~32K-128K |
Trade-off matrisi#
| Faktör | Karakter | Sözcük | Subword |
|---|---|---|---|
| Vocab size | Küçük (256) | Çok büyük | Orta (32K-128K) |
| Sequence length | Çok uzun | Çok kısa | Orta |
| OOV problem | Yok | Büyük | Yok (byte fallback) |
| Morfoloji handling | Doğal | Zayıf (Türkçe için) | İyi |
| Embedding parameter | Az | Çok | Orta |
| Compute per char | Pahalı | Ucuz | Orta |
Niye subword "kazandı"?#
Modern LLM (GPT, Llama, Claude, Qwen) — hepsi subword. Niye? Üç ana sebep:
- OOV yok: subword fallback ile karakter seviyesine kadar inebilir
- Compute-efficient: sözcük level kadar kompresyon, karakter seviyesinde flexibility
- Morphology-aware: "yürüyorum" → "yürü" + "yor" + "um" doğal yapı
Bu modülün devamında subword'ün nasıl elde edildiğini detaylı işleyeceğiz.
2. Karakter-Level Tokenization#
En basit yaklaşım: her karakter ayrı token.
UTF-8 vs Unicode codepoint#
Unicode: ~149K karakter. Token başına 1 codepoint. Vocab boyutu büyük.
UTF-8 bytes: 256 unique byte. Her karakter 1-4 byte kombinasyonu. Vocab sabit 256.
text = "Merhaba" # Unicode codepoints codepoints = [ord(c) for c in text] # UTF-8 bytes bytes_repr = text.encode("utf-8") print(list(bytes_repr)) # [77, 101, 114, 104, 97, 98, 97]
Avantajlar#
- OOV yok: her input encodable
- Vocab küçük: 256 byte yeterli
- Multilingual native: hiçbir dil özel
- Embedding parameter az: 256 × d_model
Dezavantajlar#
- Sequence çok uzun: "Merhaba" 7 token vs 1 token
- Compute pahalı: attention O(N²) — N büyük olduğunda dramatic
- Semantik birim eksik: "yürüyorum" 10 karakter → model her bir karakteri ayrı işliyor
Pratik etki#
Karakter-level Llama 3 8B fine-tune denemesi: training 3x daha yavaş (sequence 3-4x daha uzun) ve quality eşit veya daha az.
Niye yine de niş kullanım?:
- Char-level RNN (Karpathy 2015, blog post viral oldu) — pedagogical
- TinyStories experiments (small model proof of concept)
- Some specialized domains (DNA, code chars)
Modern hibrit: ByT5#
Google ByT5 (Xue 2022): tam byte-level T5. Sequence uzun ama:
- No OOV ever
- Robust to typos (yazım hatalarına dayanıklı)
- No tokenizer: dataset preprocessing yok
Ama pratikte çok yavaş → niş kullanım.
Niçin karakter-level Llama / GPT olmadı?#
Compute economics. Llama 3 8B'i karakter-level eğitmek:
- Sequence length 4x → attention 16x → training 16x daha pahalı
- Aynı budget'ta küçük model + bigger context çıkıyor
- Karakter-level'in "robust to typos" avantajı ise modern LLM zaten dayanıklı
python
# Karakter tokenization vs UTF-8 byte tokenizationtext = "Merhaba dünya! 🌍" # Karakter-level (Unicode)char_tokens = list(text)print(f"Char count: {len(char_tokens)}") # 17print(char_tokens) # UTF-8 byte-levelbyte_tokens = list(text.encode("utf-8"))print(f"Byte count: {len(byte_tokens)}") # 20 (Türkçe + emoji extra bytes)print(byte_tokens) # Karşılaştırma# Char-level vocab: 256+ unique character (alfabe + emoji + diakritik)# Byte-level vocab: SABIT 256 # Türkçe charactersturkish_chars = "şğüöçıİ"for c in turkish_chars: print(f"'{c}': codepoint={ord(c)}, bytes={list(c.encode('utf-8'))}")# 'ş': codepoint=351, bytes=[197, 159] -> 2 byte# 'ğ': codepoint=287, bytes=[196, 159] -> 2 byte# UTF-8'de Türkçe karakter 2 byteKarakter vs byte tokenization karşılaştırma.
3. Sözcük-Level Tokenization#
İkinci yaklaşım: whitespace + punctuation ile böl.
Implementation#
import re def word_tokenize(text): # Whitespace + punctuation split tokens = re.findall(r"\w+|[^\w\s]", text, re.UNICODE) return tokens print(word_tokenize("Merhaba dünya! Nasılsın?")) # ['Merhaba', 'dünya', '!', 'Nasılsın', '?']
Avantajlar#
- Compact: cümle başına az token
- Semantik birimler: kelimeler anlam birimi
- Eğitim hızlı: kısa sequence = az compute
Dezavantajlar — büyük#
1. OOV problemi
Eğer "elektromanyetik" eğitim corpus'ta yoksa → token. Model bu kelime hakkında hiçbir şey bilmiyor.
<UNK>"Elektromanyetik radyasyon" → ["<UNK>", "radyasyon"]
2. Vocab patlaması
İngilizce ~170K kelime. Türkçe ne kadar? Sonsuza yakın (morfolojik dil).
ev, evim, evler, evlerim, evimde, evlerimde, evimden, evlerimden, evimdeki, ...
Tek "ev" kökünden 100+ form. 50K vocab'a 100K kelime form sığmaz → çoğu OOV.
3. Morfoloji bilgisi kaybı
"yürüyorum" tek token ise model "yürü" + "-yor" + "-um" yapısını öğrenemez. "yürüdüm" ayrı token, ilişki kayıp.
4. Compound words
Almanca: "Donaudampfschifffahrtsgesellschaft" — tek kelime. OOV.
Türkçe: "Avrupalılaştıramadıklarımızdan" — tek kelime. OOV.
5. Tokenization karşılığı dil-bağımlı
- Türkçe/Almanca: agglutinative, morfoloji rich → çok OOV
- Çince/Japonca: hiç whitespace yok → tokenization belirsiz
- Arapça: rich morphology + script
Pratik etki#
1990-2010 NLP yaygın yöntem. 2014 sonrası subword'e geçildi.
Modern relevance#
Word-level legacy. Bazı domain'lerde hâlâ (örn. classical search indexing) ama LLM için terk edilmiş.
4. OOV (Out-of-Vocabulary) Problemi Derin#
OOV problemini biraz daha kazıyalım — niye fatal?
OOV nedir?#
Eğitim sırasında vocab'a alınmayan kelime → token.
<UNK>LLM için sonuç#
Model ile karşılaşınca:
<UNK>- Embedding generic — anlam yok
- Output: üretemiyor (genelde) → invalid output
<UNK> - Information loss
Numerical example#
"COVID-19 pandemic" cümlesi 2019 öncesi eğitilmiş model'e:
"COVID-19" → not in vocab → <UNK> "pandemic" → in vocab
Model "COVID" kavramı hakkında hiçbir şey bilmiyor.
Workarounds (subword öncesi)#
- Limited word generation: sadece common words. Yaratıcılık limitli.
- Character backup: OOV → character split. Niş.
- Stemming: "running" → "run". Lossy.
- Lemmatization: "ran" → "run". Lossy.
Subword devrim#
BPE/WordPiece OOV problemini matematik olarak çözüyor:
- "COVID-19" → ["CO", "VID", "-", "19"] — known subwords
- "Avrupalılaştıramadıklarımızdan" → ["Avrupa", "lı", "laş", "tır", "amad", "ık", "lar", "ım", "ız", "dan"]
Her input encodable, OOV concept'i ortadan kalktı.
Modern view#
Byte-level BPE (Modül 6.6) ile OOV matematiksel olarak imkansız — vocab byte'lara kadar fallback.
Bu yüzden modern LLM'ler token kullanmaz.
<UNK>5. Morfolojik Dillerin (Türkçe) Zorluğu#
Türkçe agglutinative dil — kök + suffix'ler kombinasyonu. Bu tokenization için zor.
Türkçe morfoloji örneği#
Kök: "ev"
ev (house) evim (my house) — +1 suffix evimde (in my house) — +2 suffix evimdeki (the one in my house) — +3 suffix evimdekinin (of the one in my house) — +4 suffix evimdekileri (the ones in my house, accusative) — +5 suffix
Bir kökten yüzlerce form. Word-level vocab patlar.
Diğer agglutinative diller#
- Fince: 15 case × 2 sayı = 30 form per kelime
- Macarca: similar
- Korece: agglutinative + 7 honorific level
- Japonca: agglutinative verbs + particle
- Quechua, Aymara (Güney Amerika)
Subword'ün başarısı#
Subword tokenizer "ev" + "imdekinin" gibi anlamlı parçalara böler. Model:
- "ev" kavramını öğrenir
- "-imde-" possessive + locative pattern'i öğrenir
- "Avrupalılaş-" gibi compound pattern'leri öğrenir
Türkçe-İngilizce karşılaştırma#
| Cümle | İngilizce | Türkçe |
|---|---|---|
| "Ben evdeyim" | 3 word, ~3 token | 2 word, ~5 token (BPE) |
| "Walking" | 1 word, 1 token | "Yürüyorum" 1 word, 3-4 token |
| Average ratio | 1 | 2-3x more tokens |
Pratik etki#
GPT-4o ile aynı paragraf:
- İngilizce 100 token → $0.0125
- Türkçe 250 token → $0.0313 (2.5x cost)
Bu token economics Modül 4.2'de detaylı işlendi. Burada amacımız tokenizer tasarımı açısından bakış.
Çözüm: Türkçe-tuned tokenizer#
Modül 6.9'da detaylı işleyeceğiz: Türkçe corpus üzerinde BPE training → daha verimli Türkçe tokenization. Token oranı %30-40 düşürülebilir.
6. Subword Approach Doğuşu#
Karakter çok küçük, sözcük çok büyük → arada bir şey gerek. Subword.
Tarihsel evrim#
2015: BPE for NMT (Sennrich)
Rico Sennrich, Barry Haddow, Alexandra Birch — "Neural Machine Translation of Rare Words with Subword Units", ACL 2016 (preprint 2015).
Orijinal BPE (Byte Pair Encoding) Philip Gage 1994 — compression algorithm. Sennrich NLP'ye uyguladı.
2016: WordPiece (Google)
Schuster & Nakajima — BERT'in tokenizer'ı. Likelihood-based subword.
2018: SentencePiece (Google)
Kudo & Richardson — language-agnostic, no pre-tokenization. Unigram LM alternatifi.
2019: GPT-2 byte-level BPE
OpenAI — UTF-8 byte level + BPE. UNK ortadan kalktı.
Common ground#
Hepsinin ortak özelliği:
- Sub-word units: kelimeleri parçalara böl
- Frequency-driven: yaygın pattern'ler tek token, nadirler parçalanmış
- No OOV: fallback'le her input encodable
- Learned from corpus: training data'dan vocab inşa
Algorithm farkları#
| Algorithm | Loss function | |
|---|---|---|
| BPE | Greedy merge | Frequency-based |
| WordPiece | Greedy merge | Likelihood-based |
| Unigram | Probabilistic | Marginal likelihood |
| SentencePiece | (framework, BPE veya Unigram backend) | - |
Modül 6.2-6.5'te her birini detaylı işleyeceğiz.
7. Vocabulary Size Trade-off Matrisi#
Subword tokenization parametresi: vocab size. Hangi değer optimum?
Trade-off#
| Vocab size | Avantaj | Dezavantaj |
|---|---|---|
| 8K (small) | Az embedding param, hızlı softmax | Daha çok token per cümle, weak compression |
| 32K (medium) | İyi denge | Standard, optimal değil |
| 64K-128K (large) | Az token per cümle, daha çok compression | Çok embedding param, slow softmax |
Math#
- Embedding layer parameters:
V × d_model - Output projection:
V × d_model - Softmax compute: O(V) — vocab büyüdükçe yavaşlar
Llama 3 70B: V = 128K, d = 8192. Embedding parametre: 128K × 8192 = 1B (model'in %1.4'ü).
Modern LLM vocab boyutları#
| Model | Vocab | Notlar |
|---|---|---|
| GPT-2 | 50,257 | Byte-level BPE |
| GPT-3 | 50,400 | GPT-2'ye yakın |
| GPT-4 (cl100k) | 100K+ | Multilingual improved |
| GPT-4o, GPT-5 (o200k) | 200K | Daha çok multilingual coverage |
| Llama 2 | 32K | İngilizce-odaklı |
| Llama 3 | 128K | Multilingual |
| Llama 3.1+ | 128K | Same |
| Qwen 2.5 | 152K | Çince-İngilizce odaklı |
| DeepSeek-V3 | 129K | Multilingual + code |
| Mistral 7B | 32K | İngilizce |
| Gemma 2 | 256K | Çok büyük, multilingual |
Trend#
Modern LLM'lerde vocab büyüyor: 32K → 128K → 256K. Niye?
- Multilingual coverage: birçok dilde verimli olması
- Code support: programming language tokenization
- Less tokens per message: cost economics
- Compute olmuş ucuz: parameter artışı tolere edilebilir
Türkçe için optimal#
Türkçe-only model: 50K-80K range optimal. Multilingual: 128K-256K (Türkçe coverage için 256K daha iyi).
Modül 6.9-6.10 detayda işliyor.
8. Multilingual Tokenization#
Modern LLM multilingual. Tokenizer çoklu dil destekler.
Naive approach: per-language tokenizer#
Her dil için ayrı tokenizer. Multilingual model için 20+ tokenizer. Kompleks, vocab birleştirme zor.
Modern approach: unified BPE#
Tek tokenizer, tüm dilleri kapsayan corpus üzerinde train.
Multilingual corpus: English 60% + Chinese 15% + Spanish 5% + ... + Turkish 0.5% BPE training → unified vocab
Sorun: dil dağılımı#
Eğer corpus İngilizce-heavy ise:
- English tokens efficient
- Turkish tokens inefficient (vocab Türkçe pattern'leri öğrenmedi)
Sayısal örnek (GPT-4 cl100k)#
"Hello world" → 2 tokens "Merhaba dünya" → 4 tokens (2x)
"I love programming" → 4 tokens "Programlamayı seviyorum" → 8 tokens (2x)
Modern çözümler#
- Balanced multilingual corpus: training corpus'ta dil dağılımı dengeli (her dile minimum %X)
- Per-language vocab quota: BPE training'de her dil için minimum vocab garanti
- Larger vocab: 200K+ ile her dile coverage
Empirik#
GPT-4o (o200k tokenizer) Türkçe için GPT-4 cl100k'dan ~%25 daha iyi. Türkçe pattern'ler daha çok vocab'a alınmış.
Multilingual paradox#
Aynı vocab tüm dilleri destekliyor ama:
- Yüksek-resource dil (English): mükemmel
- Düşük-resource dil (Türkçe, Vietnamca, Swahili): orta
- Çok düşük-resource dil (örn. Quechua): zayıf
Modül 6.9'da Türkçe-specific optimization detayda.
9. Modern Karar: Niye Herkes Subword'e Geçti#
2026 itibarıyla frontier LLM'lerin %100'ü subword tokenization kullanıyor. Niye?
Pros sübword#
- OOV yok (byte-level fallback)
- Compact: sözcük-level'a yakın compression
- Flexible: yeni kelimeleri handle ediyor
- Morfoloji-aware: agglutinative dillerde semantik koruma
- Code-friendly: programming language constructs (functions, operators)
- Multilingual unified: tek tokenizer her dile
Cons çözümleri#
| Sorun | Çözüm |
|---|---|
| Sequence biraz uzun (sözcükten daha uzun) | OK — character'dan çok daha kısa |
| Vocab tuning gerek | Modern best practices well-known |
| Glitch tokens (SolidGoldMagikarp) | Modern training'de filtered |
| Türkçe efficiency | Türkçe-tuned variants mevcut |
Alternative attempts#
Byte-level pure (ByT5 2022)
Sequence çok uzun → compute prohibitive. Niş kullanım.
MegaByte (Yu 2023)
Byte-level transformer ama hierarchical → büyük model lazım. Mainstream değil.
Token-free transformers (CANINE, 2022)
Karakter-level + downsampling. Mainstream değil ama interesting research.
Karar#
Subword mainstream ve önümüzdeki 5-10 yıl baskın kalacak. Modül 6.2'den başlayarak BPE'yi sıfırdan inşa edeceğiz.
10. Tasarım Karar Matrisi#
Bir LLM project için tokenizer seçimi:
Senaryo 1: General-purpose LLM (Llama-class)#
- Algorithm: BPE (byte-level)
- Vocab size: 32K-128K
- Pre-tokenization: word + punctuation
- Training corpus: balanced multilingual
- Examples: Llama 3, GPT-4, Mistral
Senaryo 2: Türkçe-only LLM#
- Algorithm: BPE (byte-level) veya WordPiece
- Vocab size: 64K
- Pre-tokenization: Türkçe-aware word splitting
- Training corpus: Türkçe-heavy (90%+)
- Examples: BERTurk, Trendyol-LLM-tokenizer
Senaryo 3: Code-specialized LLM#
- Algorithm: BPE (byte-level)
- Vocab size: 100K+
- Pre-tokenization: code-aware (identifier, operator splitting)
- Training corpus: Code-heavy (80% code, 20% docs)
- Examples: Codex, StarCoder, DeepSeek-Coder
Senaryo 4: Multilingual translation#
- Algorithm: SentencePiece (BPE or Unigram)
- Vocab size: 250K+
- Pre-tokenization: minimal (language-agnostic)
- Training corpus: parallel multilingual
- Examples: NLLB (Facebook), Google Translate models
Senaryo 5: Embedding model#
- Algorithm: WordPiece veya SentencePiece
- Vocab size: 30K-50K
- Pre-tokenization: word splitting
- Examples: BERT, sentence-transformers
Türk şirket pratiği#
Çoğu Türk şirketi var olan tokenizer kullanıyor (Llama 3 BPE veya BERTurk). Custom tokenizer research / scale projeleri için. Modül 6.10'da custom tokenizer training detayda.
11. Mini Egzersizler#
-
Karakter vs byte: "Şükrü" string'inde karakter ve byte sayısı?
-
OOV scenario: 2019'da eğitilmiş model'e "ChatGPT" verince ne olur (word-level vs subword)?
-
Vocab size karar: Türkçe-only customer support model. Optimal vocab?
-
Multilingual trade-off: 32K vocab İngilizce için yeter ama Türkçe için 80K+ gerek. Niye?
-
Tokenizer pre-tokenization: Code için niye word-level pre-tokenization yetersiz?
Bu Derste Neler Öğrendik?#
✓ Tokenization temel sorusu: karakter vs sözcük vs subword
✓ Karakter-level: UTF-8 byte, vocab sabit 256, sequence uzun, niş kullanım
✓ Sözcük-level: legacy, OOV ölümcül, morfolojik dillerde patlama
✓ OOV problemi: word-level fatal, subword çözüyor
✓ Türkçe morfoloji: agglutinative — word-level imkansız, subword zorunlu
✓ Subword doğuşu: BPE 2015, WordPiece 2016, SentencePiece 2018, byte-level BPE 2019
✓ Vocab size trade-off: modern LLM 32K → 256K range
✓ Multilingual tokenization trade-off'ları
✓ Karar matrisi — 5 senaryo
Sıradaki Ders#
6.2 — BPE Algoritması: Sennrich 2016 Satır Satır
BPE'nin matematiksel detayı. Pseudocode, complexity analizi, training procedure, encoding logic. Sıfırdan implement etmeden önce algoritmayı tam kavrayalım.
Sık Sorulan Sorular
Doğru ama maliyeti çok yüksek. Subword LLM'ler bile **scale'de** typo'lara dayanıklı — eğitim corpus'unda milyonlarca typo gördüler, pattern öğrendiler. Modern LLM 'ChatGPT' yerine 'Chatgtp' veya 'ChatGTP' yazsanız da doğru anlıyor. Karakter-level'in robustness avantajı çoğunlukla **mit**. Pratikte 16-32x compute kaybı buna değmez. ByT5 ve diğer byte-level model'ler niş kaldı.
Yorumlar & Soru-Cevap
(0)Yorum yazmak için giriş yap.
Yorumlar yükleniyor...
İlgili İçerikler
Modül 0: Kurs Çerçevesi ve Atölye Kurulumu
LLM Engineer Kimdir? Junior'dan Staff'a Yapay Zekâ Mühendisliği Kariyer Haritası
Öğrenmeye BaşlaModül 0: Kurs Çerçevesi ve Atölye Kurulumu
Kurs Felsefesi: Neden Bu Yol, Neden Bu Sıra — 8 Aylık Müfredatın İskeleti
Öğrenmeye BaşlaModül 0: Kurs Çerçevesi ve Atölye Kurulumu