نماذج اللغة2017مبتدئ10 دقيقة قراءة
إثراء متجهات الكلمات بمعلومات الوحدات الفرعية
Enriching Word Vectors with Subword Information
Bojanowski, P. · Grave, E. · Joulin, A. · Mikolov, T. — TACL
المشكلة
في Word2Vec، كل كلمة تحصل على واحد — وإذا لم تظهر الكلمة في بيانات ، فلا تمثيل لها إطلاقاً. المشكلة تتضخّم في اللغات الغنية صرفياً كالعربية والفنلندية والتركية، لأن جذراً واحداً يُولّد عشرات بل مئات الصيغ المشتقة. حتى في الإنجليزية، كلمة نادرة مثل "unbreakableness" ينتهي بها الأمر بمتجه ضعيف لأن لم يرها إلا مرات قليلة. والبنية الداخلية للكلمات — السوابق واللواحق والجذور — تضيع تماماً لأن النموذج لا يراها أصلاً.
الإسهام
يبني FastText على نموذج skip-gram بإضافة فكرة بسيطة وفعّالة: بدلاً من تمثيل كل كلمة بمتجه واحد، يُفكّكها إلى مقاطع حرفية قصيرة (character n-grams). مثلاً كلمة "where" بطول n=3 تُنتج: <wh وwhe وher وere وre> إضافةً إلى الكلمة كاملةً <where>. كل مقطع يملك متجهاً خاصاً، ومتجه الكلمة هو ببساطة مجموع متجهات مقاطعها. الفائدة المباشرة: حتى الكلمات التي لم تظهر في التدريب تحصل على تمثيل ذي معنى من قطعها الحرفية، والكلمات المتقاربة صرفياً (مثل run وruns وrunning) تتشارك معظم مقاطعها تلقائياً. على معايير تشابه الكلمات في اللغات الغنية صرفياً، يتفوّق FastText على Word2Vec بفارق واضح.
الأثر
تحوّل FastText إلى المعيار العملي لتضمينات الكلمات في بيئات الإنتاج، لا سيما في التطبيقات متعددة اللغات. متجهاته المُدرَّبة مسبقاً التي تُغطي 157 لغة لا تزال من أكثر الموارد تحميلاً في المجال. وفكرة تفكيك الكلمات إلى وحدات فرعية أثّرت مباشرةً في مُرمِّزات BPE التي تعتمدها كل النماذج اللغوية الكبيرة اليوم — GPT وBERT وClaude جميعها تعمل على مستوى الوحدات الفرعية، وهو مبدأ رسّخه FastText. عملياً، مثّل FastText نقطة التحوّل بين نماذج الكلمات الكاملة والبنى الحديثة المُدركة للحروف.
في Word2Vec، كل كلمة أشبه بـبطاقة تعريف مستقلة: «يجري» و«جارٍ» بطاقتان لا علاقة بينهما في نظر النموذج، رغم أنهما من الجذر ذاته.
FastText يتعامل مع الكلمات وكأنها مكعبات ليغو: كلمة "running" مبنية من قطع — "run" و"unn" و"nni" و"nin" و"ing" — وكل قطعة قابلة لإعادة الاستخدام. صادفتَ كلمة جديدة لم ترها من قبل؟ لا مشكلة — ما دامت قطعها موجودة في المجموعة، يمكنك تركيب معنى لها.
الفكرة تشبه تعلّم لغة جديدة من خلال فهم الجذور والأوزان، بدلاً من حفظ كل كلمة في القاموس على حدة.
المشكلة: متجه واحد لكل كلمة لا يكفي
شكّل Word2Vec نقلة نوعية: أثبت أن بالإمكان تعلّم ذات معنى من نص خام بمجرد التنبؤ بالكلمات المحيطة. لكنه يُعامل كل كلمة على أنها وحدة مُصمتة — صندوق مُغلق لا يرى ما بداخله. وينتج عن ذلك ثلاث مشكلات عملية:
-
الكلمات خارج القاموس. كل كلمة لم تظهر أثناء التدريب لا تملك أي تمثيل. في بيئة إنتاجية، خطأ إملائي بسيط أو اسم منتج جديد أو صيغة صرفية نادرة يعني أن النظام سيعجز عن التعامل مع الكلمة ويعود إلى رمز «مجهول» عام.
-
تجاهل البنية الصرفية. كلمات مثل "teach" و"teacher" و"teaching" و"teaches" يراها النموذج أربع كلمات مستقلة لا رابط بينها. الجذر المشترك "teach" غير مرئي له إطلاقاً. في العربية — حيث يتفرّع جذر واحد كـ«ك-ت-ب» إلى عشرات الصيغ (كتب، كاتب، مكتوب، كتابة، مكتبة) — تصبح هذه المشكلة كارثية.
-
ضعف تمثيل الكلمات النادرة. الكلمات التي لا تظهر إلا مرات قليلة ينتهي بها الأمر بمتجهات رديئة الجودة لأن السياق المتاح للتعلّم منه لا يكفي. المعلومات الصرفية كانت ستساعد في بناء تمثيل أوّلي لهذه الكلمات، لكن Word2Vec لا يملك آلية للاستفادة منها.
الفكرة: تفكيك الكلمات إلى مقاطع حرفية
الفكرة الأساسية بسيطة للغاية: بدلاً من إعطاء كل كلمة متجهاً واحداً، نُمثّلها بـمجموع متجهات مقاطعها الحرفية. والخطوات كالتالي:
الخطوة 1 — إضافة علامات الحدود. نُحيط الكلمة برمزَي بداية ونهاية حتى يُميّز النموذج بين مقاطع البداية ومقاطع النهاية. كلمة "where" تصبح <where>.
الخطوة 2 — استخراج المقاطع الحرفية. نُمرّر نافذة بأطوال من 3 إلى 6 حروف على الكلمة. لكلمة "where" بطول 3 نحصل على: <wh وwhe وher وere وre>.
الخطوة 3 — إضافة الكلمة الكاملة. نُدرج الكلمة كاملةً <where> كمُدخل مستقل، لأن بعض المعلومات الدلالية لا تستطيع القطع الحرفية وحدها التقاطها.
الخطوة 4 — جمع المتجهات. المتجه النهائي للكلمة هو ببساطة مجموع متجهات كل مقاطعها الحرفية مع متجه الكلمة الكاملة. هذا كل شيء — لا تعديل في بنية ، ولا . مجرد تمثيل أغنى للمدخلات.
دالة التقييم: من متجه الكلمة إلى مجموع المقاطع
في نموذج skip-gram الأصلي، العلاقة بين كلمة مركزية وكلمة سياقية تُقاس عبر لمتجهيهما: . ما يفعله FastText هو استبدال متجه الكلمة المركزية بمجموع متجهات مقاطعها الحرفية :
هذا هو التعديل الوحيد على نموذج skip-gram. كل شيء آخر — نافذة السياق المتحركة، و، و — يبقى كما هو تماماً. لكن هذا التغيير الوحيد له أثر عميق: أصبح النموذج يتشارك بين كلمات تتقاسم مقاطع حرفية مشتركة، ويستطيع تركيب متجهات لكلمات لم يرها قط أثناء التدريب.
لماذا ينجح هذا: البنية الصرفية تأتي تلقائياً
لنتأمّل الكلمات الإنجليزية "teach" و"teacher" و"teaching" و"teaches" و"taught". في Word2Vec، كل واحدة منها مُدخل مستقل يحتاج إلى بيانات تدريب كافية بمعزل عن الأخريات. أما في FastText، فتتشارك جميعها مقاطع حرفية مثل "tea" و"eac" و"ach" — وبالتالي ما يتعلّمه النموذج من واحدة يُفيد الباقي تلقائياً.
الأثر يتضاعف في اللغات الغنية صرفياً. المركّبات الألمانية الطويلة مثل "Donaudampfschifffahrtsgesellschaftskapitän" تتشارك مقاطع مع كلمات أبسط كـ"Donau" و"Schiff". وفي العربية، كلمات مثل «كِتاب» و«كاتِب» و«مَكتوب» و«مَكتَبة» تتقاسم جميعها تسلسلات حرفية من الجذر «ك-ت-ب». FastText يلتقط هذه العلاقات تلقائياً بلا حاجة إلى محلِّل صرفي خارجي.
التعامل مع الكلمات المجهولة: تركيب متجهات لكلمات لم تظهر من قبل
هذه على الأرجح أهم ميزة عملية في FastText. حين يصادف النموذج كلمة غير موجودة في قاموسه، يمرّ بالخطوات التالية:
- يُحيطها بعلامات الحدود 2. يستخرج كل المقاطع الحرفية بأطوال من 3 إلى 6 3. يبحث عن متجهات المقاطع التي سبق أن رآها 4. يجمع تلك المتجهات ليُنتج للكلمة
النتيجة لن تكون بجودة كلمة تدرّب عليها النموذج كثيراً، لكنها أفضل بمراحل من الفراغ الكامل. خطأ إملائي مثل "languge" يتقاسم معظم مقاطعه مع "language"، فيخرج متجهه المُركَّب قريباً منها. ومصطلح تقني جديد مثل "transformerized" يستمد معناه من قطعه المألوفة.
هذا الأمر بالغ الأهمية في بيئات الإنتاج: المستخدمون يُخطئون إملائياً، وكلمات جديدة تظهر كل يوم، واللغات تملك آليات اشتقاقية تُولّد صيغاً صحيحة أسرع مما يستطيع أي ملاحقته.
التدريب: العيّنات السلبية مع المقاطع الحرفية
يعتمد FastText على هدف التدريب نفسه المُستخدم في skip-gram مع العيّنات السلبية. لكل زوج (كلمة، سياق) يظهر في المتن النصي، يسحب النموذج أيضاً كلمة سياقية عشوائية كعيّنات سلبية. الهدف هو تعظيم لوغاريتم دالة لدرجة الزوج الحقيقي وتقليلها للأزواج السلبية:
الفرق الجوهري عن Word2Vec هو مسار : حين نحسب التدرّجات ونُحدّث المتجهات، يتدفق التدرّج عائداً إلى كل متجه مقطع حرفي في . فكل مثال تدريبي لا يُحدّث كلمة واحدة فحسب، بل يُحدّث جميع المقاطع المكوِّنة لها — وهذه المقاطع مشتركة مع كلمات أخرى. مثلاً، تدريب النموذج على كلمة "running" يُحسّن ضمنياً تمثيلات "run" و"runner" وكل كلمة تتقاسم معها القطع ذاتها.
حيلة عملية: التجزئة لتوفير الذاكرة
سؤال طبيعي يطرح نفسه: إذا أنتجت كل كلمة عشرات المقاطع الحرفية والقاموس يضم ملايين الكلمات، ألن يكون العدد الإجمالي للمقاطع المختلفة هائلاً؟ يحلّ FastText هذه المشكلة بحيلة التجزئة (hashing): كل مقطع حرفي يُمرَّر عبر دالة تجزئة تُسقطه على واحدة من خانة (عادةً ). المقاطع التي تقع في الخانة نفسها تتشارك المتجه ذاته.
بهذه الطريقة يُحدّ استهلاك الذاكرة عند معامل بالضبط (حيث هو بُعد )، النظر عن العدد الفعلي للمقاطع. والجميل أن معدل التصادمات منخفض بما يكفي فلا يكاد يؤثر على الجودة — حل هندسي أنيق.
النتائج: أين يتألق FastText
قيّم المؤلفون أداء FastText على نوعين من المهام عبر لغات متعددة:
الكلمات — إلى أي درجة تتوافق المسافات بين المتجهات مع أحكام التشابه البشرية؟ في اللغات الغنية صرفياً (الألمانية، التشيكية، العربية)، تفوّق FastText على نموذج skip-gram العادي بفارق يتراوح بين 5 و10 نقاط في ارتباط سبيرمان. التحسن كان أقل في الإنجليزية ذات النظام الصرفي الأبسط.
— هل يستطيع النموذج حلّ مسائل من نوع «ملك:ملكة :: رجل:؟»؟ تفوّق FastText في القياسات النحوية (التي تختبر أنماطاً صرفية كالجمع والأزمنة)، بينما كان أداؤه مكافئاً في القياسات الدلالية (كعلاقات العواصم والعملات). وهذا يؤكد أن آلية المقاطع الحرفية تلتقط البنية الصرفية بالدرجة الأولى.
الصورة الكاملة
إليك المراحل الكاملة لعمل FastText — من النص الخام إلى نموذج مُدرَّب قادر على التعامل مع أي كلمة، سواءً ظهرت أثناء التدريب أم لا:
الفكرة في شيفرة برمجية
مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.
import numpy as np
def get_ngrams(word, min_n=3, max_n=6):
"""قسّم الكلمة إلى مقاطع حرفية مع علامات الحدود."""
word = f"<{word}>" # أضف علامتَي البداية والنهاية
ngrams = []
for n in range(min_n, max_n + 1):
for i in range(len(word) - n + 1):
ngrams.append(word[i:i+n])
ngrams.append(word) # أضف الكلمة كاملةً أيضاً
return ngrams
def fasttext_score(word, context_vec, ngram_vectors):
"""احسب درجة التوافق بين كلمة وسياقها عبر المقاطع الحرفية."""
ngrams = get_ngrams(word)
# متجه الكلمة = مجموع متجهات مقاطعها الحرفية
word_vec = sum(ngram_vectors[ng] for ng in ngrams if ng in ngram_vectors)
# الدرجة = الضرب النقطي بين (مجموع المقاطع) ومتجه السياق
return float(np.dot(word_vec, context_vec))
# مثال: "where" ← ['<wh', 'whe', 'her', 'ere', 're>', '<whe', 'wher', ...]
# "runs" تتشارك مقاطع حرفية مع "run" و"running" و"runner"
# كلمة مجهولة مثل "kitchenette" تستمد معناها من مقاطع "kitchen"الإرث: من الوحدات الفرعية إلى المُرمِّزات الحديثة
2013
Word2Vec
أثبت أن شبكات عصبية بسيطة تتعلّم متجهات دلالية غنية من أنماط تجاور الكلمات في النصوص. متجه واحد لكل كلمة، بلا وعي بالبنية الداخلية.
2014
GloVe
دمج بين أساليب العد الإحصائي والتنبؤ لإنتاج متجهات الكلمات. لكنه لا يزال يُعطي متجهاً واحداً لكل كلمة بلا وعي صرفي.
2016
BPE للترجمة الآلية العصبية
طبّق Sennrich وزملاؤه ترميز أزواج البايت لبناء قواميس وحدات فرعية في الترجمة الآلية. عالج مشكلة الكلمات خارج القاموس بفعالية.
2017
FastText (هذه الورقة)
أثبت أن المقاطع الحرفية تُثري متجهات الكلمات — تتعامل مع الكلمات المجهولة، وتلتقط البنية الصرفية، وتُحسّن التضمينات متعددة اللغات.
2018
ELMo — تضمينات سياقية
نقل الفكرة خطوة أبعد: كل كلمة تحصل على متجه يتغيّر بحسب سياقها في الجملة، وذلك باستخدام شبكات LSTM عميقة ثنائية الاتجاه.
2018
BERT — ترميز WordPiece
دمج ترميز الوحدات الفرعية (WordPiece) مع محوِّلات عميقة ثنائية الاتجاه. ورسّخ مبدأ الوحدات الفرعية معياراً أساسياً في كل النماذج اللغوية الكبيرة.
يحتل FastText موقعاً محورياً في تاريخ المجال: أثبت أننا لسنا مضطرين للاختيار بين نماذج مستوى الكلمة ونماذج مستوى الحرف. بالعمل على مستوى الوحدات الفرعية، التقط البنية الصرفية دون التضحية بكفاءة وبساطة نموذج skip-gram في Word2Vec. هذا المبدأ — تفكيك الكلمات إلى وحدات فرعية — أصبح الأساس الذي بُني عليه كل مُرمِّز في معالجة اللغة الطبيعية الحديثة.
المرجعBojanowski, Grave, Joulin, Mikolov. Enriching Word Vectors with Subword Information. TACL, 2017.
مصطلحات هذه الورقة
- جزء الكلمةSubword
- تضمين الكلمةWord Embedding
- سلسلة حرفية فرعيةCharacter N-gram
- نموذج التخطي (Skip-gram)Skip-gram
- الصرفMorphology
- خارج قاموس المفرداتOut-of-Vocabulary (OOV)
- التعيين السلبيNegative Sampling
- ترميز زوج البايتByte Pair Encoding (BPE)