File size: 2,414 Bytes
593cb8c
 
 
 
 
 
 
1ad80f7
d9863ee
593cb8c
1ad80f7
5b902e6
 
 
593cb8c
1ad80f7
593cb8c
 
 
d9863ee
593cb8c
 
 
 
 
1ad80f7
593cb8c
1ad80f7
 
 
d9863ee
 
593cb8c
 
 
d9863ee
1ad80f7
d9863ee
1ad80f7
d9863ee
593cb8c
 
d9863ee
1ad80f7
 
 
d9863ee
 
 
 
 
 
1ad80f7
d9863ee
593cb8c
 
d9863ee
 
 
1ad80f7
 
d9863ee
593cb8c
 
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
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
from transformers import AutoTokenizer, AutoModelForCausalLM

class RAG:
    def __init__(self):
        # Multilingual embedding -> مناسب فارسی + انگلیسی
        self.embedder = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")

        # LLM multilingual lightweight
        self.tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-3B-Instruct")
        self.model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-3B-Instruct")


        # Load dataset
        with open("data.txt", "r", encoding="utf-8") as f:
            self.texts = [line.strip() for line in f if line.strip()]

        # Build FAISS index
        embeddings = self.embedder.encode(self.texts)
        dim = embeddings.shape[1]
        self.index = faiss.IndexFlatL2(dim)
        self.index.add(np.array(embeddings, dtype=np.float32))

    def retrieve(self, query, k=4):
        q_emb = self.embedder.encode([query])
        distances, indices = self.index.search(
            np.array(q_emb, dtype=np.float32), k
        )
        results = [self.texts[i] for i in indices[0]]
        return results

    def generate_answer(self, question):
        retrieved = self.retrieve(question)

        # No relevant data found
        if not retrieved or len("".join(retrieved).strip()) == 0:
            return "در داده‌هایی که دارم پاسخی برای این سؤال وجود ندارد."

        context = "\n".join(retrieved)

        prompt = f"""
شما یک مدل زبانی هستید که فقط و فقط اجازه دارید بر اساس اطلاعات زیر پاسخ بدهید.
هیچ دانشی خارج از متن‌ها استفاده نکنید، و هیچ خلاقیتی نداشته باشید.
پاسخ باید کاملاً فارسی، دقیق و برگرفته از داده‌ها باشد.

اطلاعات:
{context}

سؤال: {question}

پاسخ دقیق فارسی بر اساس اطلاعات بالا:
"""

        inputs = self.tokenizer(prompt, return_tensors="pt")
        output = self.model.generate(
            **inputs,
            max_new_tokens=200,
            do_sample=False,      # no creativity
            temperature=0.0,      # deterministic
        )

        return self.tokenizer.decode(output[0], skip_special_tokens=True)