Spaces:
Sleeping
Sleeping
| # این فایل server.py یا app.py در Hugging Face Space شما قرار می گیرد | |
| # این کد شامل: | |
| # - بارگذاری مدل Sentence Transformer پارسی 'PartAI/Tooka-SBERT' | |
| # - تعریف اپلیکیشن Flask | |
| # - اندپوینت /get_embedding برای دریافت سوال و ارسال بردار آن | |
| # - لاگ گیری برای عیب یابی در لاگ های Space و یک فایل جداگانه | |
| # - مدیریت خطاهای اولیه در بارگذاری مدل و پردازش درخواست ها | |
| # - رفع خطای 'SentenceTransformer' object has no attribute 'args' با اصلاح لاگ بارگذاری مدل | |
| from sentence_transformers import SentenceTransformer | |
| from flask import Flask, request, jsonify | |
| import numpy as np | |
| import logging | |
| import os | |
| # import torch # اگر از GPU استفاده می کنید و torch نصب کرده اید، این خط را فعال نگه دارید. | |
| # تنظیمات اولیه لاگینگ برای نمایش در لاگ های استاندارد Space | |
| # این لاگ ها معمولاً در تب "Container logs" دیده می شوند. | |
| logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | |
| # مسیر فایل لاگ جداگانه در فضای Hugging Face (برای عیب یابی بیشتر) | |
| # نکته: نوشتن در فایل در برخی محیط های Space ممکن است نیاز به تنظیمات مجوز داشته باشد. | |
| # خطای [Errno 13] Permission denied در لاگ قبلی به همین دلیل بود. | |
| log_file_path = "app_log.txt" | |
| # تابع برای افزودن پیام به فایل لاگ | |
| def log_message(message): | |
| try: | |
| # حالت 'a' برای اضافه کردن به انتهای فایل است. | |
| # مطمئن شوید که دایرکتوری برای فایل قابل نوشتن است. | |
| # اگر خطا مجوز می گیرید، می توانید این تابع را موقتا غیرفعال کنید یا مسیر دیگری را امتحان کنید. | |
| with open(log_file_path, "a", encoding="utf-8") as f: | |
| f.write(message + "\n") | |
| except Exception as e: | |
| # اگر نوشتن در فایل لاگ هم با خطا مواجه شد، در لاگ استاندارد Space بنویسید. | |
| logging.error(f"Error writing to log file {log_file_path}: {e}") | |
| # ****** نام مدل Sentence Transformer که می خواهیم در این سرور استفاده کنیم ****** | |
| # این مدل باید همان مدلی باشد که برای بردارسازی خاطرات در فایل های JSON استفاده کرده اید. | |
| model_name_to_load = 'PartAI/Tooka-SBERT' | |
| # *************************************************************************** | |
| # ****** بارگذاری مدل Sentence Transformer در هنگام راه اندازی سرور ****** | |
| logging.info(f"Attempting to load Sentence Transformer model: {model_name_to_load}...") # لاگ قبل از بارگذاری (در لاگ های استاندارد Space) | |
| log_message(f"Attempting to load Sentence Transformer model: {model_name_to_load}...") # لاگ قبل از بارگذاری (در فایل لاگ) | |
| try: | |
| # بارگذاری مدل. اگر GPU دارید و torch نصب شده، می توانید device='cuda' را اضافه کنید. | |
| # اگر خطایی در بارگذاری رخ دهد، Exception گرفته می شود. | |
| # model = SentenceTransformer(model_name_to_load, device='cuda' if torch.cuda.is_available() else 'cpu') | |
| model = SentenceTransformer(model_name_to_load) # بارگذاری با استفاده از CPU یا تنظیمات پیش فرض | |
| # ****** افزودن لاگ تأیید پس از بارگذاری موفق مدل ****** | |
| # این پیام ها در لاگ های Space به شما نشان می دهند که مدل با موفقیت بارگذاری شده و نام آن چیست. | |
| # ما نام مدلی که قصد بارگذاریش را داشتیم لاگ می کنیم تا از خطای Attribute Error جلوگیری شود. | |
| logging.info(f"SUCCESS: Model '{model_name_to_load}' loaded successfully.") # لاگ موفقیت (در لاگ های استاندارد Space) | |
| log_message(f"SUCCESS: Model '{model_name_to_load}' loaded successfully.") # لاگ موفقیت (در فایل لاگ) | |
| # ****************************************************** | |
| except Exception as e: | |
| # ****** مدیریت خطا در صورت عدم بارگذاری مدل ****** | |
| error_msg = f"ERROR: Failed to load model {model_name_to_load}: {e}" | |
| logging.error(error_msg) # لاگ خطا (در لاگ های استاندارد Space) | |
| log_message(error_msg) # لاگ خطا (در فایل لاگ) | |
| # در صورتی که بارگذاری مدل با خطا مواجه شد، متغیر model را None قرار می دهیم | |
| # تا در تابع get_embedding بتوانیم وضعیت خطا را چک کنیم. | |
| model = None | |
| # ************************************************* | |
| # تعریف اپلیکیشن Flask | |
| app = Flask(__name__) | |
| # تعریف اندپوینت اصلی برای تست سلامت سرور | |
| def index(): | |
| # چک کردن وضعیت مدل قبل از پاسخ به درخواست اصلی | |
| if model is None: | |
| # اگر مدل بارگذاری نشده، پیام خطا نمایش داده می شود. | |
| return "Sentiment Embedding Server is running, but model failed to load. Check Space logs for details.", 500 | |
| # اگر مدل با موفقیت بارگذاری شده، پیام موفقیت نمایش داده می شود. | |
| # از نام مدلی که در متغیر ذخیره کردیم استفاده می کنیم. | |
| return f"Sentiment Embedding Server is running successfully with model: {model_name_to_load}" | |
| # تعریف اندپوینت برای دریافت بردار (embedding) سوال | |
| def get_embedding(): | |
| # قبل از پردازش درخواست، مطمئن شوید مدل بارگذاری شده است. | |
| if model is None: | |
| error_msg = "Model is not loaded on the server due to a previous error. Check Space logs." | |
| # این خطا احتمالا قبلا در لاگ ها ثبت شده، اما برای اطمینان مجدد ثبت می کنیم. | |
| # logging.error(error_msg) # لاگ تکراری در صورتیکه بالا هم خطا داده | |
| log_message(f"Received request but model is not loaded: {error_msg}") # ثبت در فایل لاگ | |
| return jsonify({"error": error_msg}), 500 # ارسال پاسخ خطا با کد 500 | |
| try: | |
| # دریافت داده ها از درخواست POST (باید شامل فیلد 'query' باشد) | |
| data = request.get_json() | |
| query = data.get('query') | |
| # چک کردن اینکه فیلد query خالی نباشد | |
| if not query or not isinstance(query, str) or not query.strip(): | |
| log_message(f"Received invalid or empty query in /get_embedding: {data}") | |
| return jsonify({"error": "Invalid or empty query text provided"}), 400 # ارسال پاسخ خطا با کد 400 | |
| log_message(f"Received query in /get_embedding: '{query}'") | |
| logging.info(f"Processing query in /get_embedding: '{query[:50]}...'") # لاگ در کنسول Space برای درخواست های دریافتی | |
| embedding = model.encode(query, convert_to_numpy=True, pooling_mode='mean', normalize=True) | |
| # تبدیل بردار numpy به لیست Python برای ارسال در پاسخ JSON | |
| embedding_list = embedding.tolist() | |
| log_message(f"Successfully generated embedding for query in /get_embedding.") # لاگ موفقیت در فایل | |
| # logging.info(f"Embedding generated successfully for query.") # لاگ موفقیت در کنسول Space (اختیاری) | |
| # ارسال بردار به عنوان پاسخ JSON | |
| return jsonify({"embedding": embedding_list}), 200 # ارسال پاسخ موفقیت با کد 200 | |
| except Exception as e: | |
| error_message = f"An error occurred during embedding generation in /get_embedding: {e}" | |
| logging.error(error_message) # لاگ خطا (در لاگ های استاندارد Space) | |
| log_message(error_message) # لاگ خطا (در فایل لاگ) | |
| return jsonify({"error": error_message}), 500 # ارسال پاسخ خطا با کد 500 | |
| # خط زیر فقط در صورتی که فایل server.py مستقیماً اجرا شود، سرور Flask را اجرا می کند. | |
| # در Hugging Face Space، خود زیرساخت Space مسئول اجرای برنامه شماست و این بخش معمولاً غیرفعال است. | |
| # if __name__ == '__main__': | |
| # # Hugging Face Spaces از پورت 7860 استفاده می کند. | |
| # # debug=True برای محیط توسعه مفید است اما در محیط پروداکشن توصیه نمی شود. | |
| # app.run(host='0.0.0.0', port=7860, debug=False) |