lordzukoiroh commited on
Commit
1ee3854
·
verified ·
1 Parent(s): 1882db4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +56 -91
app.py CHANGED
@@ -604,96 +604,64 @@ def generate_answer(question: str, chatbot_history: List[List[str]]) -> Tuple[st
604
 
605
  inputs = encoded_inputs["input_ids"]
606
  attention_mask = encoded_inputs["attention_mask"]
607
-
608
  outputs = model.generate(
609
  inputs,
610
  attention_mask=attention_mask,
611
- max_new_tokens=150,
612
  do_sample=True,
613
  top_p=0.9,
614
  temperature=gen_params["temperature"],
615
- repetition_penalty=1.4, # <<< BURAYI DEĞİŞTİRİN (veya gen_params'te ayarlayın)
616
- no_repeat_ngram_size=6, # <<< BURAYI DEĞİŞTİRİN (gerekirse)
617
  num_beams=1,
618
  pad_token_id=tokenizer.eos_token_id,
619
  eos_token_id=tokenizer.eos_token_id,
620
  )
621
 
622
- # --- BURADAN İTİBAREN YENİ TEMİZLİK KODUNU EKLEYİN/DEĞİŞTİRİN ---
623
- response = raw_response_with_prompt
624
-
625
- # 1. Prompt'un kendisini ve "Montag:" kısmını cevaptan ayırma
626
- match = re.search(r'(?i)Montag:\s*(.*)', response, re.DOTALL)
627
- if match:
628
- response = match.group(1).strip()
629
- else:
630
- prompt_decoded_for_comparison = tokenizer.decode(inputs[0], skip_special_tokens=True)
631
- if response.startswith(prompt_decoded_for_comparison):
632
- response = response[len(prompt_decoded_for_comparison):].strip()
633
- else:
634
- response = raw_response_with_prompt.strip()
635
-
636
- # 2. Persona talimatlarının cevapta tekrarlanmasını engelle
637
- persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
638
- for line in persona_lines:
639
- if response.lower().startswith(line.lower()):
640
- response = response[len(line):].strip()
641
-
642
- # 3. Fazladan "Kullanıcı: " veya "Montag: " tekrarlarını ve anlamsız tokenleri temizle
643
- response = response.replace("<unk>", "").strip()
644
- response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
645
- response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
646
- response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
647
- if "ETİKETLER:" in response:
648
- response = response.split("ETİKETLER:", 1)[0].strip()
649
- response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
650
-
651
- # --- Önceki Konuşma ve Tekrar Eden Kalıpları Temizleme ---
652
- # Bu kısmı kendi irrelevant_dialogue_patterns listenizle birleştirin/değiştirin
653
- irrelevant_dialogue_patterns = [
654
- # Modelin sürekli tekrarladığı "Nasılsın, iyi misin" ve devamı kalıbı
655
- r'Nasılsın,\s*iyi\s*misin\s*"\s*diye\s*sordu\s*Sesin\s*oldukça\s*tizdi,\s*hatta\s*neredeyse\s*boğuluyordu\s*Sesi\s*artık\s*iyice\s*boğuklaşmıştı\s*Gözlerindeki\s*donukluk\s*ve\s*akıl\s*almaz\s*kararlılık,\s*Montag\'ın\s*aklını\s*karıştırıyordu\s*Ne\s*söyleyeceğini\s*bilemiyormuş\s*gibiydi',
656
- r'Ne\s*düşünüyorsun\s*\,\s*sorusuna,\s*—\s*İyi\s*değil\s*miyim\s*\(Tıslayarak\)\s*Hayır,\s*kötü\s*değil\s*miyim\s*diyerek\s*cevabı\s*yapıştırdı',
657
- # ... diğer temizlik kalıplarınız ...
658
- ]
659
- for pattern in irrelevant_dialogue_patterns:
660
- response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
661
-
662
- response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşluğa indirge
663
 
664
- # --- BURADA KODUNUZUN DİĞER TEMİZLİK VE FİLTRELEME İŞLEMLERİ DEVAM EDER ---
665
- # Örneğin, aggressive_words ve generic_or_nonsense_phrases listelerinizin güncel halini ve puanlama sistemini buraya ekleyin
666
-
667
- # 2. Persona talimatlarının cevapta tekrarlanmasını engelle (güncel MONTAG_PERSONA'ya göre)
668
  persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
669
  for line in persona_lines:
670
- # Sadece cevabın başında tekrar eden persona talimatlarını temizle
671
  if response.lower().startswith(line.lower()):
672
  response = response[len(line):].strip()
673
-
674
  # 3. Fazladan "Kullanıcı: " veya "Montag: " tekrarlarını ve anlamsız tokenleri temizle
675
  response = response.replace("<unk>", "").strip()
676
  response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
677
-
678
- # Ek olarak, cevabın içinde hala kalmış olabilecek "Kullanıcı:" veya "Montag:" etiketlerini temizle
679
  response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
680
  response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
681
-
682
- # Cevabın içinde "ETİKETLER:" gibi ifadeler varsa temizle
683
  if "ETİKETLER:" in response:
684
  response = response.split("ETİKETLER:", 1)[0].strip()
685
-
686
- # Cevabın sonundaki "[...]" gibi ifadeleri temizle
687
  response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
688
 
689
- # --- DEĞİŞİKLİK NOTLARI: Alakasız diyalog kalıpları listesini gevşetildi ---
690
- # Sadece gerçekten modelin 'bug'larından kaynaklanan, sürekli tekrar eden veya anlamsız kalıpları bırakın.
691
- # Montag'ın doğal diyaloguna benzeyen veya kısa, net ifadeleri ÇIKARIN.
692
- irrelevant_dialogue_patterns = [
693
- r'ne zaman kendimi, her şeyi daha iyi anlayabileceğim, daha gerçekleştirebileceğim ve her şeyin üstesinden geleceğim bir yere koysam, daha sonra o yerin bana hiçbir şey öğretmediğini ve hiçbir şeyi öğretmediğini fark ediyorum. Ben kendimi daha fazla kandırmak istemiyorum. Ama ben, beni gerçekten etkileyen başka biri tarafından yönetilen bir.', # Tekrarlayan uzun ve alakasız metin
694
- r'her şeyi en ince ayrıntısına kadar anladım ama aynı zamanda da inanılmaz derecede utanıyorum. İnan bana, ben çok utangaçım.' # Tekrarlayan utangaçlık metni
695
- # Diğerlerini kaldırın veya çok daha spesifik hale getirin
 
696
  ]
 
 
 
697
  for pattern in irrelevant_dialogue_patterns:
698
  response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
699
 
@@ -701,11 +669,10 @@ response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşlu
701
  response = re.sub(r'\s+', ' ', response).strip()
702
 
703
  # Agresif veya hakaret içeren kelimeleri kontrol et
704
- aggressive_words = ["aptal", "salak", "gerizekalı", "saçma", "boş konuşma", "kaba", "agresif"]
705
- # "bilmiyorsun", "yanlışsın" gibi kelimeleri doğrudan agresif saymak yerine, bağlama göre değerlendirilebilir.
706
 
707
- # --- DEĞİŞİKLİK NOTLARI: Filtreleme Mantığına Puanlama Sistemi Eklendi ---
708
- # Her bir filtre kuralına bir "ceza puanı" veriyoruz. Toplam puan belirli bir eşiği geçerse reddedeceğiz.
709
  rejection_score = 0
710
  filter_reasons = []
711
 
@@ -713,53 +680,52 @@ response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşlu
713
  if len(response.split()) < 5:
714
  rejection_score += 2 # Hafif ceza
715
  filter_reasons.append(f"Çok kısa ({len(response.split())} kelime).")
716
-
717
  # 2. Sadece Harf İçermiyor Kontrolü (Bu genellikle iyi bir filtre)
718
  if not any(char.isalpha() for char in response):
719
  rejection_score += 10 # Ciddi ceza
720
  filter_reasons.append("Hiç harf içermiyor (sadece noktalama/sayı).")
721
-
722
  # 3. Genel/Anlamsız İfade Kontrolü (Listeyi yukarıda temizlemiştik)
723
  generic_or_nonsense_phrases = [
724
  "içir unidur", "aligutat fakdam", "tetal inlay", "pessotim elgun", # Modelin ürettiği anlamsız tokenler
725
  "nisman tarejoglu", "faksom", "achisteloy vandleradia", "vęudis",
726
  "eltareh", "eldlar", "fotjid", "zuhalibalyon",
727
  "etiketler:", # Meta bilgi sızıntısı
728
- # Sadece gerçekten anlamsız olanları bırakın
729
- ]
730
-
731
  triggered_generic_phrases = [phrase for phrase in generic_or_nonsense_phrases if phrase in response.lower()]
732
  if triggered_generic_phrases:
733
  rejection_score += len(triggered_generic_phrases) * 3 # Her anlamsız ifade için ceza
734
  filter_reasons.append(f"Anlamsız/istenmeyen ifade tespit edildi: {triggered_generic_phrases}.")
735
 
736
  # 4. Montag Karakteriyle Alaka Kontrolü (Daha esnek)
737
- montag_keywords = ["kitap", "yakmak", "itfaiyeci", "clarisse", "faber", "beatty", "bilgi", "sansür", "düşünce", "gerçek", "televizyon", "alev", "kül", "mildred", "yangın", "fireman"]
 
 
738
  has_montag_relevance = any(keyword in response.lower() for keyword in montag_keywords)
739
-
740
- # Eğer cevap uzunsa (anlamsız uzun metinleri yakalamak için) ve alakasızsa ceza ver
741
- if len(response.split()) > 15 and not has_montag_relevance:
742
- rejection_score += 4
743
  filter_reasons.append("Montag/bağlamsal anahtar kelime yok ve cevap uzun.")
744
-
745
  # 5. Agresif Kelime Kontrolü
746
  aggressive_words_found = [word for word in aggressive_words if word in response.lower()]
747
  if aggressive_words_found:
748
  rejection_score += 5 # Ciddi ceza
749
  filter_reasons.append(f"Agresif/istenmeyen kelime tespit edildi: {aggressive_words_found}.")
750
-
751
- # --- Karar verme eşiği ---
752
- # Toplam ceza puanı 5'i (veya belirleyeceğiniz başka bir eşiği) geçerse reddet
753
  if rejection_score >= 5: # Bu eşik değerini test ederek ayarlamanız gerekebilir.
754
  print(f"DEBUG: FİLTRELEME - Cevap YETERSİZ/ANLAMSIZ/ALAKASIZ. Toplam Puan: {rejection_score}")
755
  for reason in filter_reasons:
756
  print(f" - Sebep: {reason}")
757
  print(f"INFO: Üretilen cevap ('{response}') filtreleri geçemedi. Alternatif üretiliyor.")
758
  return generate_alternative_response(question), retrieved_docs # Alternatif ve dokümanları döndür
759
-
760
- # Cümle Bölme ve Limitleme Mantığı (Burada bir hata vardı, düzeltildi)
761
  sentences = []
762
- # Noktalama işaretlerine göre böl ve boşlukları temizle
763
  split_by_punctuation = re.split(r'[.!?]', response)
764
  for s in split_by_punctuation:
765
  s_stripped = s.strip()
@@ -767,22 +733,21 @@ response = re.sub(r'\s+', ' ', response).strip() # Fazla boşlukları tek boşlu
767
  sentences.append(s_stripped)
768
  if len(sentences) >= 6: # Maksimum 6 cümle
769
  break
770
-
771
  final_response_text = ' '.join(sentences).strip()
772
-
773
  # Eğer filtreleri geçerse ve boş değilse
774
- if not final_response_text: # Tüm filtrelerden geçse bile boş kalmışsa
775
  print("INFO: Filtrelerden geçen cevap boş kaldı. Alternatif üretiliyor.")
776
  return generate_alternative_response(question), retrieved_docs
777
-
778
  final_response = add_emojis(final_response_text)
779
  return final_response, retrieved_docs # Cevap ve alınan dokümanları döndür
780
-
781
  except Exception as e:
782
  print(f"Error generating answer: {e}")
783
- # Hata durumunda alternatif cevap döndürürken retrieved_docs'ı da döndürmek daha iyi olabilir
784
  return generate_alternative_response(question), []
785
 
 
786
  # === Gradio callback fonksiyonları ===
787
  def respond(msg: str, chatbot_history: List[List[str]], progress=gr.Progress()) -> Tuple[str, List[List[str]], str, str]:
788
  if not msg.strip():
 
604
 
605
  inputs = encoded_inputs["input_ids"]
606
  attention_mask = encoded_inputs["attention_mask"]
607
+
608
  outputs = model.generate(
609
  inputs,
610
  attention_mask=attention_mask,
611
+ max_new_tokens=150,
612
  do_sample=True,
613
  top_p=0.9,
614
  temperature=gen_params["temperature"],
615
+ repetition_penalty=gen_params["repetition_penalty"], # RL ajanından gelen değeri kullanmaya devam ediyoruz
616
+ no_repeat_ngram_size=6, # <<< no_repeat_ngram_size'ı 6'ya yükselttik
617
  num_beams=1,
618
  pad_token_id=tokenizer.eos_token_id,
619
  eos_token_id=tokenizer.eos_token_id,
620
  )
621
 
622
+ raw_response_with_prompt = tokenizer.decode(outputs[0], skip_special_tokens=True)
623
+
624
+ # --- Cevap Temizleme ve Post-Processing İyileştirmeleri ---
625
+ response = raw_response_with_prompt
626
+
627
+ # 1. Prompt'un kendisini ve "Montag:" kısmını cevaptan ayırma
628
+ match = re.search(r'(?i)Montag:\s*(.*)', response, re.DOTALL)
629
+ if match:
630
+ response = match.group(1).strip()
631
+ else:
632
+ prompt_decoded_for_comparison = tokenizer.decode(inputs[0], skip_special_tokens=True)
633
+ if response.startswith(prompt_decoded_for_comparison):
634
+ response = response[len(prompt_decoded_for_comparison):].strip()
635
+ else:
636
+ response = raw_response_with_prompt.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
 
638
+ # 2. Persona talimatlarının cevapta tekrarlanmasını engelle
 
 
 
639
  persona_lines = [line.strip() for line in MONTAG_PERSONA.split('\n') if line.strip()]
640
  for line in persona_lines:
 
641
  if response.lower().startswith(line.lower()):
642
  response = response[len(line):].strip()
643
+
644
  # 3. Fazladan "Kullanıcı: " veya "Montag: " tekrarlarını ve anlamsız tokenleri temizle
645
  response = response.replace("<unk>", "").strip()
646
  response = response.replace(" .", ".").replace(" ,", ",").replace(" ?", "?").replace(" !", "!")
 
 
647
  response = re.sub(r'Kullanıcı:\s*', '', response, flags=re.IGNORECASE)
648
  response = re.sub(r'Montag:\s*', '', response, flags=re.IGNORECASE)
 
 
649
  if "ETİKETLER:" in response:
650
  response = response.split("ETİKETLER:", 1)[0].strip()
 
 
651
  response = re.sub(r'\[\s*\.{3,}\s*\]', '', response).strip()
652
 
653
+ # --- Önceki Konuşma ve Tekrar Eden Kalıpları Temizleme ---
654
+ irrelevant_dialogue_patterns = [
655
+ # Modelin sürekli tekrarladığı "Nasılsın, iyi misin" ve devamı kalıbı
656
+ re.escape("Nasılsın, iyi misin \" diye sordu Sesin oldukça tizdi, hatta neredeyse boğuluyordu Sesi artık iyice boğuklaşmıştı Gözlerindeki donukluk ve akıl almaz kararlılık, Montag'ın aklını karıştırıyordu Ne söyleyeceğini bilemiyormuş gibiydi"),
657
+ re.escape("Ne düşünüyorsun ', sorusuna, İyi değil miyim (Tıslayarak) Hayır, kötü değil miyim diyerek cevabı yapıştırdı"),
658
+ # Modelin ürettiği uzun ve alakasız metinler
659
+ r'ne zaman kendimi, her şeyi daha iyi anlayabileceğim, daha gerçekleştirebileceğim ve her şeyin üstesinden geleceğim bir yere koysam, daha sonra o yerin bana hiçbir şey öğretmediğini ve hiçbir şeyi öğretmediğini fark ediyorum. Ben kendimi daha fazla kandırmak istemiyorum. Ama ben, beni gerçekten etkileyen başka biri tarafından yönetilen bir.',
660
+ r'her şeyi en ince ayrıntısına kadar anladım ama aynı zamanda da inanılmaz derecede utanıyorum. İnan bana, ben çok utangaçım.'
661
  ]
662
+ # Regex desenlerinde özel karakterleri kaçmak için re.escape() kullandık
663
+ # Aksi takdirde, metin içindeki tırnaklar, parantezler gibi karakterler regex hatasına yol açabilir.
664
+
665
  for pattern in irrelevant_dialogue_patterns:
666
  response = re.sub(pattern, '', response, flags=re.IGNORECASE).strip()
667
 
 
669
  response = re.sub(r'\s+', ' ', response).strip()
670
 
671
  # Agresif veya hakaret içeren kelimeleri kontrol et
672
+ # 'aptal' kelimesini listeden çıkardık, çünkü Montag'ın karakterine uygun olabilir.
673
+ aggressive_words = ["salak", "gerizekalı", "saçma", "boş konuşma", "kaba", "agresif"]
674
 
675
+ # --- Filtreleme Mantığına Puanlama Sistemi Eklendi ---
 
676
  rejection_score = 0
677
  filter_reasons = []
678
 
 
680
  if len(response.split()) < 5:
681
  rejection_score += 2 # Hafif ceza
682
  filter_reasons.append(f"Çok kısa ({len(response.split())} kelime).")
683
+
684
  # 2. Sadece Harf İçermiyor Kontrolü (Bu genellikle iyi bir filtre)
685
  if not any(char.isalpha() for char in response):
686
  rejection_score += 10 # Ciddi ceza
687
  filter_reasons.append("Hiç harf içermiyor (sadece noktalama/sayı).")
688
+
689
  # 3. Genel/Anlamsız İfade Kontrolü (Listeyi yukarıda temizlemiştik)
690
  generic_or_nonsense_phrases = [
691
  "içir unidur", "aligutat fakdam", "tetal inlay", "pessotim elgun", # Modelin ürettiği anlamsız tokenler
692
  "nisman tarejoglu", "faksom", "achisteloy vandleradia", "vęudis",
693
  "eltareh", "eldlar", "fotjid", "zuhalibalyon",
694
  "etiketler:", # Meta bilgi sızıntısı
695
+ # Sadece gerçekten anlamsız olanları bırakın
696
+ ]
 
697
  triggered_generic_phrases = [phrase for phrase in generic_or_nonsense_phrases if phrase in response.lower()]
698
  if triggered_generic_phrases:
699
  rejection_score += len(triggered_generic_phrases) * 3 # Her anlamsız ifade için ceza
700
  filter_reasons.append(f"Anlamsız/istenmeyen ifade tespit edildi: {triggered_generic_phrases}.")
701
 
702
  # 4. Montag Karakteriyle Alaka Kontrolü (Daha esnek)
703
+ # Montag'ın dünyasına ve genel temalara uygun yeni anahtar kelimeler eklendi
704
+ montag_keywords = ["kitap", "yakmak", "itfaiyeci", "clarisse", "faber", "beatty", "bilgi", "sansür", "düşünce", "gerçek", "televizyon", "alev", "kül", "mildred", "yangın", "fireman",
705
+ "düşünmek", "anlamak", "hissetmek", "arayış", "isyan", "toplum", "cehalet", "yalnızlık", "monotonluk", "gerçeklik"]
706
  has_montag_relevance = any(keyword in response.lower() for keyword in montag_keywords)
707
+
708
+ # Eğer cevap uzunsa (örneğin 20 kelimeden fazla) ve alakasızsa ceza ver
709
+ if len(response.split()) > 20 and not has_montag_relevance: # Buradaki kelime sayısını artırabilirsiniz
710
+ rejection_score += 1 # Cezayı düşürdük
711
  filter_reasons.append("Montag/bağlamsal anahtar kelime yok ve cevap uzun.")
712
+
713
  # 5. Agresif Kelime Kontrolü
714
  aggressive_words_found = [word for word in aggressive_words if word in response.lower()]
715
  if aggressive_words_found:
716
  rejection_score += 5 # Ciddi ceza
717
  filter_reasons.append(f"Agresif/istenmeyen kelime tespit edildi: {aggressive_words_found}.")
718
+
719
+ # --- Karar verme eşiği ---
 
720
  if rejection_score >= 5: # Bu eşik değerini test ederek ayarlamanız gerekebilir.
721
  print(f"DEBUG: FİLTRELEME - Cevap YETERSİZ/ANLAMSIZ/ALAKASIZ. Toplam Puan: {rejection_score}")
722
  for reason in filter_reasons:
723
  print(f" - Sebep: {reason}")
724
  print(f"INFO: Üretilen cevap ('{response}') filtreleri geçemedi. Alternatif üretiliyor.")
725
  return generate_alternative_response(question), retrieved_docs # Alternatif ve dokümanları döndür
726
+
727
+ # Cümle Bölme ve Limitleme Mantığı
728
  sentences = []
 
729
  split_by_punctuation = re.split(r'[.!?]', response)
730
  for s in split_by_punctuation:
731
  s_stripped = s.strip()
 
733
  sentences.append(s_stripped)
734
  if len(sentences) >= 6: # Maksimum 6 cümle
735
  break
 
736
  final_response_text = ' '.join(sentences).strip()
737
+
738
  # Eğer filtreleri geçerse ve boş değilse
739
+ if not final_response_text:
740
  print("INFO: Filtrelerden geçen cevap boş kaldı. Alternatif üretiliyor.")
741
  return generate_alternative_response(question), retrieved_docs
742
+
743
  final_response = add_emojis(final_response_text)
744
  return final_response, retrieved_docs # Cevap ve alınan dokümanları döndür
745
+
746
  except Exception as e:
747
  print(f"Error generating answer: {e}")
 
748
  return generate_alternative_response(question), []
749
 
750
+
751
  # === Gradio callback fonksiyonları ===
752
  def respond(msg: str, chatbot_history: List[List[str]], progress=gr.Progress()) -> Tuple[str, List[List[str]], str, str]:
753
  if not msg.strip():