tiyam-chatbot / app.py
diginoron's picture
Update app.py
d2af11c verified
raw
history blame
3.61 kB
# app.py
import os
import json
import torch
import gradio as gr
from huggingface_hub import login
from pinecone import Pinecone
from sentence_transformers import SentenceTransformer
from transformers import AutoTokenizer, AutoModelForCausalLM
# 🔐 خواندن سکرت‌ها
PINECONE_API_KEY = os.environ.get("PINECONE_API_KEY")
PINECONE_INDEX_NAME = os.environ.get("INDEX_NAME", "tiyam-chat")
HF_TOKEN = os.environ.get("HF_TOKEN")
if not HF_TOKEN:
raise ValueError("❌ سکرت HF_TOKEN یافت نشد. لطفاً آن را در Settings > Secrets ثبت کنید.")
# 🔐 ورود به Hugging Face برای استفاده از مدل خصوصی
login(token=HF_TOKEN)
# 🔹 بارگذاری مدل embedding
embedding_model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
# 🔹 بارگذاری داده‌های اولیه (اختیاری)
with open("tiyam_qa_data.json", "r", encoding="utf-8") as f:
data = json.load(f)
# 🔹 اتصال به Pinecone
pc = Pinecone(api_key=PINECONE_API_KEY)
index = pc.Index(PINECONE_INDEX_NAME)
# 🔹 بارگذاری مدل بازنویسی GEMMA
tokenizer = AutoTokenizer.from_pretrained("google/gemma-2b-it", token=HF_TOKEN)
model = AutoModelForCausalLM.from_pretrained("google/gemma-2b-it", token=HF_TOKEN)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = model.to(device)
# 🔍 بازیابی پاسخ اولیه از Pinecone
def retrieve_answer(query, threshold=0.65, top_k=3):
query_embedding = embedding_model.encode([query])[0]
result = index.query(vector=query_embedding.tolist(), top_k=top_k, include_metadata=True)
if result['matches'] and result['matches'][0]['score'] > threshold:
metadata = result['matches'][0]['metadata']
return metadata.get('answer', 'پاسخ یافت نشد')
else:
return "متأسفم، پاسخ دقیقی برای این سوال نداریم. لطفاً با ما تماس بگیرید."
# 🧠 بازنویسی پاسخ با تعیین هوشمند تعداد توکن‌ها
def rewrite_answer(question, retrieved_answer):
prompt = f"""سؤال: {question}
پاسخ اولیه: {retrieved_answer}
پاسخ نهایی را به زبان طبیعی، حرفه‌ای و دوستانه بازنویسی کن:"""
# 🔍 تعیین طول هوشمندانه توکن خروجی
base_len = len(retrieved_answer)
if base_len < 60:
max_tokens = 64
elif base_len < 150:
max_tokens = 96
else:
max_tokens = 128
inputs = tokenizer(prompt, return_tensors="pt").to(device)
outputs = model.generate(
**inputs,
max_new_tokens=max_tokens,
temperature=0.7,
do_sample=True,
top_p=0.9
)
final_answer = tokenizer.decode(outputs[0], skip_special_tokens=True)
return final_answer.replace(prompt, "").strip()
# 🧪 تابع نهایی چت
def chat_interface(question):
print("📥 سوال دریافت شد:", question)
raw_answer = retrieve_answer(question)
print("📤 پاسخ خام از Pinecone:", raw_answer)
final_answer = rewrite_answer(question, raw_answer)
print("✅ پاسخ نهایی بازنویسی‌شده:", final_answer)
return final_answer
# 🌐 رابط کاربری Gradio
demo = gr.Interface(
fn=chat_interface,
inputs="text",
outputs="text",
title="💬 چت‌بات هوشمند تیام",
description="سؤالات خود درباره خدمات بازاریابی دیجیتال تیام را بپرسید."
)
demo.launch()