مستوى المقال: مبتدئ — مكتوب لأي حد لسه بيتعرّف على نماذج اللغة، بالأمثلة الأول وبعدين العلم.
الـ Tokenization: ليه الذكاء الاصطناعي مش بيشوف الحروف زيّك
بعد المقال ده هتفهم بالظبط ليه ChatGPT بيغلط لما تسأله "كام حرف r في كلمة strawberry"، وهتعرف تحسب تكلفة أي نص قبل ما تبعته للنموذج.
المشكلة باختصار
اسأل أي نموذج لغة كبير: "how many r's are in strawberry". لفترة طويلة كان بيرد باتنين، والإجابة الصح تلاتة. الغلطة دي مش لأن النموذج غبي. هي لأنه أصلاً مش بيشوف الحروف. بيشوف حاجة اسمها "توكنات" (tokens). ولو فهمت التوكن، هتفهم نص المشاكل اللي بتقابلك مع الـ AI.
مثال بسيط قبل العلم: الكلمة اللي بتتقطّع
تخيل إنك بتقرأ كلمة طويلة مش شايفها حرف حرف، لكن مقسومة لمقاطع جاهزة. زي ما بتقرأ "مستشفى" على إنها مقطع واحد بسرعة، من غير ما تتهجّى م-س-ت-ش-ف-ى. النموذج بيعمل نفس الحاجة، بس بشكل أعمق: بياخد النص ويقسّمه لقطع شائعة اسمها توكنات، وكل قطعة ليها رقم.
كلمة strawberry مثلاً بتتقسم لتلات قطع: "str" و "aw" و "berry". النموذج بيشوف تلات أرقام، مش عشر حروف. جوه "berry" فيه حرفين r، وجوه "str" فيه واحد. بس النموذج شايف القطعة كوحدة واحدة، مش شايف الـ r اللي جواها. عشان كده عدّ الحروف بيبقى صعب عليه.
الشرح العلمي: التوكن مش الحرف
التوكن هو أصغر وحدة النموذج بيتعامل معاها. مش حرف، ومش كلمة كاملة بالضرورة. غالباً بيبقى "مقطع" (subword). النموذج عنده قاموس ثابت فيه عشرات الآلاف من التوكنات، وكل توكن ليه ID رقمي. أول خطوة في أي نموذج لغة إنه يحوّل نصك لقائمة IDs. ده اسمه Tokenization.
الخوارزمية الأشهر لبناء القاموس ده اسمها Byte Pair Encoding واختصارها BPE. فكرتها بسيطة: ابدأ بالحروف المفردة، وبعدين دمج أكتر زوج حروف بيتكرر مع بعض في توكن واحد، وكرّر. لو "e" و "r" بيجوا ورا بعض كتير، هيبقى عندك توكن "er". وبعدها ممكن "b" مع "er" يبقى "ber". النتيجة قاموس فيه قطع شائعة: الكلمات المشهورة بتتمثّل بتوكن أو اتنين، والنادرة بتتقطّع لأجزاء أصغر.
جرّبها بنفسك: كود بيعدّ التوكنات
ركّز في الكود ده. بيستخدم مكتبة tiktoken بتاعة OpenAI، ونفس الترميز اللي بيستخدمه GPT-4 و GPT-3.5.
import tiktoken
# نفس ترميز GPT-4 / GPT-3.5
enc = tiktoken.get_encoding("cl100k_base")
kalima = "strawberry"
ids = enc.encode(kalima)
print(ids) # أرقام (IDs) مش حروف
print(len(ids)) # عدد التوكنات = 3 غالباً
print([enc.decode([i]) for i in ids]) # ['str', 'aw', 'berry']
# قارن نص إنجليزي بنص عربي بنفس المعنى
en = "artificial intelligence"
ar = "الذكاء الاصطناعي"
print(len(enc.encode(en))) # قليل
print(len(enc.encode(ar))) # أكبر بكثير
هتلاقي strawberry بتطلع 3 توكنات، والنموذج بيشوف أرقامها بس. وهتلاحظ إن النص العربي بياخد توكنات أكتر بكثير من الإنجليزي اللي نفس معناه. ده مش صدفة، وله تأثير مباشر على جيبك.
سيناريو واقعي بالأرقام
القاعدة التقريبية من OpenAI: كل 100 توكن ≈ 75 كلمة إنجليزي، يعني التوكن الواحد ≈ 4 حروف. لكن ده للإنجليزي. القواميس دي اتبنت على بيانات إنجليزي في الأغلب، فالعربي بياخد نصيب أكبر. دراسة Petrov وزملائه سنة 2023 قاست إن لغات كتير من بينها العربي بتاخد من 2 لـ 4 أضعاف عدد التوكنات مقابل نفس المعنى بالإنجليزي.
خلينا نطبّق. عندك تطبيق بيلخّص مقالات عربية، ومتوسط المقال 500 كلمة. بالإنجليزي كان هياخد حوالي 650 توكن. بالعربي ممكن يوصل 1500 توكن أو أكتر. والتوكنات دي هي اللي بتتحاسب عليها في الـ API، وهي اللي بتاكل من نافذة السياق (context window). يعني نفس المقال بالعربي ممكن يكلّفك ضعف اللي بتدفعه بالإنجليزي، ويملأ ضعف المساحة. الافتراض هنا إنك بتستخدم ترميز شبيه بـ cl100k_base؛ النماذج الأحدث بترميز أفضل للعربي بتقلّل الفجوة بس مبتلغيهاش.
المقايضات (trade-offs)
التوكنيزيشن بالـ subword مكسب حقيقي: بيخلّي القاموس صغير (عشرات الآلاف بدل ملايين الكلمات)، وبيعرف يتعامل مع كلمات عمره ما شافها عن طريق تقطيعها. بتكسب: مرونة وذاكرة أقل وتدريب أسرع. بتخسر: النموذج بيفقد الرؤية على مستوى الحرف، فمهام زي عدّ الحروف، القافية، أو التلاعب بالأحرف بتبقى أصعب عليه. الـ trade-off هنا واضح: كفاءة في التمثيل مقابل عمى عن الحروف.
متى لا تشغل بالك بالتوكنيزيشن
لو شغلك محادثة عادية أو تلخيص أو ترجمة، مش محتاج تحسب توكنات بإيدك؛ النموذج بيتصرّف كويس. بس ابدأ تركّز في اللحظة اللي تشتغل فيها على مهام على مستوى الحرف (عدّ، تهجئة، أكواد)، أو لما التكلفة تبقى مهمة، أو لما تقرب من حد نافذة السياق. غير كده، سيبها للنموذج.
الخطوة التالية
افتح الكود اللي فوق، شغّله على أطول نص عربي عندك، وقارن عدد التوكنات بعدد الكلمات. لو لقيت النسبة أكبر من 2، ده معناه إن العربي بيكلّفك زيادة فعلية، فابدأ تحسبها في تسعير تطبيقك. عايز تتعمّق؟ اقرأ ورقة BPE الأصلية وجرّب المصادر تحت.
المصادر
- مكتبة tiktoken من OpenAI: github.com/openai/tiktoken
- شرح OpenAI للتوكنات وقاعدة "100 توكن ≈ 75 كلمة": help.openai.com — What are tokens
- ورقة BPE الأصلية (Sennrich, Haddow, Birch 2016): arxiv.org/abs/1508.07909
- عدم عدالة التوكنيزيشن بين اللغات (Petrov et al. 2023): arxiv.org/abs/2305.15425
- Andrej Karpathy — مستودع minbpe و "Let's build the GPT Tokenizer": github.com/karpathy/minbpe