DocUA commited on
Commit
c016742
·
1 Parent(s): 1ca7c3e

Enhance error handling and logging in initialization process

Browse files

- Add detailed logging and error tracking in ClassifierApp initialization
- Improve error reporting in main() function
- Add sync_system_info() method to update system information
- Refactor model creation and initialization with more robust error handling
- Update model_info.json with latest signature and cache statistics

Ніби робочий варіант, але потрібно розібратися із створенням і оновленням сигнатур різними моделями!

Files changed (3) hide show
  1. app.py +32 -24
  2. classifier_app.py +113 -29
  3. model_info.json +6 -6
app.py CHANGED
@@ -2,9 +2,13 @@ import gradio as gr
2
  import torch
3
  import os
4
  from classifier_app import ClassifierApp, config
 
5
 
6
  def create_interface(app: ClassifierApp) -> gr.Blocks:
7
  """Створення веб-інтерфейсу"""
 
 
 
8
  with gr.Blocks() as demo:
9
  gr.Markdown("# SDC Classifier")
10
 
@@ -113,19 +117,6 @@ def create_interface(app: ClassifierApp) -> gr.Blocks:
113
  save_btn = gr.Button("Зберегти розмічені дані")
114
  save_out = gr.Label()
115
 
116
- gr.Markdown("""
117
- ### Інструкція:
118
- 1. У вкладці "Налаштування моделі" можна:
119
- - Вибрати тип моделі (OpenAI або Local)
120
- - Налаштувати параметри вибраної моделі
121
- - Завантажити новий JSON файл з класами
122
- - Примусово перебудувати signatures
123
- 2. Після зміни налаштувань натисніть "Оновити signatures"
124
- 3. Використовуйте повзунок "Поріг впевненості" для фільтрації результатів
125
- 4. На вкладці "Пакетна обробка" можна аналізувати багато повідомлень
126
- 5. Результати можна зберегти в CSV файл
127
- """)
128
-
129
  # Підключення обробників подій
