Update app.py
Browse files
app.py
CHANGED
@@ -17,6 +17,7 @@ import faiss
|
|
17 |
# ----------------- تنظیمات صفحه -----------------
|
18 |
st.set_page_config(page_title="چت بات توانا", page_icon="🪖", layout="wide")
|
19 |
|
|
|
20 |
st.markdown("""
|
21 |
<style>
|
22 |
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
|
@@ -84,17 +85,6 @@ st.markdown("""
|
|
84 |
</style>
|
85 |
""", unsafe_allow_html=True)
|
86 |
|
87 |
-
col1, col2, col3 = st.columns([1, 0.1, 1])
|
88 |
-
with col2:
|
89 |
-
st.image("army.png", width=240)
|
90 |
-
|
91 |
-
st.markdown("""
|
92 |
-
<div class="header-text">
|
93 |
-
<h1>چت بات توانا</h1>
|
94 |
-
<div class="subtitle">دستیار هوشمند برای تصمیمگیری در میدان نبرد</div>
|
95 |
-
</div>
|
96 |
-
""", unsafe_allow_html=True)
|
97 |
-
|
98 |
# ----------------- لود PDF و ساخت ایندکس -----------------
|
99 |
|
100 |
@st.cache_resource
|
@@ -103,47 +93,23 @@ def get_pdf_index():
|
|
103 |
loader = PyPDFLoader('test1.pdf')
|
104 |
documents = loader.load()
|
105 |
|
106 |
-
splitter = RecursiveCharacterTextSplitter(chunk_size=
|
107 |
texts = []
|
108 |
for doc in documents:
|
109 |
texts.extend(splitter.split_text(doc.page_content))
|
110 |
|
111 |
-
|
112 |
-
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
|
113 |
|
114 |
-
# تولید امبدینگها
|
115 |
embeddings = model.encode(texts, convert_to_numpy=True)
|
116 |
|
117 |
-
|
118 |
-
index
|
119 |
index.add(embeddings)
|
120 |
|
121 |
docs = [{"text": text} for text in texts]
|
122 |
|
123 |
return docs, embeddings, index, model
|
124 |
|
125 |
-
# ----------------- تعریف LLM -----------------
|
126 |
-
llm = ChatOpenAI(
|
127 |
-
base_url="https://api.together.xyz/v1",
|
128 |
-
api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
|
129 |
-
model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free"
|
130 |
-
)
|
131 |
-
|
132 |
-
# ----------------- تعریف SimpleRetriever -----------------
|
133 |
-
class SimpleRetriever(BaseRetriever):
|
134 |
-
documents: List[dict] = Field(...)
|
135 |
-
embeddings: np.ndarray = Field(...)
|
136 |
-
index: faiss.Index
|
137 |
-
model: SentenceTransformer
|
138 |
-
|
139 |
-
def _get_relevant_documents(self, query: str) -> List[Document]:
|
140 |
-
query_embedding = self.model.encode([query], convert_to_numpy=True)
|
141 |
-
_, indices = self.index.search(query_embedding, 5)
|
142 |
-
results = []
|
143 |
-
for i in indices[0]:
|
144 |
-
results.append(Document(page_content=self.documents[i]['text']))
|
145 |
-
return results
|
146 |
-
|
147 |
# ----------------- بارگذاری دیتا -----------------
|
148 |
documents, embeddings, index, model = get_pdf_index()
|
149 |
|
@@ -153,22 +119,14 @@ retriever = SimpleRetriever(
|
|
153 |
index=index,
|
154 |
model=model
|
155 |
)
|
156 |
-
custom_prompt = PromptTemplate(
|
157 |
-
input_variables=["context", "question"],
|
158 |
-
template="""
|
159 |
-
شما فقط مجاز هستید از اطلاعات زیر پاسخ دهید. اگر اطلاعات لازم برای پاسخ دقیق وجود ندارد، لطفاً تلاش کنید تا نزدیکترین و مفیدترین پاسخ را از اطلاعات موجود پیدا کنید. در صورتی که اطلاعات مورد نظر وجود ندارد، بهجای دادن جواب نادرست، بگویید که اطلاعات مورد نیاز را ندارید یا نمیتوانید پاسخ دقیقی بدهید.
|
160 |
-
|
161 |
-
اطلاعات:
|
162 |
-
{context}
|
163 |
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
""
|
169 |
)
|
170 |
|
171 |
-
|
172 |
# ----------------- ساخت Chain -----------------
|
173 |
qa_chain = RetrievalQA.from_chain_type(
|
174 |
llm=llm,
|
@@ -204,16 +162,20 @@ if st.session_state.pending_prompt:
|
|
204 |
thinking.markdown("🤖 در حال فکر کردن...")
|
205 |
|
206 |
try:
|
|
|
207 |
response = qa_chain.run(st.session_state.pending_prompt)
|
208 |
-
|
|
|
|
|
|
|
209 |
except Exception as e:
|
210 |
-
|
211 |
|
212 |
thinking.empty()
|
213 |
|
214 |
full_response = ""
|
215 |
placeholder = st.empty()
|
216 |
-
for word in
|
217 |
full_response += word + " "
|
218 |
placeholder.markdown(full_response + "▌")
|
219 |
time.sleep(0.03)
|
|
|
17 |
# ----------------- تنظیمات صفحه -----------------
|
18 |
st.set_page_config(page_title="چت بات توانا", page_icon="🪖", layout="wide")
|
19 |
|
20 |
+
# تنظیمات استایل
|
21 |
st.markdown("""
|
22 |
<style>
|
23 |
@import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap');
|
|
|
85 |
</style>
|
86 |
""", unsafe_allow_html=True)
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
# ----------------- لود PDF و ساخت ایندکس -----------------
|
89 |
|
90 |
@st.cache_resource
|
|
|
93 |
loader = PyPDFLoader('test1.pdf')
|
94 |
documents = loader.load()
|
95 |
|
96 |
+
splitter = RecursiveCharacterTextSplitter(chunk_size=1024, chunk_overlap=256)
|
97 |
texts = []
|
98 |
for doc in documents:
|
99 |
texts.extend(splitter.split_text(doc.page_content))
|
100 |
|
101 |
+
model = SentenceTransformer("togethercomputer/m2-bert-80M-8k-retrieval", trust_remote_code=True)
|
|
|
102 |
|
|
|
103 |
embeddings = model.encode(texts, convert_to_numpy=True)
|
104 |
|
105 |
+
index = faiss.IndexIVFFlat(embeddings.shape[1], 100)
|
106 |
+
index.train(embeddings)
|
107 |
index.add(embeddings)
|
108 |
|
109 |
docs = [{"text": text} for text in texts]
|
110 |
|
111 |
return docs, embeddings, index, model
|
112 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
# ----------------- بارگذاری دیتا -----------------
|
114 |
documents, embeddings, index, model = get_pdf_index()
|
115 |
|
|
|
119 |
index=index,
|
120 |
model=model
|
121 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
|
123 |
+
# ----------------- تعریف LLM -----------------
|
124 |
+
llm = ChatOpenAI(
|
125 |
+
base_url="https://api.together.xyz/v1",
|
126 |
+
api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
|
127 |
+
model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free"
|
128 |
)
|
129 |
|
|
|
130 |
# ----------------- ساخت Chain -----------------
|
131 |
qa_chain = RetrievalQA.from_chain_type(
|
132 |
llm=llm,
|
|
|
162 |
thinking.markdown("🤖 در حال فکر کردن...")
|
163 |
|
164 |
try:
|
165 |
+
# اگر مدل نتواند پاسخ دقیقی پیدا کند
|
166 |
response = qa_chain.run(st.session_state.pending_prompt)
|
167 |
+
if not response.strip(): # اگر پاسخ خالی یا بیفایده بود
|
168 |
+
response = "متاسفانه اطلاعات دقیقی برای پاسخ به این سوال موجود نیست."
|
169 |
+
else:
|
170 |
+
response = response.strip()
|
171 |
except Exception as e:
|
172 |
+
response = "متاسفانه اطلاعات لازم برای پاسخ به این سوال موجود نیست."
|
173 |
|
174 |
thinking.empty()
|
175 |
|
176 |
full_response = ""
|
177 |
placeholder = st.empty()
|
178 |
+
for word in response.split():
|
179 |
full_response += word + " "
|
180 |
placeholder.markdown(full_response + "▌")
|
181 |
time.sleep(0.03)
|