aysemutluay commited on
Commit
03e44d4
·
verified ·
1 Parent(s): 3e8a039

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -49
app.py CHANGED
@@ -3,7 +3,6 @@ import PyPDF2
3
  from langchain.text_splitter import RecursiveCharacterTextSplitter
4
  from langchain.embeddings import HuggingFaceEmbeddings
5
  from langchain.vectorstores import FAISS
6
- # DÜZELTME 1: Gerekli model sınıfını import et
7
  from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
8
  import os
9
  import torch
@@ -15,12 +14,11 @@ CHUNK_OVERLAP = 150
15
  EMBEDDING_MODEL_NAME = "intfloat/multilingual-e5-base"
16
  LLM_MODEL_NAME = "google/flan-t5-base"
17
 
18
- # MODEL_MAX_INPUT_TOKENS'a T5 için doğrudan gerek yok, tokenizer halleder.
19
  MAX_NEW_TOKENS = 256
20
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
21
 
22
  # --- 1. PDF'ten Vektör Veritabanı Oluştur ---
23
- # Bu fonksiyonda bir değişiklik yok, doğru çalışıyor.
24
  def create_vector_db_from_pdf(pdf_path):
25
  print(f"PDF okunuyor: {pdf_path}")
26
  text = ""
@@ -34,18 +32,15 @@ def create_vector_db_from_pdf(pdf_path):
34
  except Exception as e:
35
  print(f"PDF okunurken hata oluştu: {e}")
36
  return None
37
-
38
  if not text:
39
  print("PDF'ten metin çıkarılamadı.")
40
  return None
41
-
42
  print(f"Metin toplam {len(text)} karakter.")
43
  text_splitter = RecursiveCharacterTextSplitter(
44
  chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP, length_function=len
45
  )
46
  chunks = text_splitter.split_text(text)
47
  print(f"Metin {len(chunks)} parçaya ayrıldı.")
48
-
49
  print(f"Embedding modeli yükleniyor: {EMBEDDING_MODEL_NAME}")
50
  embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME, model_kwargs={'device': DEVICE})
51
  print("FAISS vektör veritabanı oluşturuluyor...")
@@ -53,7 +48,6 @@ def create_vector_db_from_pdf(pdf_path):
53
  print("Vektör veritabanı başarıyla oluşturuldu.")
54
  return db
55
 
56
-
57
  vector_db = None
58
  if os.path.exists(PDF_PATH):
59
  vector_db = create_vector_db_from_pdf(PDF_PATH)
@@ -61,96 +55,86 @@ else:
61
  print(f"Hata: {PDF_PATH} bulunamadı. Lütfen PDF dosyasını yükleyin.")
62
 
63
  # --- 2. LLM Yükleme ---
 
64
  text_generation_pipeline = None
65
  try:
66
  print(f"Model yükleniyor: {LLM_MODEL_NAME} -> Cihaz: {DEVICE}")
67
  tokenizer = AutoTokenizer.from_pretrained(LLM_MODEL_NAME)
68
-
69
- # DÜZELTME 1: Doğru model sınıfını kullan (AutoModelForSeq2SeqLM)
70
  model = AutoModelForSeq2SeqLM.from_pretrained(
71
- LLM_MODEL_NAME,
72
- torch_dtype=torch.float32,
73
- low_cpu_mem_usage=True
74
  )
75
-
76
  model.to(DEVICE)
77
-
78
- # DÜZELTME 2: 'device_id' değişkenini tanımla
79
  device_id = 0 if DEVICE == "cuda" else -1
80
-
81
  text_generation_pipeline = pipeline(
82
  "text2text-generation",
83
  model=model,
84
  tokenizer=tokenizer,
85
  device=device_id,
86
- max_length=MAX_NEW_TOKENS # T5'te max_new_tokens yerine max_length daha yaygındır
87
  )
88
  print("LLM pipeline başarıyla oluşturuldu.")
89
-
90
  except Exception as e:
91
  print(f"LLM yüklenirken hata oluştu: {e}")
92
  text_generation_pipeline = None
93
 
94
- # --- 3. Soru-Cevap Fonksiyonu ---
95
- def answer_question(question, chat_history):
96
- # Model veya veritabanı yüklenememişse hata mesajı göster
 
97
  if vector_db is None or text_generation_pipeline is None:
98
- err = "Model veya PDF yüklenemedi. Lütfen logları kontrol edin."
99
- chat_history.append((question, err))
100
- return chat_history
101
 
102
  print(f"Gelen soru: {question}")
103
- k = 3 # Daha iyi bağlam için 3 parça getirmek daha iyi olabilir
104
  retrieved_docs = vector_db.similarity_search(question, k=k)
105
 
106
  if not retrieved_docs:
107
- chat_history.append((question, "Bu soruyla ilgili belgede bilgi bulunamadı."))
108
- return chat_history
109
 