130
  model_type.change(
131
  fn=app.update_model_inputs,
@@ -185,20 +176,37 @@ def create_interface(app: ClassifierApp) -> gr.Blocks:
185
 
186
  return demo
187
 
 
188
  def main():
189
- app = ClassifierApp()
190
- init_result, classifier = app.initialize_environment()
191
-
192
- if classifier is None or init_result["status"] != "success":
193
- print("Не вдалося ініціалізувати середовище")
194
- return
 
 
 
 
 
 
 
 
 
 
195
 
196
- print(f"Статус ініціалізації: {init_result['status']}")
197
- print(f"Кількість завантажених класів: {len(init_result['classes_info']['classes_list'])}")
198
- print(f"Сигнатури: {'Завантажено' if os.path.exists(config.DEFAULT_SIGNATURES_FILE) else 'Створюються'}")
199
 
200
- demo = create_interface(app)
201
- demo.launch(server_name="0.0.0.0", server_port=7860, share=True)
 
 
 
 
 
 
202
 
203
  if __name__ == "__main__":
204
  main()
 
2
  import torch
3
  import os
4
  from classifier_app import ClassifierApp, config
5
+ from typing import Dict
6
 
7
  def create_interface(app: ClassifierApp) -> gr.Blocks:
8
  """Створення веб-інтерфейсу"""
9
+ # Синхронізуємо інформацію перед створенням інтерфейсу
10
+ initial_info = app.sync_system_info()
11
+
12
  with gr.Blocks() as demo:
13
  gr.Markdown("# SDC Classifier")
14
 
 
117
  save_btn = gr.Button("Зберегти розмічені дані")
118
  save_out = gr.Label()
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  # Підключення обробників подій
121
  model_type.change(
122
  fn=app.update_model_inputs,
 
176
 
177
  return demo
178
 
179
+
180
  def main():
181
+ try:
182
+ print("\nЗапуск програми...")
183
+ app = ClassifierApp()
184
+
185
+ print("\nПочаток ініціалізації середовища...")
186
+ init_result, classifier = app.initialize_environment()
187
+
188
+ print("\nРезультат ініціалізації:")
189
+ print(f"Статус: {init_result['status']}")
190
+
191
+ if init_result.get('errors'):
192
+ print("Помилки:", init_result['errors'])
193
+
194
+ if classifier is None or init_result["status"] != "success":
195
+ print("\nНе вдалося ініціалізувати середовище")
196
+ return
197
 
198
+ print(f"\nІнформація про систему:")
199
+ print(f"Кількість завантажених класів: {len(init_result['classes_info']['classes_list'])}")
200
+ print(f"Сигнатури: {'Завантажено' if os.path.exists(config.DEFAULT_SIGNATURES_FILE) else 'Створюються'}")
201
 
202
+ demo = create_interface(app)
203
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=True)
204
+
205
+ except Exception as e:
206
+ print(f"\nКритична помилка в main(): {str(e)}")
207
+ import traceback
208
+ print("\nДетальний traceback:")
209
+ print(traceback.format_exc())
210
 
211
  if __name__ == "__main__":
212
  main()
classifier_app.py CHANGED
@@ -32,53 +32,98 @@ class ClassifierApp:
32
 
33
  def initialize_environment(self) -> Tuple[Dict, Optional[SDCClassifier]]:
34
  """Ініціалізація середовища при першому запуску"""
35
-
36
- if not os.path.exists(config.DEFAULT_CLASSES_FILE):
37
- self.initial_info["errors"].append(
38
- f"ПОМИЛКА: Файл {config.DEFAULT_CLASSES_FILE} не знайдено!"
39
- )
40
- self.initial_info["status"] = "error"
41
- return self.initial_info, None
42
-
43
  try:
44
- self.classifier = SDCClassifier()
45
- classes = self.classifier.load_classes(config.DEFAULT_CLASSES_FILE)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
- self.initial_info["classes_info"] = {
48
- "total_classes": len(classes),
49
- "classes_list": list(classes.keys()),
50
- "hints_per_class": {cls: len(hints) for cls, hints in classes.items()}
51
- }
 
 
 
 
 
 
 
 
52
 
 
53
  if os.path.exists(config.DEFAULT_SIGNATURES_FILE):
54
- self.classifier.load_signatures(config.DEFAULT_SIGNATURES_FILE)
55
- self.initial_info["status"] = "success"
 
 
 
 
 
 
 
56
  else:
 
57
  self.initial_info["status"] = "creating_signatures"
58
- result = self.classifier.initialize_signatures(
59
- force_rebuild=True,
60
- signatures_file=config.DEFAULT_SIGNATURES_FILE
61
- )
62
-
63
- if isinstance(result, str) and "error" in result.lower():
64
- self.initial_info["errors"].append(result)
 
 
 
 
 
 
65
  self.initial_info["status"] = "error"
66
  return self.initial_info, None
67
 
 
68
  try:
69
  self.classifier.save_model_info(config.MODEL_INFO_FILE)
70
  with open(config.MODEL_INFO_FILE, "r") as f:
71
  self.initial_info["model_info"] = json.load(f)
72
 
73
  self.initial_info["status"] = "success"
 
74
  return self.initial_info, self.classifier
75
-
76
- except (FileNotFoundError, json.JSONDecodeError) as e:
 
77
  self.initial_info["errors"].append(f"Помилка при читанні model_info: {str(e)}")
78
  self.initial_info["status"] = "error"
79
  return self.initial_info, None
80
-
81
  except Exception as e:
 
82
  self.initial_info["errors"].append(f"ПОМИЛКА при ініціалізації: {str(e)}")
83
  self.initial_info["status"] = "error"
84
  return self.initial_info, None
@@ -91,10 +136,16 @@ class ClassifierApp:
91
  device: Optional[str] = None
92
  ) -> SDCClassifier:
93
  """Створення класифікатора з відповідними параметрами"""
 
 
94
  if model_type == "OpenAI":
95
- return SDCClassifier(openai_model=openai_model)
 
96
  else:
97
- return SDCClassifier(local_model=local_model, device=device)
 
 
 
98
 
