الدرس 5 من 24

نماذج التضمين وقواعد البيانات المتجهة

مقارنة نماذج التضمين

3 دقيقة للقراءة

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

نموذج التضمين هو أساس البحث الدلالي. اختيار النموذج الصحيح يؤثر بشكل كبير على جودة الاسترجاع.

ماذا تفعل التضمينات

التضمينات تحول النص إلى متجهات كثيفة تلتقط المعنى الدلالي:

from openai import OpenAI

client = OpenAI()

# نفس المعنى، كلمات مختلفة → متجهات متشابهة
text1 = "القطة جلست على السجادة"
text2 = "هر استراح على البساط"

emb1 = client.embeddings.create(input=text1, model="text-embedding-3-small")
emb2 = client.embeddings.create(input=text2, model="text-embedding-3-small")

# تشابه جيب التمام سيكون عالياً (~0.85+)

فئات النماذج

الفئةالأمثلةالأفضل لـ
APIs تجاريةOpenAI, Cohere, Voyageالإنتاج، سهولة الاستخدام
مفتوحة المصدرBGE, E5, GTEالخصوصية، التحكم بالتكلفة، التخصيص
خاصة بالمجالLegal-BERT, BioBERTالمجالات المتخصصة

نماذج API التجارية

تضمينات OpenAI

from openai import OpenAI

client = OpenAI()

def embed_openai(texts: list[str], model: str = "text-embedding-3-small"):
    response = client.embeddings.create(input=texts, model=model)
    return [item.embedding for item in response.data]

# النماذج المتاحة:
# text-embedding-3-small: 1536 بُعد، $0.02/1M رمز
# text-embedding-3-large: 3072 بُعد، $0.13/1M رمز
# text-embedding-ada-002: 1536 بُعد (قديم)

Cohere Embed

import cohere

co = cohere.Client()

def embed_cohere(texts: list[str], input_type: str = "search_document"):
    response = co.embed(
        texts=texts,
        model="embed-english-v3.0",
        input_type=input_type  # "search_document" أو "search_query"
    )
    return response.embeddings

# أوضاع منفصلة للمستندات مقابل الاستعلامات تحسن الاسترجاع

Voyage AI

ملاحظة: تم استحواذ MongoDB على Voyage AI في فبراير 2025.

import voyageai

vo = voyageai.Client()

def embed_voyage(texts: list[str]):
    response = vo.embed(
        texts,
        model="voyage-3-large",
        input_type="document"  # أو "query"
    )
    return response.embeddings

# معروف بأداء ممتاز في مجال الكود والقانون

نماذج مفتوحة المصدر

BGE (تضمين BAAI العام)

from sentence_transformers import SentenceTransformer

# نماذج BGE - دعم متعدد اللغات ممتاز
model = SentenceTransformer('BAAI/bge-large-en-v1.5')

def embed_bge(texts: list[str]):
    # BGE يوصي بإضافة تعليمات للاستعلامات
    return model.encode(texts, normalize_embeddings=True)

def embed_bge_query(query: str):
    # بادئة للاستعلامات تحسن الاسترجاع
    instruction = "Represent this sentence for searching relevant passages: "
    return model.encode(instruction + query, normalize_embeddings=True)

E5 (تمثيلات التضمين من المشفر ثنائي الاتجاه)

from sentence_transformers import SentenceTransformer

model = SentenceTransformer('intfloat/e5-large-v2')

def embed_e5(texts: list[str], is_query: bool = False):
    # E5 يتطلب بادئات
    if is_query:
        texts = [f"query: {t}" for t in texts]
    else:
        texts = [f"passage: {t}" for t in texts]
    return model.encode(texts, normalize_embeddings=True)

مقارنة معيار MTEB

معيار تضمين النص الضخم (MTEB) يوفر مقارنات موحدة:

النموذجدرجة MTEBالأبعادالسرعة
voyage-3-large68.281536سريع (API)
text-embedding-3-large64.593072سريع (API)
bge-large-en-v1.564.231024متوسط
e5-large-v262.251024متوسط
text-embedding-3-small62.261536سريع (API)

(الدرجات حتى منتصف 2025؛ راجع لوحة MTEB للأحدث)

ملاحظة: درجات MTEB تختلف حسب نوع المهمة. تحقق من معايير الاسترجاع الخاصة بـ RAG.

اختيار النموذج الصحيح

البداية
البيانات يجب أن تبقى محلياً؟
  ├─ نعم → مفتوح المصدر (BGE, E5)
مجال متخصص (قانون، طب، كود)؟
  ├─ نعم → خاص بالمجال أو Voyage
متطلبات متعددة اللغات؟
  ├─ نعم → BGE-M3 أو Cohere متعدد اللغات
ميزانية محدودة؟
  ├─ نعم → text-embedding-3-small أو مفتوح المصدر
الافتراضي → text-embedding-3-small (أفضل نسبة تكلفة/جودة)

نصائح التنفيذ

class EmbeddingManager:
    """إدارة التضمينات مع التجميع والتخزين المؤقت."""

    def __init__(self, model_name: str, batch_size: int = 100):
        self.model_name = model_name
        self.batch_size = batch_size
        self.cache = {}

    def embed(self, texts: list[str]) -> list[list[float]]:
        # تحقق من الذاكرة المؤقتة
        uncached = [t for t in texts if t not in self.cache]

        if uncached:
            # تجميع للكفاءة
            for i in range(0, len(uncached), self.batch_size):
                batch = uncached[i:i + self.batch_size]
                embeddings = self._embed_batch(batch)
                for text, emb in zip(batch, embeddings):
                    self.cache[text] = emb

        return [self.cache[t] for t in texts]

    def _embed_batch(self, texts: list[str]) -> list[list[float]]:
        # التنفيذ يعتمد على النموذج
        pass

نصيحة تكلفة: text-embedding-3-small من OpenAI يقدم أفضل نسبة تكلفة-إلى-جودة لمعظم حالات الاستخدام. ترقّ فقط لنماذج أكبر إذا تحسنت جودة الاسترجاع بشكل ملموس على بياناتك.

نقطة تحقق

قبل الانتقال، شغّل هذا على 10 مستندات تمثيلية من مجموعتك (التي اخترتها في نقطة تحقق الدرس 1 من الوحدة 1):

  1. ضمّنها بـ text-embedding-3-small (1536 بُعداً) و text-embedding-3-large (3072 بُعداً)
  2. استعلم بـ 3 أسئلة واقعية
  3. قارن أعلى 3 نتائج من كل منهما. هل النموذج الأكبر أفضل بشكل ملحوظ على بياناتك أنت؟

لمعظم المجموعات الإنجليزية/المختلطة الإجابة "قليلاً". للبيانات الخاصة بمجال (قانوني، طبي، كود)، قد تكون الفجوة كبيرة — وأحياناً يفوز نموذج مفتوح مضبوط دقيقاً مثل BGE على كليهما. القاعدة: افترض text-embedding-3-large (3072 بُعداً) للمشروع النهائي، لكن تحقق على بياناتك قبل الالتزام بالتخزين.

التالي، لنستكشف خيارات قواعد البيانات المتجهة لتخزين والبحث في التضمينات. :::

مراجعة سريعة: كيف تجد هذا الدرس؟

اختبار

الوحدة 2: نماذج التضمين وقواعد البيانات المتجهة

خذ الاختبار
نشرة أسبوعية مجانية

ابقَ على مسار النيرد

بريد واحد أسبوعياً — دورات، مقالات معمّقة، أدوات، وتجارب ذكاء اصطناعي.

بدون إزعاج. إلغاء الاشتراك في أي وقت.