Tokenization və training data
Tokenization və training data
Əvvəlki fəsildə transformer-in token ID-lərindən başladığını qəbul etdik. Bu fəsil sualı bir addım geri çəkir: mətn ID-lərə necə çevrilir və model hansı mətnləri görür? Hər ikisi arxitekturadan az diqqət çəkir, amma model-in nəyi bacardığına ən az onun qədər təsir edir. Pis tokenizer müəyyən dillərdə model-i bahalı və zəif edir. Pis data isə heç bir arxitektura ilə düzəldilmir. Domain model-i train edəndə ən çox vaxtınızı da məhz data-ya sərf edəcəksiniz.
Niyə tokenize etmək lazımdır
Model sabit lüğətdən ID-lər qəbul edir. Mətni bu ID-lərə bölməyin üç təbii yolu var və hər birinin problemi var:
- Simvol və ya byte səviyyəsi. Lüğət kiçikdir (256 byte), heç bir söz "naməlum" qalmır. Amma ardıcıllıqlar çox uzanır. O(T²) attention xərcini nəzərə alsaq, bu baha başa gəlir və model hər addımda çox az məna emal edir.
- Söz səviyyəsi. Ardıcıllıqlar qısadır, amma lüğət sonsuzdur. "kitab", "kitablar", "kitablarımızdan" ayrı sözlərdir və yeni yazılan hər söz naməlum olur. Azərbaycan dili kimi aqlütinativ dillərdə bu yanaşma tamamilə çökür.
- Subword səviyyəsi. Tez-tez görünən ardıcıllıqlar tək token olur, nadir sözlər hissələrə bölünür. Bu, bugünkü standartdır.
BPE addım-addım
Ən geniş yayılmış subword alqoritmi BPE (Byte Pair Encoding) belə işləyir:
- Lüğəti tək simvollarla başladın.
- Training korpusunda yan-yana gələn bütün cütləri sayın.
- Ən çox rast gələn cütü yeni token kimi lüğətə əlavə edin və korpusda onun hər rast gəlməsini birləşdirin.
- Lüğət hədəf ölçüyə çatana qədər 2–3-cü addımları təkrarlayın.
Kiçik nümunə: korpus low low low lower lowest olsun. İlk addımda l+o ən çox rast gələn cütdür və lo olur. Sonra lo+w cütü low olur. Daha sonra low+e və s. Nəticədə "low" tək token olur, "lowest" isə low + est kimi bölünür.
Birləşmə qaydaları sıra ilə yadda saxlanılır. Yeni mətni tokenize edəndə eyni qaydalar eyni sıra ilə tətbiq olunur. Bu o deməkdir ki, tokenizer da training-in məhsuludur: onun lüğəti hansı korpusda öyrənilibsə, həmin korpusu əks etdirir. İngilis mətni üstünlük təşkil edən korpusda öyrənilmiş tokenizer ingilis sözlərini tam token edir, qalan dilləri isə xırda hissələrə bölür.
Alternativlər də var. WordPiece (BERT) birləşməni sadə tezlik yox, likelihood artımına görə seçir. Unigram (SentencePiece-də) böyük lüğətdən başlayıb ən az faydalı token-ləri atır. Praktikada generative model-lərin əksəriyyəti BPE-nin variantını istifadə edir.
Byte-level BPE
Simvollardan başlasaq, Unicode-un 150 mindən çox simvolu problem yaradır və görünməmiş emoji naməlum token olur. GPT-2-dən bəri həll belədir: BPE-ni simvollar üzərində deyil, UTF-8 byte-ları üzərində işlətmək. Başlanğıc lüğət düz 256 byte-dır, deməli istənilən mətn, istənilən dil və ya binary zibil həmişə tokenize oluna bilər. Ən pis halda hər byte bir token olur. Byte-level BPE-dən əvvəl adətən pre-tokenization gəlir: regex mətni sözlərə, rəqəmlərə və durğu işarələrinə bölür ki, birləşmələr söz sərhədini keçməsin.
Lüğət ölçüsü
Lüğət ölçüsü bir trade-off-dur:
| Kiçik lüğət (32K) | Böyük lüğət (128K–256K) | |
|---|---|---|
| Ardıcıllıq uzunluğu | uzun | qısa |
| Embedding və unembedding matrix-i | kiçik | böyük |
| Nadir token-lərin training-i | yaxşı | zəif (bəzi token-lər az görünür) |
| Çoxdilli əhatə | zəif | yaxşı |
Tendensiya böyük lüğətlərə doğrudur: Llama 2-də 32K, Llama 3-də 128K, Gemma-da 256K. Səbəb sadədir: daha qısa ardıcıllıq eyni compute-la daha çox mətn emal etmək, daha ucuz inference və daha geniş effektiv context deməkdir. Kiçik model-lərdə isə embedding matrix-i parametrlərin xeyli hissəsini tuta bilər, ona görə orada lüğəti şişirtmək baha başa gəlir.
Tokenizer-in gizli təsirləri
Tokenizer seçimi model davranışında gözlənilməz izlər qoyur.
Rəqəmlər. "12345" köhnə tokenizer-lərdə "123" + "45", başqa kontekstdə isə "1" + "2345" kimi bölünə bilərdi. Model eyni rəqəmi fərqli formalarda görür və arifmetika çətinləşir. Müasir tokenizer-lər rəqəmləri ya tək-tək, ya da üçlük qruplarla sabit şəkildə bölür.
Qeyri-ingilis dilləri. Eyni məzmun müxtəlif dillərdə çox fərqli sayda token tutur. Azərbaycan dilində ingilis dilinə nisbətən 1.5–3 qat çox token alınması adi haldır və nisbət tokenizer-dən asılıdır. Bunun praktik nəticələri var: hər sorğu daha bahadır, context window effektiv olaraq kiçilir, model həmin dili pretraining zamanı da "az token-lə" görüb. Azərbaycan dili üçün model seçəndə ilk testlərdən biri belə olmalıdır: eyni paraqrafı bir neçə tokenizer-dən keçirib token sayını müqayisə edin.
Boşluqlar və böyük hərflər. " Hello", "Hello" və "HELLO" fərqli token-lərdir. Prompt-un sonunda artıq boşluq model-in növbəti token paylanmasını dəyişə bilər.
Special token-lər. <|begin_of_text|>, <|eot_id|> kimi token-lər mətndən gəlmir, struktur siqnalıdır: sənədin başlanğıcı, növbənin sonu, tool çağırışı. İstifadəçi mətnində təsadüfən və ya qəsdən bu sətirlər olarsa, onlar special token kimi parse olunmamalıdır. Bu, prompt injection-un aşağı səviyyəli bir formasıdır.
Chat template-lər. Assistant model-ləri söhbəti xüsusi formatda görüb öyrənib: rol başlıqları, special token-lər, növbə ayırıcıları. Hər model ailəsinin öz template-i var. Fine-tuning və inference zamanı ən çox rast gəlinən səssiz xətalardan biri yanlış template istifadə etməkdir. Model işləyir, amma nəzərəçarpacaq dərəcədə pis işləyir. Qayda belədir: template-i həmişə model-lə gələn tokenizer konfiqurasiyasından götürün, əl ilə yığmayın.
Pretraining data-sının mənbələri
Müasir foundation model-lər 15–40 trilyon token üzərində train olunur. Bu data əsasən aşağıdakı mənbələrdən gəlir:
- Veb crawl. Ən böyük mənbədir. Common Crawl hər ay milyardlarla səhifə toplayır. Xam halda çox səs-küylüdür: menyular, reklamlar, spam, dublikatlar.
- Kod. Açıq repository-lər. Kod yalnız proqramlaşdırma üçün deyil, ümumi reasoning qabiliyyəti üçün də faydalı hesab olunur.
- Elmi və akademik mətnlər. Məqalələr, preprint-lər.
- Kitablar, ensiklopediyalar və istinad mətnləri. Yüksək keyfiyyətli, uzun və ardıcıl mətn. Lisenziya məsələləri ən çox burada qızışır.
- Synthetic data. Daha güclü model-in yaratdığı mətnlər, məsələn dərslik üslubunda izahlar və ya həll olunmuş tapşırıqlar. Bu mənbənin payı sürətlə artır, ikinci hissədə ətraflı baxacağıq.
FineWeb, DCLM, Dolma kimi açıq dataset-lər və onların texniki hesabatları pipeline-ın hər addımını sənədləşdirir. Domain data-sı hazırlayarkən onlar ən yaxşı istinad mənbəyidir.
Data pipeline
Xam veb-dən training korpusuna gedən yol ardıcıl filtrlərdən ibarətdir. Hər mərhələ data-nın böyük hissəsini atır. Veb mətninin son korpusa düşən payı çox vaxt 10%-dən azdır.
1. Extraction. HTML-dən əsas mətni çıxarmaq: naviqasiya, footer, reklam bloklarını atmaq. Bu addım sadə görünür, amma keyfiyyətə çox təsir edir. Common Crawl-un hazır mətn versiyası (WET) xam HTML-dən yaxşı extractor ilə alınan mətndən nəzərəçarpacaq dərəcədə pisdir.
2. Language identification. fastText tipli sürətli classifier hər sənədin dilini və əminlik balını təyin edir. Çoxdilli model üçün bu addımda hər dilin payı da məlum olur. Azərbaycan dili kimi az resurslu dillərdə classifier-in səhvləri (türk dili ilə qarışdırmaq, latın/kiril qarışıqlığı) əl ilə yoxlanmalıdır.
3. Heuristic filtrlər. Ucuz qaydalar zibilin böyük hissəsini atır. Məsələn: çox qısa sənədlər, simvol/söz nisbəti qəribə olanlar, sətirlərin çoxu nöqtə ilə bitməyənlər, eyni sətrin təkrarlandığı səhifələr, "lorem ipsum" və ya "cookie" boilerplate-i. Gopher və C4 qaydaları klassik nümunədir.
4. Model-based quality filtering. Kiçik classifier sənədin "yaxşı" mətnə nə qədər bənzədiyini qiymətləndirir. "Yaxşı" anlayışı istinad korpusu ilə müəyyən olunur. FineWeb-Edu bu yanaşmanı göstərdi: güclü LLM bir neçə yüz min sənədi "təhsil dəyəri" üzrə qiymətləndirdi, bu etiketlərlə kiçik classifier öyrədildi, sonra classifier milyardlarla sənədə tətbiq olundu. Data-nın yüksək ballı hissəsi ilə train edilən model-lər benchmark-larda xeyli irəlidədir. Risk də var: classifier-in zövqü korpusun zövqünə çevrilir və müxtəliflik daralır.
5. Deduplication. Veb-də eyni mətn minlərlə dəfə təkrarlanır. Dublikatlar compute-u israf edir, memorization-ı gücləndirir və evaluation-ı çirkləndirir.
- Exact dedup: normallaşdırılmış mətnin hash-i. Sürətlidir, amma bir vergülü fərqli olan nüsxələri tutmur.
- Near-duplicate dedup (MinHash + LSH): sənəd n-gram-lar çoxluğuna çevrilir. MinHash bu çoxluğu qısa imzaya sıxır və iki imzanın üst-üstə düşmə payı Jaccard oxşarlığını təxmini göstərir. LSH oxşar imzaları eyni "bucket"-ə salır ki, milyardlarla sənədi cüt-cüt müqayisə etmək lazım olmasın. Adətən 0.7–0.8 oxşarlıqdan yuxarı olanlar dublikat sayılır.
# MinHash ideyası: k təsadüfi hash funksiyası, hər biri üçün ən kiçik dəyər
def minhash(shingles, hash_fns):
return [min(h(s) for s in shingles) for h in hash_fns]
def est_jaccard(sig_a, sig_b):
return sum(a == b for a, b in zip(sig_a, sig_b)) / len(sig_a)
6. PII və toxicity. E-mail, telefon nömrəsi, IP kimi şəxsi məlumatlar regex və NER ilə maskalanır. Toksik və ya qeyri-qanuni məzmun classifier-lərlə və domen blok siyahıları ilə çıxarılır. Burada balans lazımdır: toxicity filtri çox aqressiv olarsa, model müəyyən dialektləri və mövzuları ümumiyyətlə görmür və sonra onları başa düşmür.
Data mixture
Təmizlənmiş data-nın hansı mənbədən nə qədər götürüləcəyi ayrıca qərardır: veb, kod, riyaziyyat, çoxdilli mətn, kitablar. Mixture model-in xarakterini müəyyən edir. Kod payını artırmaq reasoning-i gücləndirir, amma müəyyən həddən sonra təbii dil keyfiyyəti düşə bilər. Az resurslu dilin payını artırmaq həmin dili yaxşılaşdırır, lakin data azdırsa, onu çox epoch təkrarlamaq lazım gəlir və bu da memorization riski yaradır. Mixture adətən kiçik proxy model-lərdə eksperimentlərlə seçilir. Training-in sonunda isə yüksək keyfiyyətli data-nın payı artırılır (annealing), bu da son nəticəyə nəzərəçarpacaq dərəcədə təsir edir.
Contamination: ilk xəbərdarlıq
Benchmark sualları və cavabları internetdə dərc olunur və veb crawl onları korpusa gətirir. Model test sualını training zamanı görübsə, yüksək bal onun bacarığını deyil, yaddaşını ölçür. Buna contamination deyilir. Ciddi pipeline-lar benchmark-larla n-gram overlap yoxlaması aparır və uyğun sənədləri çıxarır. Bu kifayət deyil, çünki parafraz edilmiş və ya tərcümə olunmuş nüsxələr qalır. Səkkizinci fəsildə evaluation-ı bu problemə davamlı etməyin yollarına baxacağıq. İndilik qayda budur: domain data-nızı topladıqca evaluation set-inizi əvvəlcədən ayırın və training data-nızın ona toxunmadığını yoxlayın.
Tapşırıqlar
- Kiçik bir korpusda (məsələn 1 MB Azərbaycan dilində mətn) sıfırdan BPE implementasiya edin və 1000, 4000, 16000 ölçülü lüğətlər öyrədin. Hər biri üçün eyni test paraqrafının token sayını və ən uzun 20 token-i yazın. Hansı morfemlər tək token olur?
- Eyni 500 sözlük Azərbaycan dilində və ingilis dilində mətni üç fərqli açıq model-in tokenizer-indən keçirin. Token/söz nisbətini cədvəldə göstərin və hansı model-in bu dil üçün ən səmərəli olduğunu əsaslandırın.
- 10 000 veb sənədindən ibarət nümunədə mini-pipeline qurun: language ID, üç heuristic filtr, exact dedup və MinHash dedup. Hər mərhələdən sonra neçə sənədin qaldığını və hər filtrin atdığı sənədlərdən 5 təsadüfi nümunəni yazın. Haqsız atılanlar varmı?