montagicses / app.py
lordzukoiroh's picture
Update app.py
f5338c3 verified
import torch
import gradio as gr
import faiss
import numpy as np
from sentence_transformers import SentenceTransformer
from peft import PeftModel, PeftConfig
from transformers import AutoModelForCausalLM, AutoTokenizer
import json
import os
from typing import List, Tuple, Dict
# === CSS ve Emoji Fonksiyonu ===
current_css = """
#chatbot { height: 500px; overflow-y: auto; }
"""
def add_emojis(text: str) -> str:
emoji_mapping = {
"kitap": "📚", "kitaplar": "📚",
"bilgi": "🧠", "öğrenmek": "🧠",
"özgürlük": "🕊️", "özgür": "🕊️",
"düşünce": "💭", "düşünmek": "💭",
"ateş": "🔥", "yanmak": "🔥",
"yasak": "🚫", "yasaklamak": "🚫",
"tehlike": "⚠️", "tehlikeli": "⚠️",
"devlet": "🏛️", "hükümet": "🏛️",
"soru": "❓", "cevap": "✅",
"okumak": "👁️", "oku": "👁️",
"itfaiye": "🚒", "itfaiyeci": "🚒",
"değişim": "🔄", "değişmek": "🔄",
"isyan": "✊", "başkaldırı": "✊",
"uyuşturucu": "💊", "hap": "💊",
"televizyon": "📺", "tv": "📺",
"mutlu": "😊", "mutluluk": "😊",
"üzgün": "😞", "korku": "😨",
"merak": "🤔", "meraklı": "🤔"
}
found_emojis = []
words = text.split()
for word in words:
clean_word = word.lower().strip(".,!?")
if clean_word in emoji_mapping:
found_emojis.append(emoji_mapping[clean_word])
unique_emojis = list(set(found_emojis))
if unique_emojis:
return f"{text} {' '.join(unique_emojis)}"
return text
# === SABİTLER ===
BASE_MODEL = "ytu-ce-cosmos/turkish-gpt2-large-750m-instruct-v0.1"
PEFT_MODEL = "lordzukoiroh/montaggppt2lora"
BOOK_PATH = "fahrenheittt451.txt"
QA_PATH = "qa_dataset.jsonl"
EMBEDDER_NAME = "paraphrase-multilingual-MiniLM-L12-v2"
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
# Model ve tokenizer yükleme
print("Modeller yükleniyor...")
try:
# Temel modeli yükle
base_model = AutoModelForCausalLM.from_pretrained(
BASE_MODEL,
device_map="auto",
torch_dtype=torch.float16 if DEVICE == "cuda" else torch.float32
)
# LoRA adaptörünü yükle
model = PeftModel.from_pretrained(
base_model,
PEFT_MODEL,
device_map="auto"
)
print("LoRA adaptörü başarıyla yüklendi")
except Exception as e:
print(f"Hata: {e}")
raise RuntimeError("Model yüklenemedi, lütfen model yollarını kontrol edin")
# Tokenizer'ı yükle
tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
model.eval()
# Kitap verisini yükle
with open(BOOK_PATH, "r", encoding="utf-8") as f:
book_text = f.read()
paragraphs = [p.strip() for p in book_text.split("\n") if len(p.strip()) > 100]
# Embedder ve FAISS indeksi oluştur
embedder = SentenceTransformer(EMBEDDER_NAME)
paragraph_embeddings = embedder.encode(paragraphs, convert_to_numpy=True)
index = faiss.IndexFlatL2(paragraph_embeddings.shape[1])
index.add(paragraph_embeddings)
# === QA KAYIT ===
def save_feedback(question: str, answer: str, liked: bool, filepath: str = QA_PATH):
qa_pair = {"question": question, "answer": answer, "liked": liked}
with open(filepath, "a", encoding="utf-8") as f:
f.write(json.dumps(qa_pair, ensure_ascii=False) + "\n")
# === CEVAP ÜRET ===
def retrieve_context(question: str, top_k: int = 1) -> str:
try:
question_vec = embedder.encode([question])
_, indices = index.search(np.array(question_vec).astype("float32"), top_k)
return "\n".join([paragraphs[i] for i in indices[0]])
except Exception as e:
print(f"Error retrieving context: {e}")
return ""
def generate_answer(question: str, history: List[Dict] = []) -> str:
try:
context = retrieve_context(question)
prompt = (
f"Kullanıcı: {question}\n\n"
f"Bağlam:\n{context}\n\n"
"Montag, kendisi bir itfaiyeci olarak, her zaman bilgiye ve fikir özgürlüğüne değer verir. "
"Onun için kitaplar ve düşünceler, sistemin dayattığı kurallardan çok daha önemlidir. "
"Montag'ın perspektifinden cevap ver:"
)
inputs = tokenizer.encode(prompt, return_tensors="pt").to(DEVICE)
outputs = model.generate(
inputs,
max_new_tokens=200,
do_sample=True,
top_p=0.95,
temperature=0.85,
repetition_penalty=1.1,
pad_token_id=tokenizer.eos_token_id
)
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
if "Montag:" in response:
response = response.split("Montag:")[-1].strip()
else:
response = response.replace(prompt, "").strip()
return add_emojis(response)
except Exception as e:
print(f"Error generating answer: {e}")
return "Üzgünüm, bir hata oluştu. Lütfen tekrar deneyin."
# --- Yeni cevap üret ---
def regenerate_answer(chat_history: List[Dict]) -> Tuple[str, List[Dict]]:
if not chat_history:
return "", chat_history
last_interaction = None
for msg in reversed(chat_history):
if msg["role"] == "user":
last_interaction = msg["content"]
break
if last_interaction:
new_answer = generate_answer(last_interaction)
chat_history.append({"role": "assistant", "content": new_answer})
return "", chat_history
# --- Beğenilenleri kaydet ---
def save_liked(chat_history: List[Dict]) -> List[Dict]:
user_msg = None
assistant_msg = None
for msg in reversed(chat_history):
if msg["role"] == "user" and user_msg is None:
user_msg = msg["content"]
elif msg["role"] == "assistant" and assistant_msg is None:
assistant_msg = msg["content"]
if user_msg and assistant_msg:
break
if user_msg and assistant_msg:
save_feedback(user_msg, assistant_msg, liked=True)
return chat_history
# --- Kullanıcı mesajına yanıt ver ---
# === GRADIO ARAYÜZÜ ===
with gr.Blocks(css=current_css) as demo:
gr.Markdown("""
# 📚 Montag Chatbot (Fahrenheit 451)
*Ray Bradbury'nin Fahrenheit 451 romanındaki karakter Montag ile sohbet edin*
""")
chatbot = gr.Chatbot(
label="Sohbet Geçmişi",
height=500,
elem_id="chatbot",
type="messages"
)
msg = gr.Textbox(
label="Montag'a sormak istediğiniz soruyu yazın",
placeholder="Kitaplar neden yasaklandı?"
)
with gr.Row():
like_btn = gr.Button("👍 Beğendim")
dislike_btn = gr.Button("👎 Beğenmedim (Alternatif Cevap)")
clear_btn = gr.Button("🧹 Sohbeti Temizle")
# Olay bağlantıları
msg.submit(
respond,
inputs=[msg, chatbot],
outputs=[msg, chatbot]
)
like_btn.click(
save_liked,
inputs=[chatbot],
outputs=[chatbot]
)
import gradio as gr
from typing import Dict, List
def respond(message: str, chat_history: List[Dict[str, str]]) -> Dict[str, str]:
"""
Düzgün tip tanımlarıyla fonksiyon
Args:
message: str -> Kullanıcı mesajı
chat_history: List[Dict] -> Geçmiş sohbetler
Returns:
Dict[str, str] -> {'role': 'assistant', 'content': 'cevap'}
"""
return {"role": "assistant", "content": f"Merhaba! {message}"}
def regenerate_answer(chat_history: List[Dict[str, str]]) -> Tuple[str, List[Dict[str, str]]]:
# Yeniden cevap oluşturma mantığı
return "", chat_history + [{"role": "assistant", "content": "Yeni cevap"}]
with gr.Blocks() as demo:
chatbot = gr.Chatbot(
label="Sohbet",
type="messages",
value=[]
)
msg = gr.Textbox(label="Mesajınız")
with gr.Row():
dislike_btn = gr.Button("👎 Beğenmedim")
clear_btn = gr.Button("🧹 Temizle")
# Mesaj gönderme işlemi
msg.submit(
fn=respond,
inputs=[msg, chatbot],
outputs=[chatbot],
api_name="respond"
)
# Beğenmeme butonu işlemi
dislike_btn.click(
fn=regenerate_answer,
inputs=[chatbot],
outputs=[msg, chatbot],
api_name="regenerate"
)
# Temizle butonu işlemi
clear_btn.click(
fn=lambda: [],
inputs=None,
outputs=[chatbot],
api_name="clear_chat"
)
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
enable_queue=True,
show_api=True
)