99
  def update_model_inputs(
100
  self,
@@ -261,6 +312,39 @@ class ClassifierApp:
261
  except Exception as e:
262
  return f"Помилка: {str(e)}"
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  @staticmethod
265
  def update_system_markdown(info: Dict) -> str:
266
  """Оновлення Markdown з системною інформацією"""
 
32
 
33
  def initialize_environment(self) -> Tuple[Dict, Optional[SDCClassifier]]:
34
  """Ініціалізація середовища при першому запуску"""
 
 
 
 
 
 
 
 
35
  try:
36
+ # Перевіряємо наявність необхідних файлів
37
+ if not os.path.exists(config.DEFAULT_CLASSES_FILE):
38
+ self.initial_info["errors"].append(
39
+ f"ПОМИЛКА: Файл {config.DEFAULT_CLASSES_FILE} не знайдено!"
40
+ )
41
+ self.initial_info["status"] = "error"
42
+ print(f"\nПомилка: Файл {config.DEFAULT_CLASSES_FILE} не знайдено!")
43
+ return self.initial_info, None
44
+
45
+ print("\nСтворення класифікатора...")
46
+ try:
47
+ # Визначаємо яка модель використовувалась для сигнатур
48
+ signatures_model = None
49
+ if os.path.exists(config.MODEL_INFO_FILE):
50
+ with open(config.MODEL_INFO_FILE, 'r') as f:
51
+ model_info = json.load(f)
52
+ if not model_info.get('using_local', True):
53
+ signatures_model = "text-embedding-3-small" # Модель, яка використовувалась
54
+
55
+ # Створюємо класифікатор з тією ж моделлю
56
+ self.classifier = SDCClassifier(openai_api_key=os.getenv("OPENAI_API_KEY"))
57
+ print(f"Використовується модель: {signatures_model or 'local'}")
58
+
59
+ except Exception as e:
60
+ print(f"\nПомилка при створенні класифікатора: {str(e)}")
61
+ self.initial_info["errors"].append(f"Помилка при створенні класифікатора: {str(e)}")
62
+ self.initial_info["status"] = "error"
63
+ return self.initial_info, None
64
 
65
+ print("\nЗавантаження класів...")
66
+ try:
67
+ classes = self.classifier.load_classes(config.DEFAULT_CLASSES_FILE)
68
+ self.initial_info["classes_info"] = {
69
+ "total_classes": len(classes),
70
+ "classes_list": list(classes.keys()),
71
+ "hints_per_class": {cls: len(hints) for cls, hints in classes.items()}
72
+ }
73
+ except Exception as e:
74
+ print(f"\nПомилка при завантаженні класів: {str(e)}")
75
+ self.initial_info["errors"].append(f"Помилка при завантаженні класів: {str(e)}")
76
+ self.initial_info["status"] = "error"
77
+ return self.initial_info, None
78
 
79
+ print("\nПеревірка та завантаження сигнатур...")
80
  if os.path.exists(config.DEFAULT_SIGNATURES_FILE):
81
+ try:
82
+ self.classifier.load_signatures(config.DEFAULT_SIGNATURES_FILE)
83
+ self.initial_info["status"] = "success"
84
+ print("Сигнатури завантажено успішно")
85
+ except Exception as e:
86
+ print(f"\nПомилка при завантаженні сигнатур: {str(e)}")
87
+ self.initial_info["errors"].append(f"Помилка при завантаженні сигнатур: {str(e)}")
88
+ self.initial_info["status"] = "error"
89
+ return self.initial_info, None
90
  else:
91
+ print("\nСтворення нових сигнатур...")
92
  self.initial_info["status"] = "creating_signatures"
93
+ try:
94
+ result = self.classifier.initialize_signatures(
95
+ force_rebuild=True,
96
+ signatures_file=config.DEFAULT_SIGNATURES_FILE
97
+ )
98
+ if isinstance(result, str) and "error" in result.lower():
99
+ print(f"\nПомилка при створенні сигнатур: {result}")
100
+ self.initial_info["errors"].append(result)
101
+ self.initial_info["status"] = "error"
102
+ return self.initial_info, None
103
+ except Exception as e:
104
+ print(f"\nПомилка при створенні сигнатур: {str(e)}")
105
+ self.initial_info["errors"].append(f"Помилка при створенні сигнатур: {str(e)}")
106
  self.initial_info["status"] = "error"
107
  return self.initial_info, None
108
 
109
+ print("\nЗбереження інформації про модель...")
110
  try:
111
  self.classifier.save_model_info(config.MODEL_INFO_FILE)
112
  with open(config.MODEL_INFO_FILE, "r") as f:
113
  self.initial_info["model_info"] = json.load(f)
114
 
115
  self.initial_info["status"] = "success"
116
+ print("\nІніціалізація завершена успішно")
117
  return self.initial_info, self.classifier
118
+
119
+ except Exception as e:
120
+ print(f"\nПомилка при збереженні інформації про модель: {str(e)}")
121
  self.initial_info["errors"].append(f"Помилка при читанні model_info: {str(e)}")
122
  self.initial_info["status"] = "error"
123
  return self.initial_info, None
124
+
125
  except Exception as e:
126
+ print(f"\nЗагальна помилка при ініціалізації: {str(e)}")
127
  self.initial_info["errors"].append(f"ПОМИЛКА при ініціалізації: {str(e)}")
128
  self.initial_info["status"] = "error"
129
  return self.initial_info, None
 
136
  device: Optional[str] = None
137
  ) -> SDCClassifier:
