Spaces:
Running
Running
altawil
commited on
Update model_definition.py
Browse files- model_definition.py +144 -173
model_definition.py
CHANGED
@@ -33,6 +33,8 @@ try:
|
|
33 |
from timm.layers import trunc_normal_
|
34 |
except ImportError:
|
35 |
from timm.models.layers import trunc_normal_
|
|
|
|
|
36 |
|
37 |
# مكتبات إضافية
|
38 |
import os
|
@@ -48,11 +50,6 @@ import numpy as np
|
|
48 |
import cv2
|
49 |
|
50 |
# مكتبات اختيارية (يمكن تعطيلها إذا لم تكن متوفرة)
|
51 |
-
try:
|
52 |
-
import wandb
|
53 |
-
WANDB_AVAILABLE = True
|
54 |
-
except ImportError:
|
55 |
-
WANDB_AVAILABLE = False
|
56 |
|
57 |
try:
|
58 |
from tqdm import tqdm
|
@@ -1194,11 +1191,103 @@ class InterfuserModel(nn.Module):
|
|
1194 |
|
1195 |
|
1196 |
|
1197 |
-
def get_master_config(model_path="model/best_model.pth"):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1198 |
"""
|
1199 |
-
[النسخة
|
1200 |
-
|
|
|
1201 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1202 |
model_params = {
|
1203 |
"img_size": 224, "embed_dim": 256, "enc_depth": 6, "dec_depth": 6,
|
1204 |
"rgb_backbone_name": 'r50', "lidar_backbone_name": 'r18',
|
@@ -1213,11 +1302,13 @@ def get_master_config(model_path="model/best_model.pth"):
|
|
1213 |
"use_view_embed": False, "use_mmad_pretrain": None,
|
1214 |
}
|
1215 |
|
|
|
1216 |
grid_conf = {
|
1217 |
'h': 20, 'w': 20, 'x_res': 1.0, 'y_res': 1.0,
|
1218 |
'y_min': 0.0, 'y_max': 20.0, 'x_min': -10.0, 'x_max': 10.0,
|
1219 |
}
|
1220 |
|
|
|
1221 |
controller_params = {
|
1222 |
'turn_KP': 0.75, 'turn_KI': 0.05, 'turn_KD': 0.25, 'turn_n': 20,
|
1223 |
'speed_KP': 0.55, 'speed_KI': 0.05, 'speed_KD': 0.15, 'speed_n': 20,
|
@@ -1232,192 +1323,72 @@ def get_master_config(model_path="model/best_model.pth"):
|
|
1232 |
'follow_grace_period': 20
|
1233 |
}
|
1234 |
|
|
|
1235 |
master_config = {
|
|
|
1236 |
'model_params': model_params,
|
1237 |
'grid_conf': grid_conf,
|
1238 |
'controller_params': controller_params,
|
1239 |
-
'
|
1240 |
-
|
|
|
1241 |
}
|
1242 |
|
1243 |
return master_config
|
1244 |
|
1245 |
|
|
|
|
|
|
|
|
|
1246 |
def load_and_prepare_model(device: torch.device) -> InterfuserModel:
|
1247 |
"""
|
1248 |
-
[النسخة
|
1249 |
-
تستخدم
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1250 |
"""
|
1251 |
try:
|
1252 |
-
logging.info("
|
1253 |
-
|
|
|
1254 |
config = get_master_config()
|
1255 |
|
1256 |
-
# 2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1257 |
model = InterfuserModel(**config['model_params']).to(device)
|
1258 |
-
logging.info(f"Model instantiated on device: {device}")
|
1259 |
|
1260 |
-
#
|
1261 |
-
|
1262 |
-
model.load_pretrained(
|
|
|
|
|
1263 |
|
1264 |
-
#
|
1265 |
model.eval()
|
1266 |
-
logging.info("✅ Model prepared and set to evaluation mode.")
|
1267 |
|
1268 |
return model
|
1269 |
|
1270 |
except Exception as e:
|
1271 |
-
|
|
|
1272 |
raise
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
# def load_and_prepare_model(config, device):
|
1277 |
-
# """
|
1278 |
-
# يقوم بإنشاء النموذج وتحميل الأوزان المدربة مسبقًا.
|
1279 |
-
|
1280 |
-
# Args:
|
1281 |
-
# config (dict): إعدادات النموذج والمسارات
|
1282 |
-
# device (torch.device): الجهاز المستهدف (CPU/GPU)
|
1283 |
-
|
1284 |
-
# Returns:
|
1285 |
-
# InterfuserModel: النموذج المحمل
|
1286 |
-
# """
|
1287 |
-
# try:
|
1288 |
-
# # إنشاء النموذج
|
1289 |
-
# model = InterfuserModel(**config.get('model_params', {})).to(device)
|
1290 |
-
# logging.info(f"تم إنشاء النموذج على الجهاز: {device}")
|
1291 |
-
|
1292 |
-
# # تحميل الأوزان إذا كان المسار محدد
|
1293 |
-
# checkpoint_path = config.get('paths', {}).get('pretrained_weights')
|
1294 |
-
# if checkpoint_path:
|
1295 |
-
# success = model.load_pretrained(checkpoint_path, strict=False)
|
1296 |
-
# if success:
|
1297 |
-
# logging.info("✅ تم تحميل النموذج والأوزان بنجاح")
|
1298 |
-
# else:
|
1299 |
-
# logging.warning("⚠️ تم إنشاء النموذج بأوزان عشوائية")
|
1300 |
-
# else:
|
1301 |
-
# logging.info("لم يتم تحديد مسار الأوزان، سيتم استخدام أوزان عشوائية")
|
1302 |
-
|
1303 |
-
# # وضع النموذج في وضع التقييم
|
1304 |
-
# model.eval()
|
1305 |
-
|
1306 |
-
# return model
|
1307 |
-
|
1308 |
-
# except Exception as e:
|
1309 |
-
# logging.error(f"خطأ في إنشاء النموذج: {str(e)}")
|
1310 |
-
# raise
|
1311 |
-
|
1312 |
-
|
1313 |
-
# def create_model_config(model_path="model/best_model.pth", **model_params):
|
1314 |
-
# """
|
1315 |
-
# إنشاء إعدادات النموذج باستخدام الإعدادات الصحيحة من التدريب
|
1316 |
-
|
1317 |
-
# Args:
|
1318 |
-
# model_path (str): مسار ملف الأوزان
|
1319 |
-
# **model_params: معاملات النموذج الإضافية
|
1320 |
-
|
1321 |
-
# Returns:
|
1322 |
-
# dict: إعدادات النموذج
|
1323 |
-
# """
|
1324 |
-
# # الإعدادات الصحيحة من كونفيج التدريب الأصلي
|
1325 |
-
# training_config_params = {
|
1326 |
-
# "img_size": 224,
|
1327 |
-
# "embed_dim": 256, # مهم: هذه القيمة من التدريب الأصلي
|
1328 |
-
# "enc_depth": 6,
|
1329 |
-
# "dec_depth": 6,
|
1330 |
-
# "rgb_backbone_name": 'r50',
|
1331 |
-
# "lidar_backbone_name": 'r18',
|
1332 |
-
# "waypoints_pred_head": 'gru',
|
1333 |
-
# "use_different_backbone": True,
|
1334 |
-
# "with_lidar": False,
|
1335 |
-
# "with_right_left_sensors": False,
|
1336 |
-
# "with_center_sensor": False,
|
1337 |
-
|
1338 |
-
# # إعدادات إضافية من الكونفيج الأصلي
|
1339 |
-
# "multi_view_img_size": 112,
|
1340 |
-
# "patch_size": 8,
|
1341 |
-
# "in_chans": 3,
|
1342 |
-
# "dim_feedforward": 2048,
|
1343 |
-
# "normalize_before": False,
|
1344 |
-
# "num_heads": 8,
|
1345 |
-
# "dropout": 0.1,
|
1346 |
-
# "end2end": False,
|
1347 |
-
# "direct_concat": False,
|
1348 |
-
# "separate_view_attention": False,
|
1349 |
-
# "separate_all_attention": False,
|
1350 |
-
# "freeze_num": -1,
|
1351 |
-
# "traffic_pred_head_type": "det",
|
1352 |
-
# "reverse_pos": True,
|
1353 |
-
# "use_view_embed": False,
|
1354 |
-
# "use_mmad_pretrain": None,
|
1355 |
-
# }
|
1356 |
-
|
1357 |
-
# # دمج المعاملات المخصصة مع الإعدادات من التدريب
|
1358 |
-
# training_config_params.update(model_params)
|
1359 |
-
|
1360 |
-
# config = {
|
1361 |
-
# 'model_params': training_config_params,
|
1362 |
-
# 'paths': {
|
1363 |
-
# 'pretrained_weights': model_path
|
1364 |
-
# },
|
1365 |
-
|
1366 |
-
# # إضافة إعدادات الشبكة من التدريب
|
1367 |
-
# 'grid_conf': {
|
1368 |
-
# 'h': 20, 'w': 20,
|
1369 |
-
# 'x_res': 1.0, 'y_res': 1.0,
|
1370 |
-
# 'y_min': 0.0, 'y_max': 20.0,
|
1371 |
-
# 'x_min': -10.0, 'x_max': 10.0,
|
1372 |
-
# },
|
1373 |
-
|
1374 |
-
# # معلومات إضافية عن التدريب
|
1375 |
-
# 'training_info': {
|
1376 |
-
# 'original_project': 'Interfuser_Finetuning',
|
1377 |
-
# 'run_name': 'Finetune_Focus_on_Detection_v5',
|
1378 |
-
# 'focus': 'traffic_detection_and_iou',
|
1379 |
-
# 'backbone': 'ResNet50 + ResNet18',
|
1380 |
-
# 'trained_on': 'PDM_Lite_Carla'
|
1381 |
-
# }
|
1382 |
-
# }
|
1383 |
-
|
1384 |
-
# return config
|
1385 |
-
|
1386 |
-
|
1387 |
-
# def get_training_config():
|
1388 |
-
# """
|
1389 |
-
# إرجاع إعدادات التدريب الأصلية للمرجع
|
1390 |
-
# هذه الإعدادات توضح كيف تم تدريب النموذج
|
1391 |
-
# """
|
1392 |
-
# return {
|
1393 |
-
# 'project_info': {
|
1394 |
-
# 'project': 'Interfuser_Finetuning',
|
1395 |
-
# 'entity': None,
|
1396 |
-
# 'run_name': 'Finetune_Focus_on_Detection_v5'
|
1397 |
-
# },
|
1398 |
-
# 'training': {
|
1399 |
-
# 'epochs': 50,
|
1400 |
-
# 'batch_size': 8,
|
1401 |
-
# 'num_workers': 2,
|
1402 |
-
# 'learning_rate': 1e-4, # معدل تعلم منخفض للـ Fine-tuning
|
1403 |
-
# 'weight_decay': 1e-2,
|
1404 |
-
# 'patience': 15,
|
1405 |
-
# 'clip_grad_norm': 1.0,
|
1406 |
-
# },
|
1407 |
-
# 'loss_weights': {
|
1408 |
-
# 'iou': 2.0, # أولوية قصوى لدقة الصناديق
|
1409 |
-
# 'traffic_map': 25.0, # تركيز عالي على اكتشاف الكائنات
|
1410 |
-
# 'waypoints': 1.0, # مرجع أساسي
|
1411 |
-
# 'junction': 0.25, # مهام متقنة بالفعل
|
1412 |
-
# 'traffic_light': 0.5,
|
1413 |
-
# 'stop_sign': 0.25,
|
1414 |
-
# },
|
1415 |
-
# 'data_split': {
|
1416 |
-
# 'strategy': 'interleaved',
|
1417 |
-
# 'segment_length': 100,
|
1418 |
-
# 'validation_frequency': 10,
|
1419 |
-
# },
|
1420 |
-
# 'transforms': {
|
1421 |
-
# 'use_data_augmentation': False, # معطل للتركيز على البيانات الأصلية
|
1422 |
-
# }
|
1423 |
-
# }
|
|
|
33 |
from timm.layers import trunc_normal_
|
34 |
except ImportError:
|
35 |
from timm.models.layers import trunc_normal_
|
36 |
+
from huggingface_hub import hf_hub_download, HfApi
|
37 |
+
from huggingface_hub.utils import HfFolder
|
38 |
|
39 |
# مكتبات إضافية
|
40 |
import os
|
|
|
50 |
import cv2
|
51 |
|
52 |
# مكتبات اختيارية (يمكن تعطيلها إذا لم تكن متوفرة)
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
try:
|
55 |
from tqdm import tqdm
|
|
|
1191 |
|
1192 |
|
1193 |
|
1194 |
+
# def get_master_config(model_path="model/best_model.pth"):
|
1195 |
+
# """
|
1196 |
+
# [النسخة الكاملة والنهائية]
|
1197 |
+
# ينشئ ويدمج كل الإعدادات المطلوبة للتطبيق (النموذج، المتتبع، المتحكم).
|
1198 |
+
# """
|
1199 |
+
# model_params = {
|
1200 |
+
# "img_size": 224, "embed_dim": 256, "enc_depth": 6, "dec_depth": 6,
|
1201 |
+
# "rgb_backbone_name": 'r50', "lidar_backbone_name": 'r18',
|
1202 |
+
# "waypoints_pred_head": 'gru', "use_different_backbone": True,
|
1203 |
+
# "with_lidar": False, "with_right_left_sensors": False,
|
1204 |
+
# "with_center_sensor": False, "multi_view_img_size": 112,
|
1205 |
+
# "patch_size": 8, "in_chans": 3, "dim_feedforward": 2048,
|
1206 |
+
# "normalize_before": False, "num_heads": 8, "dropout": 0.1,
|
1207 |
+
# "end2end": False, "direct_concat": False, "separate_view_attention": False,
|
1208 |
+
# "separate_all_attention": False, "freeze_num": -1,
|
1209 |
+
# "traffic_pred_head_type": "det", "reverse_pos": True,
|
1210 |
+
# "use_view_embed": False, "use_mmad_pretrain": None,
|
1211 |
+
# }
|
1212 |
+
|
1213 |
+
# grid_conf = {
|
1214 |
+
# 'h': 20, 'w': 20, 'x_res': 1.0, 'y_res': 1.0,
|
1215 |
+
# 'y_min': 0.0, 'y_max': 20.0, 'x_min': -10.0, 'x_max': 10.0,
|
1216 |
+
# }
|
1217 |
+
|
1218 |
+
# controller_params = {
|
1219 |
+
# 'turn_KP': 0.75, 'turn_KI': 0.05, 'turn_KD': 0.25, 'turn_n': 20,
|
1220 |
+
# 'speed_KP': 0.55, 'speed_KI': 0.05, 'speed_KD': 0.15, 'speed_n': 20,
|
1221 |
+
# 'max_speed': 8.0, 'max_throttle': 0.75, 'min_speed': 0.1,
|
1222 |
+
# 'brake_sensitivity': 0.3, 'light_threshold': 0.5, 'stop_threshold': 0.6,
|
1223 |
+
# 'stop_sign_duration': 20, 'max_stop_time': 250,
|
1224 |
+
# 'forced_move_duration': 20, 'forced_throttle': 0.5,
|
1225 |
+
# 'max_red_light_time': 150, 'red_light_block_duration': 80,
|
1226 |
+
# 'accel_rate': 0.1, 'decel_rate': 0.2, 'critical_distance': 4.0,
|
1227 |
+
# 'follow_distance': 10.0, 'speed_match_factor': 0.9,
|
1228 |
+
# 'tracker_match_thresh': 2.5, 'tracker_prune_age': 5,
|
1229 |
+
# 'follow_grace_period': 20
|
1230 |
+
# }
|
1231 |
+
|
1232 |
+
# master_config = {
|
1233 |
+
# 'model_params': model_params,
|
1234 |
+
# 'grid_conf': grid_conf,
|
1235 |
+
# 'controller_params': controller_params,
|
1236 |
+
# 'paths': {'pretrained_weights': model_path},
|
1237 |
+
# 'simulation': {'frequency': 10.0}
|
1238 |
+
# }
|
1239 |
+
|
1240 |
+
# return master_config
|
1241 |
+
|
1242 |
+
|
1243 |
+
# def load_and_prepare_model(device: torch.device) -> InterfuserModel:
|
1244 |
+
# """
|
1245 |
+
# [النسخة النهائية الصحيحة - تستقبل مدخلاً واحدًا فقط]
|
1246 |
+
# تستخدم دالة الإعدادات الرئيسية لإنشاء وتحميل النموذج.
|
1247 |
+
# """
|
1248 |
+
# try:
|
1249 |
+
# logging.info("Attempting to load model using master config...")
|
1250 |
+
# # 1. الحصول على كل الإعدادات من المصدر الوحيد للحقيقة
|
1251 |
+
# config = get_master_config()
|
1252 |
+
|
1253 |
+
# # 2. إنشاء النموذج باستخدام إعدادات النموذج فقط
|
1254 |
+
# model = InterfuserModel(**config['model_params']).to(device)
|
1255 |
+
# logging.info(f"Model instantiated on device: {device}")
|
1256 |
+
|
1257 |
+
# # 3. تحميل الأوزان باستخدام الدالة الداخلية للنموذج
|
1258 |
+
# checkpoint_path = config['paths']['pretrained_weights']
|
1259 |
+
# model.load_pretrained(checkpoint_path, strict=False)
|
1260 |
+
|
1261 |
+
# # 4. وضع النموذج في وضع التقييم
|
1262 |
+
# model.eval()
|
1263 |
+
# logging.info("✅ Model prepared and set to evaluation mode.")
|
1264 |
+
|
1265 |
+
# return model
|
1266 |
+
|
1267 |
+
# except Exception as e:
|
1268 |
+
# logging.error(f"❌ CRITICAL ERROR in load_and_prepare_model: {e}", exc_info=True)
|
1269 |
+
# raise
|
1270 |
+
|
1271 |
+
|
1272 |
+
|
1273 |
+
# ==============================================================================
|
1274 |
+
# الدالة الأولى: get_master_config
|
1275 |
+
# ==============================================================================
|
1276 |
+
|
1277 |
+
def get_master_config():
|
1278 |
"""
|
1279 |
+
[النسخة الاحترافية]
|
1280 |
+
يعيد قاموسًا شاملاً يحتوي على جميع إعدادات التطبيق الثابتة.
|
1281 |
+
هذه الدالة هي المصدر الوحيد للحقيقة للإعدادات.
|
1282 |
"""
|
1283 |
+
|
1284 |
+
# --- القسم 1: معلومات مستودع النموذج على Hugging Face Hub ---
|
1285 |
+
huggingface_repo = {
|
1286 |
+
'repo_id': "Adam-IT/Interfuser-Baseer-v1", # استبدله باسم مستودع النموذج الخاص بك
|
1287 |
+
'filename': "best_model.pth" # اسم ملف الأوزان داخل المستودع
|
1288 |
+
}
|
1289 |
+
|
1290 |
+
# --- القسم 2: إعدادات بنية نموذج Interfuser ---
|
1291 |
model_params = {
|
1292 |
"img_size": 224, "embed_dim": 256, "enc_depth": 6, "dec_depth": 6,
|
1293 |
"rgb_backbone_name": 'r50', "lidar_backbone_name": 'r18',
|
|
|
1302 |
"use_view_embed": False, "use_mmad_pretrain": None,
|
1303 |
}
|
1304 |
|
1305 |
+
# --- القسم 3: إعدادات الشبكة ومنظور عين الطائر (BEV) ---
|
1306 |
grid_conf = {
|
1307 |
'h': 20, 'w': 20, 'x_res': 1.0, 'y_res': 1.0,
|
1308 |
'y_min': 0.0, 'y_max': 20.0, 'x_min': -10.0, 'x_max': 10.0,
|
1309 |
}
|
1310 |
|
1311 |
+
# --- القسم 4: إعدادات وحدة التحكم (Controller) والمتتبع (Tracker) ---
|
1312 |
controller_params = {
|
1313 |
'turn_KP': 0.75, 'turn_KI': 0.05, 'turn_KD': 0.25, 'turn_n': 20,
|
1314 |
'speed_KP': 0.55, 'speed_KI': 0.05, 'speed_KD': 0.15, 'speed_n': 20,
|
|
|
1323 |
'follow_grace_period': 20
|
1324 |
}
|
1325 |
|
1326 |
+
# --- القسم 5: تجميع كل شيء في قاموس رئيسي واحد ---
|
1327 |
master_config = {
|
1328 |
+
'huggingface_repo': huggingface_repo,
|
1329 |
'model_params': model_params,
|
1330 |
'grid_conf': grid_conf,
|
1331 |
'controller_params': controller_params,
|
1332 |
+
'simulation': {
|
1333 |
+
'frequency': 10.0
|
1334 |
+
}
|
1335 |
}
|
1336 |
|
1337 |
return master_config
|
1338 |
|
1339 |
|
1340 |
+
# ==============================================================================
|
1341 |
+
# الدالة الثانية: load_and_prepare_model
|
1342 |
+
# ==============================================================================
|
1343 |
+
|
1344 |
def load_and_prepare_model(device: torch.device) -> InterfuserModel:
|
1345 |
"""
|
1346 |
+
[النسخة الاحترافية]
|
1347 |
+
تستخدم الإعدادات الرئيسية من `get_master_config` لإنشاء وتحميل النموذج.
|
1348 |
+
تقوم بتحويل معرّف النموذج من Hugging Face Hub إلى مسار ملف حقيقي.
|
1349 |
+
|
1350 |
+
Args:
|
1351 |
+
device (torch.device): الجهاز المستهدف (CPU/GPU)
|
1352 |
+
|
1353 |
+
Returns:
|
1354 |
+
Interfuser: النموذج المحمل وجاهز للاستدلال.
|
1355 |
"""
|
1356 |
try:
|
1357 |
+
logging.info("Initializing model loading process...")
|
1358 |
+
|
1359 |
+
# 1. الحصول على جميع الإعدادات من المصدر الوحيد للحقيقة
|
1360 |
config = get_master_config()
|
1361 |
|
1362 |
+
# 2. تحميل ملف الأوزان من Hugging Face Hub
|
1363 |
+
repo_info = config['huggingface_repo']
|
1364 |
+
logging.info(f"Downloading model weights from repo: '{repo_info['repo_id']}'")
|
1365 |
+
|
1366 |
+
# استخدام token إذا كان المستودع خاصًا
|
1367 |
+
# token = HfFolder.get_token() # أو يمكن تمريره مباشرة
|
1368 |
+
actual_model_path = hf_hub_download(
|
1369 |
+
repo_id=repo_info['repo_id'],
|
1370 |
+
filename=repo_info['filename'],
|
1371 |
+
# token=token, # قم بإلغاء التعليق إذا كان المستودع خاصًا
|
1372 |
+
)
|
1373 |
+
logging.info(f"Model weights are available at local path: {actual_model_path}")
|
1374 |
+
|
1375 |
+
# 3. إنشاء نسخة من النموذج باستخدام الإعدادات الصحيحة
|
1376 |
+
logging.info("Instantiating model with specified parameters...")
|
1377 |
model = InterfuserModel(**config['model_params']).to(device)
|
|
|
1378 |
|
1379 |
+
# 4. تحميل الأوزان التي تم تنزيلها إلى النموذج
|
1380 |
+
# نستخدم الدالة المساعدة الموجودة داخل كلاس النموذج نفسه
|
1381 |
+
success = model.load_pretrained(actual_model_path, strict=False)
|
1382 |
+
if not success:
|
1383 |
+
logging.warning("⚠️ Model weights were not loaded successfully. The model will use random weights.")
|
1384 |
|
1385 |
+
# 5. وضع النموذج في وضع التقييم (خطوة حاسمة)
|
1386 |
model.eval()
|
1387 |
+
logging.info("✅ Model prepared and set to evaluation mode. Ready for inference.")
|
1388 |
|
1389 |
return model
|
1390 |
|
1391 |
except Exception as e:
|
1392 |
+
# تسجيل الخطأ بالتفصيل ثم إطلاقه مرة أخرى ليتم التعامل معه في مستوى أعلى
|
1393 |
+
logging.error(f"❌ CRITICAL ERROR during model initialization: {e}", exc_info=True)
|
1394 |
raise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|