نماذج اللغة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 لا يملك آلية للاستفادة منها.

افتح في المختبر
اكتب أي كلمة — Word2Vec لا يعرف إلا ما حفظه بالكامل. أما FastText فيبني متجهاً من القطع الحرفية حتى لكلمات لم يصادفها من قبل.
تستيقظ التجربة عند وصولك…

الفكرة: تفكيك الكلمات إلى مقاطع حرفية

الفكرة الأساسية بسيطة للغاية: بدلاً من إعطاء كل كلمة متجهاً واحداً، نُمثّلها بـمجموع متجهات مقاطعها الحرفية. والخطوات كالتالي:

الخطوة 1 — إضافة علامات الحدود. نُحيط الكلمة برمزَي بداية ونهاية حتى يُميّز النموذج بين مقاطع البداية ومقاطع النهاية. كلمة "where" تصبح <where>.

الخطوة 2 — استخراج المقاطع الحرفية. نُمرّر نافذة بأطوال من 3 إلى 6 حروف على الكلمة. لكلمة "where" بطول 3 نحصل على: <wh وwhe وher وere وre>.

الخطوة 3 — إضافة الكلمة الكاملة. نُدرج الكلمة كاملةً <where> كمُدخل مستقل، لأن بعض المعلومات الدلالية لا تستطيع القطع الحرفية وحدها التقاطها.

الخطوة 4 — جمع المتجهات. المتجه النهائي للكلمة هو ببساطة مجموع متجهات كل مقاطعها الحرفية مع متجه الكلمة الكاملة. هذا كل شيء — لا تعديل في بنية ، ولا . مجرد تمثيل أغنى للمدخلات.

افتح في المختبر
اكتب أي كلمة وشاهد كيف يُقسّمها FastText إلى مقاطع حرفية مع علامات الحدود.
تستيقظ التجربة عند وصولك…

دالة التقييم: من متجه الكلمة إلى مجموع المقاطع

في نموذج skip-gram الأصلي، العلاقة بين كلمة مركزية ww وكلمة سياقية cc تُقاس عبر لمتجهيهما: s(w,c)=uwvcs(w, c) = \mathbf{u}_w^\top \mathbf{v}_c. ما يفعله FastText هو استبدال متجه الكلمة المركزية بمجموع متجهات مقاطعها الحرفية Gw\mathcal{G}_w:

s(w,c)=gGwzgvcs(w, c) = \sum_{g \in \mathcal{G}_w} \mathbf{z}_g^\top \mathbf{v}_c
دالة تقييم FastText — درجة الكلمة هي مجموع درجات مقاطعها الحرفيةلكل مقطع حرفي g متجه مُتعلَّم z_g · للكلمة السياقية c متجه v_c · الدرجة الإجمالية هي حاصل جمع الضرب النقطي لكل مقطع مع متجه السياق — كلما أشارت مقاطع أكثر نحو الكلمة السياقية ارتفعت الدرجة

هذا هو التعديل الوحيد على نموذج skip-gram. كل شيء آخر — نافذة السياق المتحركة، و، و — يبقى كما هو تماماً. لكن هذا التغيير الوحيد له أثر عميق: أصبح النموذج يتشارك بين كلمات تتقاسم مقاطع حرفية مشتركة، ويستطيع تركيب متجهات لكلمات لم يرها قط أثناء التدريب.

افتح في المختبر
شاهد كيف يُسهم كل مقطع حرفي بضربه النقطي في الدرجة الإجمالية بين الكلمة والسياق.
تستيقظ التجربة عند وصولك…

لماذا ينجح هذا: البنية الصرفية تأتي تلقائياً

لنتأمّل الكلمات الإنجليزية "teach" و"teacher" و"teaching" و"teaches" و"taught". في Word2Vec، كل واحدة منها مُدخل مستقل يحتاج إلى بيانات تدريب كافية بمعزل عن الأخريات. أما في FastText، فتتشارك جميعها مقاطع حرفية مثل "tea" و"eac" و"ach" — وبالتالي ما يتعلّمه النموذج من واحدة يُفيد الباقي تلقائياً.

الأثر يتضاعف في اللغات الغنية صرفياً. المركّبات الألمانية الطويلة مثل "Donaudampfschifffahrtsgesellschaftskapitän" تتشارك مقاطع مع كلمات أبسط كـ"Donau" و"Schiff". وفي العربية، كلمات مثل «كِتاب» و«كاتِب» و«مَكتوب» و«مَكتَبة» تتقاسم جميعها تسلسلات حرفية من الجذر «ك-ت-ب». FastText يلتقط هذه العلاقات تلقائياً بلا حاجة إلى محلِّل صرفي خارجي.