138
  """Створення класифікатора з відповідними параметрами"""
139
+ classifier = SDCClassifier()
140
+
141
  if model_type == "OpenAI":
142
+ if hasattr(classifier, 'set_openai_model'):
143
+ classifier.set_openai_model(openai_model)
144
  else:
145
+ if hasattr(classifier, 'set_local_model'):
146
+ classifier.set_local_model(local_model, device)
147
+
148
+ return classifier
149
 
150
  def update_model_inputs(
151
  self,
 
312
  except Exception as e:
313
  return f"Помилка: {str(e)}"
314
 
315
+ def sync_system_info(self) -> Dict:
316
+ """Синхронізація системної інформації"""
317
+ try:
318
+ if self.classifier is None:
319
+ raise ValueError("Класифікатор не ініціалізовано")
320
+
321
+ self.classifier.save_model_info(config.MODEL_INFO_FILE)
322
+ with open(config.MODEL_INFO_FILE, "r") as f:
323
+ model_info = json.load(f)
324
+
325
+ self.initial_info = {
326
+ "status": "success",
327
+ "model_info": model_info,
328
+ "classes_info": {
329
+ "total_classes": len(self.classifier.classes_json),
330
+ "classes_list": list(self.classifier.classes_json.keys()),
331
+ "hints_per_class": {
332
+ cls: len(hints)
333
+ for cls, hints in self.classifier.classes_json.items()
334
+ }
335
+ },
336
+ "errors": []
337
+ }
338
+ return self.initial_info
339
+ except Exception as e:
340
+ self.initial_info = {
341
+ "status": "error",
342
+ "model_info": {},
343
+ "classes_info": {},
344
+ "errors": [str(e)]
345
+ }
346
+ return self.initial_info
347
+
348
  @staticmethod
349
  def update_system_markdown(info: Dict) -> str:
350
  """Оновлення Markdown з системною інформацією"""
model_info.json CHANGED
@@ -1,13 +1,13 @@
1
  {
2
  "using_local": true,
3
  "classes_count": 131,
4
- "signatures_count": 15,
5
  "cache_stats": {
6
- "total_entries": 6765,
7
- "cache_size_mb": 44.05,
8
- "hits": 0,
9
- "misses": 0,
10
- "hit_rate_percent": 0
11
  },
12
  "local_model": {
13
  "model_name": "cambridgeltl/SapBERT-from-PubMedBERT-fulltext",
 
1
  {
2
  "using_local": true,
3
  "classes_count": 131,
4
+ "signatures_count": 131,
5
  "cache_stats": {
6
+ "total_entries": 8746,
7
+ "cache_size_mb": 51.91,
8
+ "hits": 122,
9
+ "misses": 1450,
10
+ "hit_rate_percent": 7.76
11
  },
12
  "local_model": {
13
  "model_name": "cambridgeltl/SapBERT-from-PubMedBERT-fulltext",