الدرس 12 من 22

أنماط نماذج اللغة المحلية المتقدمة

التضمينات المحلية

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

التضمينات هي أساس RAG، البحث الدلالي، والعديد من تطبيقات الذكاء الاصطناعي. تشغيلها محلياً يمنحك الخصوصية وتوفير التكاليف على نطاق واسع.

نماذج التضمين المحلية

┌─────────────────────────────────────────────────────────────────┐
│                   نماذج التضمين المحلية الشائعة                  │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  النموذج             │ الأبعاد    │ السرعة   │ الأفضل لـ         │
│  ────────────────────│────────────│──────────│─────────────     │
│  nomic-embed-text    │ 768        │ سريع     │ نص عام           │
│  mxbai-embed-large   │ 1024       │ متوسط    │ دقة عالية        │
│  all-minilm          │ 384        │ سريع جداً│ أولوية السرعة    │
│  snowflake-arctic    │ 1024       │ متوسط    │ المؤسسات         │
│  bge-large           │ 1024       │ متوسط    │ متعدد اللغات     │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

استخدام Ollama للتضمينات

# اسحب نموذج تضمين
ollama pull nomic-embed-text

# ولّد تضمينات عبر CLI
echo '{"model": "nomic-embed-text", "input": "Hello world"}' | \
  curl -s http://localhost:11434/api/embed -d @-

التنفيذ بـ Python

import ollama
import numpy as np

def get_embedding(text: str, model: str = "nomic-embed-text") -> list[float]:
    """ولّد تضمين لنص واحد."""
    response = ollama.embed(model=model, input=text)
    return response["embeddings"][0]

def get_embeddings(texts: list[str], model: str = "nomic-embed-text") -> list[list[float]]:
    """ولّد تضمينات لنصوص متعددة."""
    response = ollama.embed(model=model, input=texts)
    return response["embeddings"]

# مثال الاستخدام
embedding = get_embedding("Machine learning is transforming industries")
print(f"بُعد التضمين: {len(embedding)}")

البحث عن التشابه الدلالي

import ollama
import numpy as np
from typing import List, Tuple

class LocalVectorStore:
    """مخزن متجهات بسيط في الذاكرة مع تضمينات محلية."""

    def __init__(self, model: str = "nomic-embed-text"):
        self.model = model
        self.documents: list[str] = []
        self.embeddings: list[list[float]] = []

    def add_documents(self, documents: list[str]):
        """أضف مستندات للمخزن."""
        new_embeddings = ollama.embed(
            model=self.model,
            input=documents
        )["embeddings"]

        self.documents.extend(documents)
        self.embeddings.extend(new_embeddings)

    def search(self, query: str, top_k: int = 3) -> list[tuple[str, float]]:
        """ابحث عن مستندات مشابهة."""
        query_embedding = ollama.embed(
            model=self.model,
            input=query
        )["embeddings"][0]

        # احسب التشابهات
        similarities = []
        for i, doc_embedding in enumerate(self.embeddings):
            sim = self._cosine_similarity(query_embedding, doc_embedding)
            similarities.append((self.documents[i], sim))

        # رتب حسب التشابه (تنازلي)
        similarities.sort(key=lambda x: x[1], reverse=True)
        return similarities[:top_k]

    def _cosine_similarity(self, a: list[float], b: list[float]) -> float:
        """احسب تشابه جيب التمام بين متجهين."""
        a, b = np.array(a), np.array(b)
        return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# الاستخدام
store = LocalVectorStore()
store.add_documents([
    "Python is a programming language",
    "JavaScript runs in web browsers",
    "Machine learning uses neural networks",
    "Python is popular for data science"
])

results = store.search("What language is good for AI?")
for doc, score in results:
    print(f"{score:.3f}: {doc}")

المعالجة الدفعية لمجموعات البيانات الكبيرة

import ollama
from tqdm import tqdm

def embed_large_dataset(
    documents: list[str],
    model: str = "nomic-embed-text",
    batch_size: int = 100
) -> list[list[float]]:
    """ضمّن مجموعات بيانات كبيرة في دفعات."""
    all_embeddings = []

    for i in tqdm(range(0, len(documents), batch_size)):
        batch = documents[i:i + batch_size]
        response = ollama.embed(model=model, input=batch)
        all_embeddings.extend(response["embeddings"])

    return all_embeddings

# عالج 10,000 مستند
documents = [f"Document {i} content here" for i in range(10000)]
embeddings = embed_large_dataset(documents)

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

import ollama
import numpy as np
import time

def benchmark_embedding_model(model: str, texts: list[str]) -> dict:
    """قيّم نموذج تضمين."""
    start = time.time()
    response = ollama.embed(model=model, input=texts)
    elapsed = time.time() - start

    embeddings = response["embeddings"]
    return {
        "model": model,
        "dimension": len(embeddings[0]),
        "time_seconds": elapsed,
        "texts_per_second": len(texts) / elapsed
    }

# نصوص الاختبار
test_texts = ["This is a test sentence"] * 100

# قارن النماذج
models = ["nomic-embed-text", "all-minilm", "mxbai-embed-large"]
for model in models:
    try:
        result = benchmark_embedding_model(model, test_texts)
        print(f"{result['model']}: {result['dimension']}d, "
              f"{result['texts_per_second']:.1f} نص/ثانية")
    except Exception as e:
        print(f"{model}: غير متاح ({e})")

حفظ التضمينات

import ollama
import numpy as np
import json

def save_embeddings(documents: list[str], embeddings: list[list[float]], path: str):
    """احفظ المستندات والتضمينات للقرص."""
    data = {
        "documents": documents,
        "embeddings": embeddings
    }
    with open(path, "w") as f:
        json.dump(data, f)

def load_embeddings(path: str) -> tuple[list[str], list[list[float]]]:
    """حمّل المستندات والتضمينات من القرص."""
    with open(path, "r") as f:
        data = json.load(f)
    return data["documents"], data["embeddings"]

# احفظ
documents = ["Doc 1", "Doc 2", "Doc 3"]
embeddings = ollama.embed(model="nomic-embed-text", input=documents)["embeddings"]
save_embeddings(documents, embeddings, "embeddings.json")

# حمّل لاحقاً
docs, embs = load_embeddings("embeddings.json")

تكامل LangChain

from langchain_ollama import OllamaEmbeddings
from langchain_community.vectorstores import FAISS

# هيئ تضمينات محلية
embeddings = OllamaEmbeddings(model="nomic-embed-text")

# أنشئ مخزن متجهات مع تضمينات محلية
documents = [
    "Python is great for AI",
    "JavaScript is for web development",
    "Rust is systems programming"
]

vectorstore = FAISS.from_texts(documents, embeddings)

# ابحث
results = vectorstore.similarity_search("AI programming", k=2)
for doc in results:
    print(doc.page_content)

دليل اختيار النموذج

حالة الاستخدام النموذج الموصى لماذا
غرض عام nomic-embed-text توازن جيد للسرعة والجودة
دقة عالية mxbai-embed-large أفضل أداء استرجاع
أولوية السرعة all-minilm الأسرع، أبعاد أصغر
متعدد اللغات bge-large يتعامل مع لغات متعددة

التضمينات المحلية تفتح البحث الدلالي المحافظ على الخصوصية. في الدرس التالي، سنبني خط أنابيب RAG محلي كامل. :::

اختبار

الوحدة 4: أنماط نماذج اللغة المحلية المتقدمة

خذ الاختبار