Spaces:
Runtime error
Runtime error
File size: 9,249 Bytes
3ff18b8 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
import os
import shutil
import logging
import gradio as gr
from langchain_community.document_loaders import PyPDFLoader # تغییر به PyPDFLoader
from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.chat_models import ChatOpenAI
# تنظیمات لاگگیری
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# تنظیمات مسیرها
UPLOAD_FOLDER = "uploaded_files"
DATABASE_FILE = "/home/user/app/vector_database" # بدون پسوند .pkl
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
# بررسی و بارگذاری دیتابیس برداری
def load_database():
try:
if os.path.exists(DATABASE_FILE):
embeddings = OpenAIEmbeddings(openai_api_key=os.getenv("My_huggingface_key"))
vector_db = FAISS.load_local(DATABASE_FILE, embeddings)
logger.info(f"✅ دیتابیس بارگذاری شد: {DATABASE_FILE}")
return vector_db
else:
logger.warning(f"❌ دیتابیس در مسیر `{DATABASE_FILE}` وجود ندارد.")
return None
except Exception as e:
logger.error(f"❌ خطا در بارگذاری دیتابیس: {e}")
return None
def save_database(vector_db):
try:
vector_db.save_local(DATABASE_FILE)
logger.info(f"✅ دیتابیس ذخیره شد: {DATABASE_FILE}")
except Exception as e:
logger.error(f"❌ خطا در ذخیره دیتابیس: {e}")
raise e
global_vector_db = load_database()
# پردازش و ذخیرهسازی فایلهای PDF
def process_and_store_pdfs(file_paths):
texts = []
for file_path in file_paths:
try:
logger.info(f"در حال پردازش فایل: {file_path}")
if file_path.endswith(".pdf"):
# استفاده از PyPDFLoader به جای PDFMinerLoader
loader = PyPDFLoader(file_path)
documents = loader.load()
texts.extend(documents)
logger.info(f"✅ تعداد صفحات پردازش شده: {len(documents)}")
else:
logger.warning(f"فرمت فایل {file_path} پشتیبانی نمیشود.")
except Exception as e:
logger.error(f"خطا در پردازش فایل {file_path}: {e}")
try:
logger.info("در حال ایجاد embeddings و ذخیرهسازی در FAISS...")
openai_api_key = os.getenv("My_huggingface_key")
if not openai_api_key:
logger.error("❌ کلید API مقداردهی نشده است!")
raise ValueError("❌ کلید OpenAI API یافت نشد.")
embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key)
vector_db = FAISS.from_documents(texts, embeddings)
logger.info(f"✅ ذخیرهسازی در FAISS با موفقیت انجام شد. تعداد اسناد: {vector_db.index.ntotal}")
return vector_db
except Exception as e:
logger.error(f"خطا در ایجاد embeddings یا ذخیرهسازی در FAISS: {e}")
return None
# پاسخگویی بر اساس اسناد بارگذاریشده
def chat_with_doc(query):
try:
global global_vector_db
if not global_vector_db:
return "❌ لطفاً یک فایل مرتبط آپلود کنید."
if not query.strip():
return "❌ لطفاً سوال خود را وارد کنید."
# بازیابی اسناد مرتبط
retriever = global_vector_db.as_retriever(search_kwargs={"k": 5})
docs = retriever.get_relevant_documents(query)
# لاگگیری برای بررسی اسناد بازیابی شده
logger.info(f"تعداد اسناد بازیابی شده: {len(docs)}")
for doc in docs:
logger.info(f"سند بازیابی شده: {doc.page_content[:100]}...") # نمایش بخشی از متن سند
context = "\n\n".join([doc.page_content for doc in docs])
if not context:
return "هیچ اطلاعات مرتبطی یافت نشد."
# استفاده از مدل gpt-3.5-turbo به جای gpt-4 (در صورت عدم دسترسی به GPT-4)
llm = ChatOpenAI(model_name="gpt-3.5-turbo", openai_api_key=os.getenv("My_huggingface_key"))
# ساختار درخواست سادهتر
prompt = f"""سوال: {query}\n\nاطلاعات مرتبط:\n{context}\n\nلطفاً به سوال پاسخ دهید:"""
response = llm.predict(prompt)
final_response = f"پاسخ:\n{response}\n\nمنابع:\n"
for doc in docs:
final_response += f"- {doc.metadata.get('source', 'نامشخص')}, صفحه {doc.metadata.get('page', 'نامشخص')}\n"
return final_response
except Exception as e:
logger.error(f"خطا در پاسخگویی بر اساس سند: {e}")
return f"❌ خطایی رخ داده است: {e}"
# ذخیره فایل آپلود شده
def save_uploaded_file(file):
try:
file_name = os.path.basename(file)
file_path = os.path.join(UPLOAD_FOLDER, file_name)
shutil.copy(file, file_path)
global global_vector_db
global_vector_db = process_and_store_pdfs([file_path])
if global_vector_db:
save_database(global_vector_db)
return f"✅ فایل ذخیره شد: {file_path}"
except Exception as e:
return f"❌ خطا در ذخیره فایل: {e}"
# دباگ موقت
def debug_temp():
debug_results = []
# بررسی مقدار کلید API
openai_api_key = os.getenv("My_huggingface_key")
if openai_api_key:
debug_results.append(f"✅ کلید API مقداردهی شده: {openai_api_key[:5]}********")
else:
debug_results.append("❌ کلید API مقداردهی نشده است!")
# بررسی نسخه langchain_community
try:
import langchain_community
version = langchain_community.__version__
debug_results.append(f"✅ نسخه langchain_community: {version}")
except Exception as e:
debug_results.append(f"❌ خطا در بررسی نسخه langchain_community: {e}")
# بررسی فایلهای PDF در مسیر آپلود
try:
pdf_files = [f for f in os.listdir(UPLOAD_FOLDER) if f.endswith(".pdf")]
if pdf_files:
file_paths = [os.path.join(UPLOAD_FOLDER, f) for f in pdf_files]
debug_results.append(f"✅ فایلهای PDF در مسیر `{UPLOAD_FOLDER}`:")
# بررسی تعداد صفحات هر فایل
for file_path in file_paths:
try:
loader = PyPDFLoader(file_path) # استفاده از PyPDFLoader
documents = loader.load()
debug_results.append(f" - {os.path.basename(file_path)}: {len(documents)} صفحه")
except Exception as e:
debug_results.append(f"❌ خطا در بررسی صفحات {file_path}: {str(e)}")
else:
debug_results.append(f"❌ هیچ فایل PDF در مسیر `{UPLOAD_FOLDER}` وجود ندارد.")
except Exception as e:
debug_results.append(f"❌ خطا در بررسی پوشه `{UPLOAD_FOLDER}`: {e}")
# بررسی وضعیت دیتابیس
try:
if os.path.exists(DATABASE_FILE):
debug_results.append(f"✅ دیتابیس در مسیر `{DATABASE_FILE}` وجود دارد.")
# بررسی تعداد اسناد ذخیره شده
if global_vector_db:
debug_results.append(f" - تعداد اسناد در دیتابیس: {global_vector_db.index.ntotal}")
else:
debug_results.append("❌ دیتابیس در حافظه بارگذاری نشده است")
else:
debug_results.append(f"❌ دیتابیس در مسیر `{DATABASE_FILE}` وجود ندارد.")
except Exception as e:
debug_results.append(f"❌ خطا در بررسی دیتابیس: {e}")
return "\n".join(debug_results)
# رابط کاربری با Gradio
with gr.Blocks() as demo:
gr.Markdown("# هوش مصنوعی همراه کارشناسان توزیع برق ایران")
query = gr.Textbox(label="سوال خود را بپرسید", lines=2)
response = gr.Textbox(label="پاسخ", lines=10, interactive=False)
submit_btn = gr.Button("ارسال سوال")
file = gr.File(label="📎 آپلود فایل", file_types=[".pdf"])
upload_status = gr.Textbox(label="وضعیت آپلود", interactive=False)
upload_btn = gr.Button("ارسال فایل")
debug_btn = gr.Button("🔍 بررسی دباگ موقت")
debug_output = gr.Textbox(label="نتایج دباگ", lines=10, interactive=False)
upload_btn.click(save_uploaded_file, inputs=[file], outputs=[upload_status])
submit_btn.click(chat_with_doc, inputs=[query], outputs=[response])
debug_btn.click(debug_temp, outputs=debug_output)
demo.launch() |