افتح في المختبر
قارن بين Word2Vec وFastText في التعامل مع كلمات متقاربة صرفياً. لاحظ كيف تخلق المقاطع الحرفية المشتركة تشابهاً طبيعياً بين المتجهات.
تستيقظ التجربة عند وصولك…

التعامل مع الكلمات المجهولة: تركيب متجهات لكلمات لم تظهر من قبل

هذه على الأرجح أهم ميزة عملية في FastText. حين يصادف النموذج كلمة غير موجودة في قاموسه، يمرّ بالخطوات التالية:

  1. يُحيطها بعلامات الحدود 2. يستخرج كل المقاطع الحرفية بأطوال من 3 إلى 6 3. يبحث عن متجهات المقاطع التي سبق أن رآها 4. يجمع تلك المتجهات ليُنتج للكلمة

النتيجة لن تكون بجودة كلمة تدرّب عليها النموذج كثيراً، لكنها أفضل بمراحل من الفراغ الكامل. خطأ إملائي مثل "languge" يتقاسم معظم مقاطعه مع "language"، فيخرج متجهه المُركَّب قريباً منها. ومصطلح تقني جديد مثل "transformerized" يستمد معناه من قطعه المألوفة.

هذا الأمر بالغ الأهمية في بيئات الإنتاج: المستخدمون يُخطئون إملائياً، وكلمات جديدة تظهر كل يوم، واللغات تملك آليات اشتقاقية تُولّد صيغاً صحيحة أسرع مما يستطيع أي ملاحقته.

افتح في المختبر
أدخل كلمة مُختلَقة أو بها خطأ إملائي وشاهد كيف يُركّب FastText متجهها من مقاطع حرفية معروفة.
تستيقظ التجربة عند وصولك…

التدريب: العيّنات السلبية مع المقاطع الحرفية

يعتمد FastText على هدف التدريب نفسه المُستخدم في skip-gram مع العيّنات السلبية. لكل زوج (كلمة، سياق) (w,c)(w, c) يظهر في المتن النصي، يسحب النموذج أيضاً kk كلمة سياقية عشوائية كعيّنات سلبية. الهدف هو تعظيم لوغاريتم دالة لدرجة الزوج الحقيقي وتقليلها للأزواج السلبية:

L=logσ ⁣(s(w,c))+i=1kEni ⁣[logσ ⁣(s(w,ni))]\mathcal{L} = \log\sigma\!\left(s(w,c)\right) + \sum_{i=1}^{k}\mathbb{E}_{n_i}\!\left[\log\sigma\!\left(-s(w,n_i)\right)\right]
خسارة العيّنات السلبية — ارفع الأزواج الحقيقية وأخفض العشوائيةs(w,c) هي درجة مجموع المقاطع الحرفية من المعادلة السابقة · σ دالة السيجمويد · الحد الأول يُكافئ الدرجات العالية للأزواج الحقيقية · المجموع يُعاقب الدرجات العالية للأزواج العشوائية · k تتراوح عادةً بين 5 و20

الفرق الجوهري عن Word2Vec هو مسار : حين نحسب التدرّجات ونُحدّث المتجهات، يتدفق التدرّج عائداً إلى كل متجه مقطع حرفي في Gw\mathcal{G}_w. فكل مثال تدريبي لا يُحدّث كلمة واحدة فحسب، بل يُحدّث جميع المقاطع المكوِّنة لها — وهذه المقاطع مشتركة مع كلمات أخرى. مثلاً، تدريب النموذج على كلمة "running" يُحسّن ضمنياً تمثيلات "run" و"runner" وكل كلمة تتقاسم معها القطع ذاتها.

حيلة عملية: التجزئة لتوفير الذاكرة

سؤال طبيعي يطرح نفسه: إذا أنتجت كل كلمة عشرات المقاطع الحرفية والقاموس يضم ملايين الكلمات، ألن يكون العدد الإجمالي للمقاطع المختلفة هائلاً؟ يحلّ FastText هذه المشكلة بحيلة التجزئة (hashing): كل مقطع حرفي يُمرَّر عبر دالة تجزئة تُسقطه على واحدة من BB خانة (عادةً B=2,000,000B = 2{,}000{,}000). المقاطع التي تقع في الخانة نفسها تتشارك المتجه ذاته.

