I77 commited on
Commit
a361ca0
·
verified ·
1 Parent(s): 14487bd

Upload 15 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ data/chunks.json filter=lfs diff=lfs merge=lfs -text
37
+ data/embeddings.index filter=lfs diff=lfs merge=lfs -text
app.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from src.retriever import CustomRetriever
3
+ from src.generator import CustomGenerator
4
+ from src.model import MyRagModel
5
+
6
+ retriever = CustomRetriever(r'data/chunks.json', r'data/embeddings.index', r'data/metadata.json')
7
+ generator = CustomGenerator()
8
+ rag = MyRagModel(retriever, generator)
9
+
10
+
11
+ def generate_response(query):
12
+ return rag.get_answer(query)
13
+
14
+
15
+ interface = gr.Interface(
16
+ fn=generate_response,
17
+ inputs=gr.Textbox(label='Введите ваш вопрос: '),
18
+ outputs=gr.Textbox(label='Ответ модели: '),
19
+ title='Rag Model Demo',
20
+ description='QA ассистент по вопросам законов Кыргызской Республики. Может отвечать на вопросы по типу: '
21
+ '"Сколько лет дают за убийство человека?"',
22
+ allow_flagging='never',
23
+ )
24
+
25
+
26
+ if __name__ == '__main__':
27
+ interface.launch(share=True)
data/chunks.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5490a3392697cd1e719445197aa3ebf4bc1ee6e3b954f231c1cc1ba97e740b61
3
+ size 19871573
data/embeddings.index ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:feb52c93f3dbfe55c29a6fd605898862ea2fe483687451f0706c07fa06984118
3
+ size 46215213
data/metadata.json ADDED
The diff for this file is too large to render. See raw diff
 
requirements.txt ADDED
Binary file (2.46 kB). View file
 
src/__init__.py ADDED
File without changes
src/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (170 Bytes). View file
 
src/__pycache__/generator.cpython-311.pyc ADDED
Binary file (3.1 kB). View file
 
src/__pycache__/model.cpython-311.pyc ADDED
Binary file (1.12 kB). View file
 
src/__pycache__/retriever.cpython-311.pyc ADDED
Binary file (3.32 kB). View file
 
src/config.py ADDED
File without changes
src/generator.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from groq import Client
2
+
3
+
4
+ class CustomGenerator:
5
+ def __init__(self, model_name='llama-3.3-70b-versatile',
6
+ api_key='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'):
7
+ self.model = model_name
8
+ self.client = Client(api_key=api_key)
9
+ self.system_prompt = """
10
+ Ты Q&A ассистент по вопросам законов Кыргызской Республики (Кыргызстана).
11
+ Твоя задача - ответить на заданный вопрос на основе переданной тебе информации.
12
+ Если вопрос касается законов Кыргызской республики, но в контексте нет ответа,
13
+ то ответь, что ты не знаешь ответа на этот вопрос. А если же вопрос не касается
14
+ законов Кыргызской Республики, то ответь только то, что ты не знаешь, потому что
15
+ ты помощник по вопросам законов Кыргызской Республики!
16
+ Укажи исходя из какой книги ответ, и сошлись на номер статьи, в конце ответа приведи добавь ссылку на книгу.
17
+ Ответ обязательно должен быть на русском, если ты придумал его на другом языке, то потом обязательно переведи на русский.
18
+ """
19
+
20
+ def generate(self, query, context):
21
+ query_wrapper = f"""
22
+ На основе вот этой информации {context},
23
+ ответь на вопрос клиента {query},
24
+ не забудь добавить источник ответа и
25
+ не забудь, что ответ должен быть на русском.
26
+ """
27
+ response = self.client.chat.completions.create(
28
+ model=self.model,
29
+ messages=[
30
+ {"role": "system", "content": self.system_prompt},
31
+ {"role": "user", "content": query_wrapper},
32
+ ]
33
+ )
34
+
35
+ return response.choices[0].message.content
src/model.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .retriever import CustomRetriever
2
+ from .generator import CustomGenerator
3
+
4
+
5
+ class MyRagModel:
6
+ def __init__(self, retriever: CustomRetriever, generator: CustomGenerator):
7
+ self.retriever = retriever
8
+ self.generator = generator
9
+
10
+ def get_answer(self, query):
11
+ context = self.retriever.retrieve(query)
12
+ response = self.generator.generate(query, context)
13
+ return response
src/retriever.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from sentence_transformers import CrossEncoder
2
+ from sentence_transformers import SentenceTransformer
3
+ import faiss
4
+ import json
5
+
6
+
7
+ class CustomRetriever:
8
+ def __init__(self, chunks_path, embeddings_path, metadata_path, top_k=50):
9
+ self.model_bi = SentenceTransformer("deepvk/USER-bge-m3")
10
+ self.model_cross = CrossEncoder("DiTy/cross-encoder-russian-msmarco")
11
+ with open(chunks_path, "r") as f:
12
+ self.chunks = json.load(f)
13
+ self.index = faiss.read_index(embeddings_path)
14
+ self.top_k = top_k
15
+ with open(metadata_path, "r") as f:
16
+ self.metadata = json.load(f)
17
+
18
+ def retrieve(self, query):
19
+ query_vector = self.model_bi.encode([query])
20
+ faiss.normalize_L2(query_vector)
21
+ distances, indices = self.index.search(query_vector, self.top_k)
22
+ possible_answers = list()
23
+ for i in range(len(indices[0])):
24
+ possible_answers.append(self.chunks[indices[0][i]])
25
+ s = self.model_cross.rank(query, possible_answers)
26
+ context = ''
27
+ for i in range(5):
28
+ meta = self.metadata[str(indices[0][s[i]["corpus_id"]])]
29
+ context += f"Факт {str(i + 1)}: {possible_answers[s[i]['corpus_id']]}. Источник:\nкнига - {meta['book']}\nномер статьи - {meta['article_num']}\nссылка на книгу - {meta['link']}\n"
30
+ return context
src/utils.py ADDED
File without changes