110
  context = "\n\n".join([doc.page_content for doc in retrieved_docs])
111
 
112
- # T5 modelleri için prompt formatı biraz daha basit olabilir
 
113
  prompt = (
114
- "Aşağıdaki bağlamı kullanarak soruyu yanıtla. Bağlamda cevap yoksa 'Bilgi bulunamadı' de.\n\n"
115
- f"Bağlam: {context}\n\n"
116
- f"Soru: {question}\n\n"
117
  "Cevap:"
118
  )
119
 
120
- print(f"Prompt token sayısı: {len(tokenizer.encode(prompt))}")
121
 
122
  try:
123
- # Pipeline'ı çalıştır
124
  outputs = text_generation_pipeline(prompt)
125
- # DÜZELTME 3: T5 çıktısı zaten temizdir, .replace'e gerek yok
126
  final_answer = outputs[0]["generated_text"].strip()
 
127
  except Exception as e:
128
  print("Cevap üretilirken hata:", e)
129
- final_answer = f"Cevap üretilemedi: {e}"
130
-
131
- chat_history.append((question, final_answer))
132
- return chat_history
133
 
134
- # --- 4. Gradio Arayüzü (Daha Akıcı Kullanım İçin İyileştirildi) ---
135
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
136
  gr.Markdown("# 📘 Fırat Üniversitesi Mevzuat Asistanı")
137
- # Chatbot'un label'ını ve yüksekliğini değiştirdim
138
- chatbot = gr.Chatbot(label="Sohbet Geçmişi", height=500)
139
  msg = gr.Textbox(label="Sorunuzu yazın:", placeholder="Örn: MADDE 1’i özetle")
140
 
141
- # Kullanıcının mesajını anında ekleyip sonra cevabı bekleyen fonksiyon
 
 
 
 
142
  def user(user_message, history):
143
  return gr.update(value="", interactive=False), history + [[user_message, None]]
144
 
145
- # Cevap geldikten sonra textbox'ı tekrar aktif eden fonksiyon
 
146
  def bot(history):
147
- # Son kullanıcı mesajını al
148
  question = history[-1][0]
149
- # Cevabı üret
150
- history = answer_question(question, history)
151
  return history, gr.update(interactive=True)
152
 
153
- # Buton ve Enter tuşu olayları
154
  msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
155
  bot, chatbot, [chatbot, msg]
156
  )
@@ -158,6 +142,5 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
158
  clear_btn = gr.Button("Sohbeti Temizle")
159
  clear_btn.click(lambda: (None, []), None, [msg, chatbot], queue=False)
160
 
161
-
162
  if __name__ == "__main__":
163
- demo.launch(debug=True) # debug=True logları daha detaylı görmeni sağlar
 
3
  from langchain.text_splitter import RecursiveCharacterTextSplitter
4
  from langchain.embeddings import HuggingFaceEmbeddings
5
  from langchain.vectorstores import FAISS
 
6
  from transformers import pipeline, AutoTokenizer, AutoModelForSeq2SeqLM
7
  import os
8
  import torch
 
14
  EMBEDDING_MODEL_NAME = "intfloat/multilingual-e5-base"
15
  LLM_MODEL_NAME = "google/flan-t5-base"
16
 
 
17
  MAX_NEW_TOKENS = 256
18
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
19
 
20
  # --- 1. PDF'ten Vektör Veritabanı Oluştur ---
21
+ # Bu fonksiyonda bir değişiklik yok.
22
  def create_vector_db_from_pdf(pdf_path):
23
  print(f"PDF okunuyor: {pdf_path}")
24
  text = ""
 
32
  except Exception as e:
33
  print(f"PDF okunurken hata oluştu: {e}")
34
  return None
 
35
  if not text:
36
  print("PDF'ten metin çıkarılamadı.")
37
  return None
 
38
  print(f"Metin toplam {len(text)} karakter.")
39
  text_splitter = RecursiveCharacterTextSplitter(
40
  chunk_size=CHUNK_SIZE, chunk_overlap=CHUNK_OVERLAP, length_function=len
41
  )
42
  chunks = text_splitter.split_text(text)
43
  print(f"Metin {len(chunks)} parçaya ayrıldı.")
 
44
  print(f"Embedding modeli yükleniyor: {EMBEDDING_MODEL_NAME}")
45
  embeddings = HuggingFaceEmbeddings(model_name=EMBEDDING_MODEL_NAME, model_kwargs={'device': DEVICE})
46
  print("FAISS vektör veritabanı oluşturuluyor...")
 
48
  print("Vektör veritabanı başarıyla oluşturuldu.")
49
  return db
50
 
 
51
  vector_db = None
52
  if os.path.exists(PDF_PATH):
53
  vector_db = create_vector_db_from_pdf(PDF_PATH)
 
55
  print(f"Hata: {PDF_PATH} bulunamadı. Lütfen PDF dosyasını yükleyin.")
