چیتشیت
توکنسازی و BPE
Tokenization and BPE
آموزش، انکود و رمزگشایی یک توکنساز BPE در سطح بایت، سپس برش جریان شناسهها به پنجرههای آموزشی.
فهرست مطالب
وظایف
کار و کد| وظیفه | کد |
|---|---|
| آموزش BPE در سطح بایت | train(tokenizer, <corpus>, target_vocab_size=320) |
| انکود با توکنهای ویژه | encode(tokenizer, text, allow_special=True) |
| رمزگشایی شناسهها به متن | decode(tokenizer, ids) |
| ابتدا نرمالسازی یونیکد | unicodedata.normalize("NFKC", text) |
| انکود با tiktoken | `enc = tiktoken.get_encoding("cl100k_base")` then `enc.encode(text)` |
| آموزش با توکنسازهای HF | tokenizer.train(["corpus.txt"], trainer) |
| آموزش SentencePiece | spm.SentencePieceTrainer.train(input="corpus.txt", vocab_size=8000) |
| بارگذاری توکنساز مدل | AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B") |
توکنساز و پایپلاین داده
معماریآموزش ادغامهای BPE
کدpython
tokenizer.initialize(specials) # 256 بایت، سپس شناسههای ویژه
units = _build_initial_units(corpus) # تاپل بایت -> تعداد تکرار کلمه
while tokenizer.vocab_size < target_vocab_size:
pairs = _count_pairs(units) # وزندهیشده با تعداد تکرار کلمه
max_count = max(pairs.values())
candidates = sorted(p for p, c in pairs.items() if c == max_count)
best = candidates[0] # حل تساوی روی جفت
if pairs[best] < 2:
break # عدم تکرار جفتها
new_id = tokenizer._add_token(
tokenizer.vocab[best[0]] + tokenizer.vocab[best[1]]
) # شناسهی آزاد بعدی
tokenizer.merges[best] = new_id # ترتیب همان رتبه است
units = _apply_merge_to_corpus(units, best, new_id)
انکود متن جدید
گامبهگام- ویژههابا
allow_special=True، رشتههای ویژه تحتاللفظی شناسههای رزروشده میگیرند. - پیشتوکنسازیتابع
_pretokenizeمتن را به فاصلهها و توالی کلمات تقسیم میکند. - بایتهاهر تکه به شناسههای بایت UTF-8 خود تبدیل میشود.
- رتبهیافتن پایینترین رتبه ادغام که روی تکه اعمال میشود.
- Mergeجایگزینی آن جفت با شناسه ادغامشدهاش.
- تکرارتوقف هنگامی که هیچ ادغامی از جدول قابل اعمال نباشد.
- اتصالالحاق شناسههای تمام تکهها به ترتیب.
مجموعه داده پنجرهی لغزان
کدpython
usable = num_ids - (context_length + 1) # count_windows
return 1 + usable // stride # 0 وقتی usable < 0 باشد
start = index * self.stride # __getitem__
end = start + self.context_length + 1 # T+1 شناسه
window = self.ids[start:end]
return window[:-1].clone(), window[1:].clone() # ورودی، هدف
generator = torch.Generator()
generator.manual_seed(base_seed + epoch) # ترتیب یکسان در اجرای مجدد
inputs, targets = next(iter(loader)) # (B, T) و (B, T)
الگوریتمها و فرمولها
مفهومها- BPE
- ادغام متوالی پرتکرارترین جفت مجاور تا رسیدن به اندازهی واژگان هدف.
- BPE در سطح بایت
- واژگان پایه دقیقاً 256 بایت. بدون توکن ناشناخته.
- WordPiece
- ادغام بر اساس
count(AB) / (count(A) * count(B)). قطعات ادامه##میگیرند. - Unigram
- شروع با حجم بالا، هرس توکنهایی که حذفشان کمترین افزایش را در درستنمایی لگاریتمی پیکره متنی دارد.
- SentencePiece
- آموزش BPE یا Unigram روی یونیکد خام. فاصله برابر است با
▁. - tiktoken
- انکودر سریع برای واژگانهای ازپیشساخته. آموزش انجام نمیدهد.
- هزینه انکود ساده
- $O(n \cdot \lvert \text{merges} \rvert)$ برای یک کلمه.
- تعداد پنجرهها
max(0, 1 + (N - (T + 1)) // S)برای N شناسه، زمینه T و استراید S.
پیشفرضها و اعداد
پیشفرضها| تنظیم | پیشفرض | نکته |
|---|---|---|
Byte alphabet | 256 | شناسهها برای بایتهای 0x00 تا 0xFF |
GPT-2 vocabulary | 50,257 | 256 بایت، 50,000 ادغام، 1 توکن ویژه |
BERT WordPiece vocabulary | 30,522 | پیشوند ادامهی ## |
Llama 3 vocabulary | 128,256 | BPE در سطح بایت |
GPT-4o vocabulary | 200,019 | انکودینگ o200k_base |
SentencePiece character_coverage | 0.9995 | 0.995 برای ژاپنی |
SlidingWindowDataset stride | context_length | استفاده هنگام None بودن استراید |
make_dataloader num_workers | 0 | برش یک تنسور درون حافظه |
عیبیابی
عیبیابیخروجی نامفهوم مدل پس از استقرار
- علت
- آموزش با واژگان A، استقرار با واژگان B
- راهحل
- بررسی هش فایل توکنساز در CI
«hello» و « hello» شناسههای متفاوتی میگیرند
- علت
- ابهام در فاصله خالی
- راهحل
- تنظیم صریح
add_special_tokensوadd_prefix_space
مدل چت خروجی نامفهوم میدهد
- علت
- تفاوت الگوی چت با زمان آموزش
- راهحل
- تطبیق دقیق با فرمت آموزش
هزینهی 5 تا 10 برابری توکن برای متن غیرلاتین
- علت
- واژگان وابسته به زبان انگلیسی
- راهحل
- آموزش یک واژگان چندزبانه بزرگتر
خطای الگوی
\p{L}- علت
- ماژول
reاستاندارد ویژگیهای یونیکد را پشتیبانی نمیکند - راهحل
- نصب
regex
توکن ویژه به بایت انکود میشود
- علت
- گزینهی
allow_specialغیرفعال است - راهحل
- ارسال
allow_special=True
خطای
KeyErrorبرای شناسه توکن ناشناخته- علت
- شناسه در واژگان موجود نیست
- راهحل
- تنها رمزگشایی شناسههای تولیدشده توسط همین توکنساز
نبود پنجرهی آخر
- علت
- طول انتهای توالی کمتر از T+1 شناسه است
- راهحل
- طبیعی است. برشدهنده آن را حذف میکند
اصطلاحات
اصطلاحها- BPE
- رمزگذاری جفتبایت. ادغام مکرر پرتکرارترین جفت.
- NFKC
- نرمالسازی یونیکد. تبدیل ادغام «fi» به «fi».
- Merge table
- فهرست مرتب ادغام جفتها. همان توکنساز است.
- پیشتوکنسازی
- قواعد جداسازی پیش از BPE، تا ادغامها درون کلمات بمانند.
- نرخ باروری
- میانگین توکن به ازای هر کلمه. 1.0 ایدهآل است.
- نسبت فشردهسازی
- توکنهای تولیدشده تقسیم بر بایتهای ورودی. کمتر بهتر است.
- الگوی چت
- فرمت مختص مدل برای تبدیل پیامها به یک توالی فلت توکن.
- توکنهای ویژه
- شناسههای رزروشده که BPE را دور میزنند، مانند [BOS]، [EOS] و [PAD].
پرسشها
پرسش و پاسخ- چرا الفبای بایتی؟
- هر ورودی UTF-8 پیش از هر ادغامی در واژگان جا میگیرد. بدون توکن ناشناخته.
- چرا پیشتوکنسازی؟
- بدون آن، ادغامها از مرز کلمات عبور کرده و واژگان را با عبارات پر میکنند.
- چرا اعمال ادغامها به ترتیب رتبه؟
- انکودینگ در این صورت قطعی شده و با آموزش مطابقت دارد.
- واژگان بزرگ یا کوچک؟
- واژگان بزرگ توالیهای کوتاهتر اما ماتریس امبدینگ بزرگتری میدهد.
- چرا سید دادن به برزدن؟
- تا دو اجرا با تفاوت در یک هایپرپارامتر، ترتیب دادهی یکسانی ببینند.
نکات
نکتهها- بررسی رفتوبرگشت روی متن دیدهنشده، یک ایموجی و رشتهی تحتاللفظی <|endoftext|>.
- اندازهگیری نسبت فشردهسازی روی متن نگهداشتهشده، نه روی پیکره متنی آموزش.
- یکبار انکود کردن پیکره متنی در زمان ساخت، سپس برش جریان شناسهها.
- درج شناسههای <|endoftext|> بین اسناد.
- استفاده از استراید برابر با طول زمینه برای پیکره متنی بزرگ.
- تنظیم اندازهی واژگان متناسب با مدل: 32 هزار برای زیر 1 میلیارد پارامتر، 50 تا 100 هزار برای 1 تا 10 میلیارد.