Spaces:
Runtime error
Runtime error
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 | |
) | |