الدرس 7 من 23

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

استراتيجيات الفهرسة

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

فهارس المتجهات تمكّن البحث السريع عن التشابه عبر ملايين المتجهات. فهم أنواع الفهارس يساعدك على موازنة السرعة والدقة والذاكرة.

لماذا الفهرسة مهمة

بدون فهرس، إيجاد متجهات متشابهة يتطلب المقارنة مع كل متجه:

# القوة الغاشمة: O(n) - يفحص كل متجه
def brute_force_search(query: list[float], vectors: list[list[float]], k: int):
    distances = [cosine_distance(query, v) for v in vectors]
    return sorted(range(len(distances)), key=lambda i: distances[i])[:k]

# مع 1M متجه: ~1 ثانية لكل استعلام
# مع فهرس: ~10ms لكل استعلام

أنواع الفهارس

الفهرس السرعة الدقة الذاكرة الأفضل لـ
Flat بطيء 100% عالية < 10K متجه
IVF سريع 95-99% متوسطة 10K-10M متجه
HNSW الأسرع 95-99% عالية أي نطاق، زمن استجابة منخفض
PQ سريع 90-95% منخفضة ذاكرة محدودة

فهرس Flat (القوة الغاشمة)

بحث دقيق بدون تقريب:

# Pinecone
index = pc.create_index(
    name="exact-search",
    dimension=1536,
    metric="cosine"
    # فهرس Flat افتراضياً لمجموعات البيانات الصغيرة
)

# Chroma
collection = client.create_collection(
    name="documents",
    metadata={"hnsw:space": "cosine"}
    # يستخدم بحث flat للمجموعات الصغيرة
)

استخدم عندما: < 10K متجه أو عندما يُطلب استدعاء 100%.

IVF (فهرس الملف المقلوب)

يجمّع المتجهات، يبحث فقط في المجموعات ذات الصلة:

# pgvector مع IVF
cur.execute("""
    CREATE INDEX ON documents
    USING ivfflat (embedding vector_cosine_ops)
    WITH (lists = 100)  -- عدد المجموعات
""")

# أثناء البحث، يفحص فقط مجموعة فرعية من المجموعات
# قوائم أكثر = بحث أسرع، استدعاء أقل
# قوائم أقل = بحث أبطأ، استدعاء أعلى

كيف يعمل:

  1. يجمّع المتجهات في lists مجموعات أثناء الفهرسة
  2. في وقت الاستعلام، يجد أقرب مراكز المجموعات
  3. يبحث فقط في المتجهات في تلك المجموعات

ضبط IVF:

حجم مجموعة البيانات القوائم الفحوصات
100K 100 10
1M 1000 50
10M 4000 100

HNSW (العالم الصغير الهرمي القابل للتنقل)

فهرس قائم على الرسم البياني للبحث فائق السرعة:

# Qdrant
from qdrant_client.models import VectorParams, HnswConfigDiff

client.create_collection(
    collection_name="documents",
    vectors_config=VectorParams(
        size=1536,
        distance=Distance.COSINE
    ),
    hnsw_config=HnswConfigDiff(
        m=16,           # الاتصالات لكل عقدة (أعلى = استدعاء أفضل، ذاكرة أكثر)
        ef_construct=100  # جودة البناء (أعلى = فهرس أفضل، بناء أبطأ)
    )
)

# ضبط وقت الاستعلام
results = client.search(
    collection_name="documents",
    query_vector=query_embedding,
    limit=5,
    search_params={"ef": 128}  # أعلى = استدعاء أفضل، بحث أبطأ
)

معلمات HNSW:

المعلمة التأثير القيم النموذجية
m اتصال الرسم البياني 8-64 (16 افتراضي)
ef_construct جودة بناء الفهرس 64-512 (100 افتراضي)
ef (استعلام) جودة البحث 50-500

التكميم المنتج (PQ)

يضغط المتجهات لكفاءة الذاكرة:

# Milvus مع PQ
from pymilvus import Collection, CollectionSchema, FieldSchema, DataType

schema = CollectionSchema([
    FieldSchema("id", DataType.INT64, is_primary=True),
    FieldSchema("embedding", DataType.FLOAT_VECTOR, dim=1536)
])

collection = Collection("documents", schema)

# إنشاء فهرس PQ
index_params = {
    "index_type": "IVF_PQ",
    "metric_type": "IP",  # الضرب الداخلي
    "params": {
        "nlist": 1024,    # مجموعات IVF
        "m": 64,          # عدد المكممات الفرعية
        "nbits": 8        # البتات لكل مكمم فرعي
    }
}
collection.create_index("embedding", index_params)

توفير الذاكرة: 1536-بُعد float32 (6KB) → PQ مع m=64 (64 بايت) = ~99% تخفيض

المقايضة: دقة استدعاء أقل (90-95%) مقابل توفير ذاكرة هائل.

طرق التكميم

الطريقة تخفيض الذاكرة تأثير الدقة
SQ (قياسي) 4x ضئيل
PQ (منتج) 32-64x معتدل
Binary 32x كبير
# تكميم Qdrant القياسي
client.create_collection(
    collection_name="documents",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
    quantization_config={
        "scalar": {
            "type": "int8",
            "quantile": 0.99,
            "always_ram": True
        }
    }
)

اختيار استراتيجية الفهرسة

البداية
< 10K متجه؟
  ├─ نعم → Flat (بحث دقيق)
ذاكرة محدودة؟
  ├─ نعم → IVF_PQ أو HNSW + تكميم قياسي
تحتاج أقل زمن استجابة؟
  ├─ نعم → HNSW (اضبط m و ef)
> 10M متجه مع احتياجات متوازنة؟
  ├─ نعم → IVF_HNSW هجين
الافتراضي → HNSW (أفضل مقايضة زمن استجابة/استدعاء)

وقت بناء الفهرس مقابل الاستعلام

الفهرس وقت البناء وقت الاستعلام الذاكرة
Flat O(n) O(n) 1x
IVF O(n log n) O(log n) 1.1x
HNSW O(n log n) O(log n) 1.5-2x
PQ O(n) O(log n) 0.1x

نصيحة إنتاج: ابدأ مع افتراضيات HNSW. اضبط المعلمات فقط عندما يكون لديك متطلبات محددة لزمن الاستجابة أو الاستدعاء. التحسين المسبق نادراً ما يكون ضرورياً.

التالي، لنستكشف تصفية البيانات الوصفية للتحكم الدقيق بالاسترجاع. :::

اختبار

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

خذ الاختبار