File size: 3,916 Bytes
c0b2a4d
 
 
 
 
 
 
 
da06f67
 
c0b2a4d
da06f67
c0b2a4d
 
 
da06f67
c0b2a4d
 
da06f67
c0b2a4d
 
 
 
 
 
da06f67
c0b2a4d
 
 
da06f67
c0b2a4d
 
 
 
 
da06f67
c0b2a4d
da06f67
c0b2a4d
 
da06f67
c0b2a4d
 
 
 
 
da06f67
c0b2a4d
 
 
 
 
 
 
 
 
da06f67
c0b2a4d
 
da06f67
c0b2a4d
 
 
 
da06f67
c0b2a4d
 
 
 
da06f67
c0b2a4d
309ee8b
c0b2a4d
 
 
 
 
 
 
da06f67
c0b2a4d
da06f67
 
c0b2a4d
 
 
 
da06f67
c0b2a4d
da06f67
c0b2a4d
 
 
da06f67
c0b2a4d
 
 
 
 
 
da06f67
c0b2a4d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import dspy, gradio as gr
import chromadb
from chromadb.config import Settings
import fitz  # PyMuPDF
from sentence_transformers import SentenceTransformer
import json
from dspy import Example, MIPROv2, Evaluate, evaluate

# ✅ إعداد نموذج مفتوح المصدر متوافق مع Hugging Face Spaces
dspy.settings.configure(lm=dspy.LM("mistralai/Mistral-7B-Instruct-v0.2"))

# إعداد قاعدة البيانات Chroma
client = chromadb.Client(Settings(chroma_db_impl="duckdb+parquet", persist_directory="./chroma_db"))
col = client.get_or_create_collection(name="arabic_docs", metadata={"hnsw:space": "cosine"})

# إعداد أداة توليد embeddings تدعم العربية
embedder = SentenceTransformer("sentence-transformers/LaBSE")

# تقطيع النصوص من ملفات PDF
def process_pdf(pdf_bytes):
    doc = fitz.open(stream=pdf_bytes, filetype="pdf")
    texts = []
    for p in doc:
        text = p.get_text()
        for chunk in text.split("\n\n"):
            if len(chunk.strip()) > 50:
                texts.append(chunk.strip())
    return texts

# إدخال النصوص إلى قاعدة البيانات
def ingest(pdf_bytes):
    texts = process_pdf(pdf_bytes)
    embeddings = embedder.encode(texts, show_progress_bar=True)
    for i, (chunk, emb) in enumerate(zip(texts, embeddings)):
        col.add(ids=[f"chunk_{i}"], embeddings=[emb.tolist()], metadatas=[{"text": chunk}])
    return f"✅ تمت إضافة {len(texts)} مقطعاً."

# محدد الاسترجاع
retriever = dspy.Retrieve(lambda q: [m["text"] for m in col.query(q, n_results=3)["metadatas"]], k=1)

# توقيع DSPy للإجابة باستخدام السياق
class RagSig(dspy.Signature):
    question: str
    context: str
    answer: str

# وحدة التنبؤ DSPy
class RagMod(dspy.Module):
    def __init__(self):
        super().__init__()
        self.predictor = dspy.Predict(RagSig)

    def forward(self, question):
        context = retriever(question)[0]
        return self.predictor(question=question, context=context)

# النموذج الأساسي
model = RagMod()

# التفاعل الأساسي
def answer(question):
    out = model(question)
    return out.answer

# تحميل بيانات التدريب
def load_dataset(path):
    with open(path, "r", encoding="utf-8") as f:
        return [Example(**json.loads(l)).with_inputs("question") for l in f]

# تحسين النموذج باستخدام MIPROv2
def optimize(train_file, val_file):
    global model
    trainset = load_dataset(train_file.name)
    valset = load_dataset(val_file.name)
    tp = MIPROv2(metric=evaluate.answer_exact_match, auto="light", num_threads=4)
    optimized = tp.compile(model, trainset=trainset, valset=valset)
    model = optimized
    return "✅ تم تحسين النموذج!"

# واجهة Gradio
with gr.Blocks() as demo:
    gr.Markdown("## 🧠 نظام RAG عربي باستخدام DSPy + نموذج مفتوح المصدر من Hugging Face")
    
    with gr.Tab("📥 تحميل وتخزين"):
        pdf_input = gr.File(label="ارفع ملف PDF")
        ingest_btn = gr.Button("إضافة إلى قاعدة البيانات")
        ingest_btn.click(ingest, inputs=pdf_input, outputs=gr.Textbox())
    
    with gr.Tab("❓ سؤال"):
        q = gr.Textbox(label="اكتب سؤالك بالعربية")
        answer_btn = gr.Button("احصل على الإجابة")
        out = gr.Textbox(label="الإجابة")
        answer_btn.click(answer, inputs=q, outputs=out)
    
    with gr.Tab("⚙️ تحسين النموذج"):
        train_file = gr.File(label="trainset.jsonl")
        val_file = gr.File(label="valset.jsonl")
        opt_btn = gr.Button("ابدأ التحسين")
        result = gr.Textbox(label="نتيجة التحسين")
        opt_btn.click(optimize, inputs=[train_file, val_file], outputs=result)

    demo.launch()