rag22v2 / rag_pipeline.py
ramysaidagieb's picture
Upload 5 files
c90b40e verified
raw
history blame
3.4 kB
from sentence_transformers import CrossEncoder, SentenceTransformer
from transformers import AutoTokenizer, AutoModelForCausalLM
import faiss
import numpy as np
from typing import List, Dict
class ArabicRAGSystem:
def __init__(self):
# Initialize models
self.embedding_model = SentenceTransformer("aubmindlab/bert-base-arabertv2")
self.cross_encoder = CrossEncoder("Arabic-Misc/roberta-base-arabic-camelbert-da-msa")
self.tokenizer = AutoTokenizer.from_pretrained("inception-mbzuai/jais-13b-chat")
self.llm = AutoModelForCausalLM.from_pretrained("inception-mbzuai/jais-13b-chat")
self.index = faiss.IndexFlatL2(768)
def _create_index(self, documents: List[Dict]):
texts = [doc["text"] for doc in documents]
embeddings = self.embedding_model.encode(texts)
self.index.add(np.array(embeddings))
def generate_answer(self, question: str, documents: List[Dict],
top_k: int = 5, temperature: float = 0.7) -> tuple:
# Indexing phase
self._create_index(documents)
# Two-stage retrieval
query_embedding = self.embedding_model.encode([question])
distances, indices = self.index.search(query_embedding, top_k*2)
# Re-ranking with cross-encoder
pairs = [[question, documents[idx]["text"]] for idx in indices[0]]
scores = self.cross_encoder.predict(pairs)
ranked_indices = np.argsort(scores)[::-1][:top_k]
# Prepare context
context = "\n\n".join([
f"المصدر: {documents[idx]['source']}\n"
f"الصفحة: {documents[idx]['page']}\n"
f"النص: {documents[idx]['text']}"
for idx in [indices[0][i] for i in ranked_indices]
])
# Generate answer
prompt = f"""
أنت خبير في التحليل الديني. قم بالإجابة على السؤال التالي بناءً على السياق المقدم فقط:
السياق:
{context}
السؤال:
{question}
التعليمات:
- أجب باللغة العربية الفصحى
- استخدم علامات التنسيق المناسبة
- أشر إلى المصادر باستخدام التنسيق [المصدر: اسم الملف، الصفحة: رقم]
- إذا لم توجد إجابة واضحة، قل "لا تتوفر معلومات كافية"
الإجابة:
""".strip()
inputs = self.tokenizer(prompt, return_tensors="pt")
outputs = self.llm.generate(
inputs.input_ids,
max_new_tokens=512,
temperature=temperature,
do_sample=True,
pad_token_id=self.tokenizer.eos_token_id
)
answer = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
answer = answer.split("الإجابة:")[-1].strip()
# Prepare sources
sources = []
for idx in [indices[0][i] for i in ranked_indices]:
sources.append({
"text": documents[idx]["text"],
"source": documents[idx]["source"],
"page": documents[idx]["page"],
"score": float(scores[idx])
})
return answer, sources