بهذه الطريقة يُحدّ استهلاك الذاكرة عند B×dB \times d معامل بالضبط (حيث dd هو بُعد النظر عن العدد الفعلي للمقاطع. والجميل أن معدل التصادمات منخفض بما يكفي فلا يكاد يؤثر على الجودة — حل هندسي أنيق.

افتح في المختبر
شاهد كيف تُسقَط مقاطع حرفية مختلفة على خانات التجزئة. التصادمات نادرة لكنها واردة.
تستيقظ التجربة عند وصولك…

النتائج: أين يتألق FastText

قيّم المؤلفون أداء FastText على نوعين من المهام عبر لغات متعددة:

الكلمات — إلى أي درجة تتوافق المسافات بين المتجهات مع أحكام التشابه البشرية؟ في اللغات الغنية صرفياً (الألمانية، التشيكية، العربية)، تفوّق FastText على نموذج skip-gram العادي بفارق يتراوح بين 5 و10 نقاط في ارتباط سبيرمان. التحسن كان أقل في الإنجليزية ذات النظام الصرفي الأبسط.

— هل يستطيع النموذج حلّ مسائل من نوع «ملك:ملكة :: رجل:؟»؟ تفوّق FastText في القياسات النحوية (التي تختبر أنماطاً صرفية كالجمع والأزمنة)، بينما كان أداؤه مكافئاً في القياسات الدلالية (كعلاقات العواصم والعملات). وهذا يؤكد أن آلية المقاطع الحرفية تلتقط البنية الصرفية بالدرجة الأولى.

افتح في المختبر
قارن درجات تشابه الكلمات بين FastText وskip-gram عبر لغات ذات مستويات صرفية مختلفة.
تستيقظ التجربة عند وصولك…

الصورة الكاملة

إليك المراحل الكاملة لعمل FastText — من النص الخام إلى نموذج مُدرَّب قادر على التعامل مع أي كلمة، سواءً ظهرت أثناء التدريب أم لا:

افتح في المختبر
انقر على كل مرحلة لترى ما يحدث في كل خطوة من خطوات تدريب FastText.
تستيقظ التجربة عند وصولك…

الفكرة في شيفرة برمجية

حساب درجات المقاطع الحرفية في FastText — الآلية الكاملةpython

مبسَّط لإظهار الفكرة — ليس التنفيذ الحقيقي.

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"

الإرث: من الوحدات الفرعية إلى المُرمِّزات الحديثة

  1. 2013

    Word2Vec

    أثبت أن شبكات عصبية بسيطة تتعلّم متجهات دلالية غنية من أنماط تجاور الكلمات في النصوص. متجه واحد لكل كلمة، بلا وعي بالبنية الداخلية.

  2. 2014

    GloVe

    دمج بين أساليب العد الإحصائي والتنبؤ لإنتاج متجهات الكلمات. لكنه لا يزال يُعطي متجهاً واحداً لكل كلمة بلا وعي صرفي.

  3. 2016

    BPE للترجمة الآلية العصبية

    طبّق Sennrich وزملاؤه ترميز أزواج البايت لبناء قواميس وحدات فرعية في الترجمة الآلية. عالج مشكلة الكلمات خارج القاموس بفعالية.

  4. 2017

    FastText (هذه الورقة)

    أثبت أن المقاطع الحرفية تُثري متجهات الكلمات — تتعامل مع الكلمات المجهولة، وتلتقط البنية الصرفية، وتُحسّن التضمينات متعددة اللغات.

  5. 2018

    ELMo — تضمينات سياقية

    نقل الفكرة خطوة أبعد: كل كلمة تحصل على متجه يتغيّر بحسب سياقها في الجملة، وذلك باستخدام شبكات LSTM عميقة ثنائية الاتجاه.

  6. 2018

    BERT — ترميز WordPiece

    دمج ترميز الوحدات الفرعية (WordPiece) مع محوِّلات عميقة ثنائية الاتجاه. ورسّخ مبدأ الوحدات الفرعية معياراً أساسياً في كل النماذج اللغوية الكبيرة.

يحتل FastText موقعاً محورياً في تاريخ المجال: أثبت أننا لسنا مضطرين للاختيار بين نماذج مستوى الكلمة ونماذج مستوى الحرف. بالعمل على مستوى الوحدات الفرعية، التقط البنية الصرفية دون التضحية بكفاءة وبساطة نموذج skip-gram في Word2Vec. هذا المبدأ — تفكيك الكلمات إلى وحدات فرعية — أصبح الأساس الذي بُني عليه كل مُرمِّز في معالجة اللغة الطبيعية الحديثة.

المرجعBojanowski, Grave, Joulin, Mikolov. Enriching Word Vectors with Subword Information. TACL, 2017.

مصطلحات هذه الورقة