56
 
57
  # --- 2. LLM Yükleme ---
58
+ # Bu bölümde bir değişiklik yok.
59
  text_generation_pipeline = None
60
  try:
61
  print(f"Model yükleniyor: {LLM_MODEL_NAME} -> Cihaz: {DEVICE}")
62
  tokenizer = AutoTokenizer.from_pretrained(LLM_MODEL_NAME)
 
 
63
  model = AutoModelForSeq2SeqLM.from_pretrained(
64
+ LLM_MODEL_NAME, torch_dtype=torch.float32, low_cpu_mem_usage=True
 
 
65
  )
 
66
  model.to(DEVICE)
 
 
67
  device_id = 0 if DEVICE == "cuda" else -1
 
68
  text_generation_pipeline = pipeline(
69
  "text2text-generation",
70
  model=model,
71
  tokenizer=tokenizer,
72
  device=device_id,
73
+ max_length=MAX_NEW_TOKENS
74
  )
75
  print("LLM pipeline başarıyla oluşturuldu.")
 
76
  except Exception as e:
77
  print(f"LLM yüklenirken hata oluştu: {e}")
78
  text_generation_pipeline = None
79
 
80
+ # --- 3. Soru-Cevap Fonksiyonu (DÜZELTİLDİ) ---
81
+ # DİKKAT: Bu fonksiyon artık sohbet geçmişini ('chat_history') almıyor.
82
+ # Sadece soruyu alıp, cevabı bir metin olarak döndürüyor.
83
+ def get_answer_from_llm(question):
84
  if vector_db is None or text_generation_pipeline is None:
85
+ return "Model veya PDF yüklenemedi. Lütfen logları kontrol edin."
 
 
86
 
87
  print(f"Gelen soru: {question}")
88
+ k = 3
89
  retrieved_docs = vector_db.similarity_search(question, k=k)
90
 
91
  if not retrieved_docs:
92
+ return "Bu soruyla ilgili belgede bilgi bulunamadı."
 
93
 
94
  context = "\n\n".join([doc.page_content for doc in retrieved_docs])
95
 
96
+ # DÜZELTME 2: Prompt'u daha basit ve net hale getirdik.
97
+ # Modelin kafasını karıştıracak "Soru:", "Bağlam:" gibi kelimeleri sadeleştirdik.
98
  prompt = (
99
+ "Verilen metne dayanarak aşağıdaki soruyu cevaplayın.\n\n"
100
+ f"Metin: \"{context}\"\n\n"
101
+ f"Soru: \"{question}\"\n\n"
102
  "Cevap:"
103
  )
104
 
105
+ print("LLM'e gönderilen prompt'un başlangıcı:", prompt[:500])
106
 
107
  try:
 
108
  outputs = text_generation_pipeline(prompt)
 
109
  final_answer = outputs[0]["generated_text"].strip()
110
+ return final_answer
111
  except Exception as e:
112
  print("Cevap üretilirken hata:", e)
113
+ return f"Cevap üretilemedi: {e}"
 
 
 
114
 
115
+ # --- 4. Gradio Arayüzü (DÜZELTİLDİ) ---
116
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
117
  gr.Markdown("# 📘 Fırat Üniversitesi Mevzuat Asistanı")
118
+ chatbot = gr.Chatbot(label="Sohbet Geçmişi", height=500)
 
119
  msg = gr.Textbox(label="Sorunuzu yazın:", placeholder="Örn: MADDE 1’i özetle")
120
 
121
+ # DÜZELTME 1: Sohbet mantığını tamamen düzelttik.
122
+ # Bu yeni yapı, Gradio ile chatbot yapmak için doğru yöntemdir.
123
+
124
+ # 1. Adım: Kullanıcı mesajını gönderir. Mesaj kutusu temizlenir ve pasif hale gelir.
125
+ # Sohbet geçmişine [kullanıcı_mesajı, None] eklenir.
126
  def user(user_message, history):
127
  return gr.update(value="", interactive=False), history + [[user_message, None]]
128
 
129
+ # 2. Adım: Model cevabı üretir ve sohbet geçmişindeki "None" olan yeri doldurur.
130
+ # Cevap gelince mesaj kutusu tekrar aktif hale gelir.
131
  def bot(history):
 
132
  question = history[-1][0]
133
+ answer = get_answer_from_llm(question)
134
+ history[-1][1] = answer
135
  return history, gr.update(interactive=True)
136
 
137
+ # Enter veya butona basıldığında user fonksiyonu, ardından bot fonksiyonu çalışır.
138
  msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
139
  bot, chatbot, [chatbot, msg]
140
  )
 
142
  clear_btn = gr.Button("Sohbeti Temizle")
143
  clear_btn.click(lambda: (None, []), None, [msg, chatbot], queue=False)
144
 
 
145
  if __name__ == "__main__":
146
+ demo.launch(debug=True)