M17idd commited on
Commit
0de879f
·
verified ·
1 Parent(s): f656688

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -55
app.py CHANGED
@@ -10,7 +10,7 @@ from langchain.chat_models import ChatOpenAI
10
  from typing import List
11
  from together import Together
12
  import pandas as pd
13
- import streamlit as st
14
 
15
  # ----------------- تنظیمات صفحه -----------------
16
  st.set_page_config(page_title="رزم یار ارتش", page_icon="🪖", layout="wide")
@@ -182,14 +182,16 @@ st.markdown('<div class="chat-message">👋 سلام! چطور میتونم کم
182
 
183
 
184
  # ----------------- لود csv و ساخت ایندکس -----------------
 
 
 
185
  class TogetherEmbeddings(Embeddings):
186
  def __init__(self, model_name: str, api_key: str):
187
  self.model_name = model_name
188
  self.client = Together(api_key=api_key)
189
 
190
  def embed_documents(self, texts: List[str]) -> List[List[float]]:
191
- # تقسیم متن‌ها به دسته‌های کوچک‌تر برای جلوگیری از خطای 413
192
- batch_size = 100 # این مقدار را می‌توانید تنظیم کنید
193
  embeddings = []
194
  for i in range(0, len(texts), batch_size):
195
  batch = texts[i:i + batch_size]
@@ -200,84 +202,64 @@ class TogetherEmbeddings(Embeddings):
200
  def embed_query(self, text: str) -> List[float]:
201
  return self.embed_documents([text])[0]
202
 
 
203
  @st.cache_resource
204
  def get_csv_index(csv_file):
205
  with st.spinner('📄 در حال پردازش فایل CSV...'):
206
- # خواندن داده‌های CSV
207
  df = pd.read_csv(csv_file)
208
-
209
- # تبدیل DataFrame به لیست از متون
210
- texts = df.iloc[:, 0].astype(str).tolist() # ستون اول را می‌گیرد
211
-
212
- # فیلتر کردن متن‌های خالی
213
  texts = [text for text in texts if text.strip()]
214
-
215
- # تقسیم متن‌های طولانی به بخش‌های کوچکتر
216
  text_splitter = RecursiveCharacterTextSplitter(
217
  chunk_size=2048,
218
  chunk_overlap=256,
219
  length_function=len,
220
  separators=["\n\n", "\n", " ", ""]
221
  )
222
-
223
  split_texts = []
224
  for text in texts:
225
  split_texts.extend(text_splitter.split_text(text))
226
 
227
- # ایجاد embeddings
 
228
  embeddings = TogetherEmbeddings(
229
  model_name="togethercomputer/m2-bert-80M-8k-retrieval",
230
  api_key="0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979"
231
  )
232
 
233
- # استفاده از VectorstoreIndexCreator برای ساخت ایندکس
234
- index_creator = VectorstoreIndexCreator(
235
- embedding=embeddings,
236
- text_splitter=text_splitter
237
- )
238
-
239
- # تبدیل متون به اسناد (documents)
240
- from langchain.docstore.document import Document
241
- documents = [Document(page_content=text) for text in split_texts]
242
-
243
- return index_creator.from_documents(documents)
244
 
245
- # مسیر فایل CSV
246
  csv_file_path = 'output (1).csv'
247
 
248
  try:
249
- # ساخت ایندکس
250
- csv_index = get_csv_index(csv_file_path)
251
- # st.success("ایندکس فایل CSV با موفقیت ساخته شد!")
252
  except Exception as e:
253
  st.error(f"خطا در ساخت ایندکس: {str(e)}")
 
254
 
255
-
256
-
257
- #------------------------------------------
258
  llm = ChatOpenAI(
259
  base_url="https://api.together.xyz/v1",
260
  api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
261
- model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free"
262
- )
263
-
264
- chain = RetrievalQA.from_chain_type(
265
- llm=llm,
266
- chain_type='stuff',
267
- retriever=csv_index.vectorstore.as_retriever(),
268
- input_key='question'
269
  )
270
 
 
271
  if 'messages' not in st.session_state:
272
  st.session_state.messages = []
273
 
274
  if 'pending_prompt' not in st.session_state:
275
  st.session_state.pending_prompt = None
276
 
 
277
  for msg in st.session_state.messages:
278
  with st.chat_message(msg['role']):
279
  st.markdown(f"🗨️ {msg['content']}", unsafe_allow_html=True)
280
 
 
281
  prompt = st.chat_input("چطور می‌تونم کمک کنم؟")
282
 
283
  if prompt:
@@ -285,24 +267,45 @@ if prompt:
285
  st.session_state.pending_prompt = prompt
286
  st.rerun()
287
 
 
288
  if st.session_state.pending_prompt:
289
  with st.chat_message('ai'):
290
  thinking = st.empty()
291
  thinking.markdown("🤖 در حال فکر کردن...")
292
 
293
- response = chain.run(f'پاسخ را فقط به زبان فارسی جواب بده به هیچ عنوان از زبان غیر از فارسی در پاسخ استفاده نکن. سوال: {st.session_state.pending_prompt}')
294
- answer = response.split("Helpful Answer:")[-1].strip() if "Helpful Answer:" in response else response.strip()
295
- if not answer:
296
- answer = "متأسفم، اطلاعات دقیقی در این مورد ندارم."
297
-
298
- thinking.empty()
299
- full_response = ""
300
- placeholder = st.empty()
301
- for word in answer.split():
302
- full_response += word + " "
303
- placeholder.markdown(full_response + "")
304
- time.sleep(0.03)
305
-
306
- placeholder.markdown(full_response)
307
- st.session_state.messages.append({'role': 'ai', 'content': full_response})
308
- st.session_state.pending_prompt = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  from typing import List
11
  from together import Together
12
  import pandas as pd
13
+ from langchain.docstore.document import Document
14
 
15
  # ----------------- تنظیمات صفحه -----------------
16
  st.set_page_config(page_title="رزم یار ارتش", page_icon="🪖", layout="wide")
 
182
 
183
 
184
  # ----------------- لود csv و ساخت ایندکس -----------------
185
+
186
+
187
+ # --- Embedding Class ---
188
  class TogetherEmbeddings(Embeddings):
189
  def __init__(self, model_name: str, api_key: str):
190
  self.model_name = model_name
191
  self.client = Together(api_key=api_key)
192
 
193
  def embed_documents(self, texts: List[str]) -> List[List[float]]:
194
+ batch_size = 100
 
195
  embeddings = []
196
  for i in range(0, len(texts), batch_size):
197
  batch = texts[i:i + batch_size]
 
202
  def embed_query(self, text: str) -> List[float]:
203
  return self.embed_documents([text])[0]
204
 
205
+ # --- Load CSV and Create Index ---
206
  @st.cache_resource
207
  def get_csv_index(csv_file):
208
  with st.spinner('📄 در حال پردازش فایل CSV...'):
 
209
  df = pd.read_csv(csv_file)
210
+ texts = df.iloc[:, 0].astype(str).tolist()
 
 
 
 
211
  texts = [text for text in texts if text.strip()]
212
+
 
213
  text_splitter = RecursiveCharacterTextSplitter(
214
  chunk_size=2048,
215
  chunk_overlap=256,
216
  length_function=len,
217
  separators=["\n\n", "\n", " ", ""]
218
  )
219
+
220
  split_texts = []
221
  for text in texts:
222
  split_texts.extend(text_splitter.split_text(text))
223
 
224
+ documents = [Document(page_content=text) for text in split_texts]
225
+
226
  embeddings = TogetherEmbeddings(
227
  model_name="togethercomputer/m2-bert-80M-8k-retrieval",
228
  api_key="0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979"
229
  )
230
 
231
+ vectorstore = FAISS.from_documents(documents, embeddings)
232
+ return vectorstore, embeddings
 
 
 
 
 
 
 
 
 
233
 
234
+ # --- Load CSV ---
235
  csv_file_path = 'output (1).csv'
236
 
237
  try:
238
+ vectorstore, embedding_model = get_csv_index(csv_file_path)
 
 
239
  except Exception as e:
240
  st.error(f"خطا در ساخت ایندکس: {str(e)}")
241
+ st.stop()
242
 
243
+ # --- Load LLM ---
 
 
244
  llm = ChatOpenAI(
245
  base_url="https://api.together.xyz/v1",
246
  api_key='0291f33aee03412a47fa5d8e562e515182dcc5d9aac5a7fb5eefdd1759005979',
247
+ model="meta-llama/Llama-3-70B-Instruct"
 
 
 
 
 
 
 
248
  )
249
 
250
+ # --- Chat UI ---
251
  if 'messages' not in st.session_state:
252
  st.session_state.messages = []
253
 
254
  if 'pending_prompt' not in st.session_state:
255
  st.session_state.pending_prompt = None
256
 
257
+ # نمایش پیام‌های قبلی
258
  for msg in st.session_state.messages:
259
  with st.chat_message(msg['role']):
260
  st.markdown(f"🗨️ {msg['content']}", unsafe_allow_html=True)
261
 
262
+ # ورودی جدید کاربر
263
  prompt = st.chat_input("چطور می‌تونم کمک کنم؟")
264
 
265
  if prompt:
 
267
  st.session_state.pending_prompt = prompt
268
  st.rerun()
269
 
270
+ # پردازش سوال
271
  if st.session_state.pending_prompt:
272
  with st.chat_message('ai'):
273
  thinking = st.empty()
274
  thinking.markdown("🤖 در حال فکر کردن...")
275
 
276
+ try:
277
+ # امبد کردن سوال
278
+ query = st.session_state.pending_prompt
279
+ query_embedding = embedding_model.embed_query(query)
280
+
281
+ # بازیابی اسناد مشابه
282
+ docs = vectorstore.similarity_search_by_vector(query_embedding, k=4)
283
+ context = "\n".join([doc.page_content for doc in docs])
284
+
285
+ # ساخت پرامپت نهایی برای LLM
286
+ final_prompt = f"""با توجه به اطلاعات زیر پاسخ بده. فقط به زبان فارسی پاسخ بده:
287
+ اطلاعات:\n{context}\n\nسوال: {query}
288
+ """
289
+
290
+ # ارسال به LLM
291
+ response = llm.invoke(final_prompt)
292
+ answer = response.content.strip()
293
+ if not answer:
294
+ answer = "متأسفم، اطلاعات دقیقی در این مورد ندارم."
295
+
296
+ # تایپ کردن تدریجی پاسخ
297
+ thinking.empty()
298
+ full_response = ""
299
+ placeholder = st.empty()
300
+ for word in answer.split():
301
+ full_response += word + " "
302
+ placeholder.markdown(full_response + "▌")
303
+ time.sleep(0.03)
304
+
305
+ placeholder.markdown(full_response)
306
+ st.session_state.messages.append({'role': 'ai', 'content': full_response})
307
+ st.session_state.pending_prompt = None
308
+
309
+ except Exception as e:
310
+ thinking.empty()
311
+ st.error(f"خطا در پاسخ‌دهی: {str(e)}")