Spaces:
Running
Running
Download ocr-training/scripts/monitor_v25_kernel.py from phucsd/cham-ocr-studio: direct link, hf CLI and curl.
- Browser
- Download file 5.52 kB
-
https://huggingface.co/spaces/phucsd/cham-ocr-studio/resolve/main/ocr-training/scripts/monitor_v25_kernel.py
- Command line
-
hf download hf://spaces/phucsd/cham-ocr-studio/ocr-training/scripts/monitor_v25_kernel.py
-
curl -L -o monitor_v25_kernel.py https://huggingface.co/spaces/phucsd/cham-ocr-studio/resolve/main/ocr-training/scripts/monitor_v25_kernel.py
5.52 kB
| #!/usr/bin/env python3 | |
| # -*- coding: utf-8 -*- | |
| """ | |
| Dedicated Real-Time Monitor for Cham-OCR V25 Kaggle Kernels. | |
| Streams live training logs (Epoch, Step, Loss, Acc, ETA) directly from Kaggle stream API. | |
| """ | |
| import os | |
| import sys | |
| import time | |
| import json | |
| import socket | |
| if sys.stdout and hasattr(sys.stdout, 'reconfigure'): | |
| sys.stdout.reconfigure(encoding='utf-8') | |
| socket.setdefaulttimeout(30) | |
| SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| sys.path.insert(0, SCRIPT_DIR) | |
| from kaggle_auth import init_kaggle_auth | |
| init_kaggle_auth() | |
| from kaggle_ops import get_authenticated_api | |
| from kagglesdk.kernels.types.kernels_api_service import ApiGetKernelSessionLogsStreamRequest | |
| def fetch_stream_lines(api, user_name, kernel_slug, timeout_sec=6): | |
| clean_lines = [] | |
| try: | |
| with api.build_kaggle_client() as kaggle: | |
| client = kaggle.kernels.kernels_api_client | |
| req = ApiGetKernelSessionLogsStreamRequest() | |
| req.user_name = user_name | |
| req.kernel_slug = kernel_slug | |
| res = client.get_kernel_session_logs_stream(req) | |
| t0 = time.time() | |
| for line in res.iter_lines(decode_unicode=True): | |
| if line and line.startswith('data: '): | |
| try: | |
| item = json.loads(line[6:]) | |
| text = item.get('data', '') | |
| for d in text.splitlines(): | |
| if d.strip(): | |
| clean_lines.append(d.strip()) | |
| except Exception: | |
| pass | |
| if time.time() - t0 > timeout_sec: | |
| break | |
| except Exception as e: | |
| pass | |
| return clean_lines | |
| def monitor(kernel_id, poll_seconds=60): | |
| api = get_authenticated_api() | |
| if not api: | |
| print("❌ Lỗi: Không thể xác thực Kaggle API.") | |
| return 1 | |
| parts = kernel_id.split('/') | |
| user_name = parts[0] | |
| kernel_slug = parts[1] if len(parts) > 1 else parts[0] | |
| print("=" * 75) | |
| print(f"🛰️ BẮT ĐẦU GIÁM SÁT REAL-TIME STREAMING KERNEL: {kernel_id}") | |
| print(f" • Tần suất kiểm tra : {poll_seconds} giây / lần") | |
| print(f" • Thời gian bắt đầu : {time.strftime('%Y-%m-%d %H:%M:%S')}") | |
| print("=" * 75) | |
| sys.stdout.flush() | |
| start_t = time.time() | |
| last_status = None | |
| last_count = 0 | |
| poll_count = 0 | |
| while True: | |
| poll_count += 1 | |
| elapsed_min = int((time.time() - start_t) / 60) | |
| try: | |
| st_obj = api.kernels_status(kernel_id) | |
| status = getattr(st_obj, 'status', None) | |
| if hasattr(status, 'name'): | |
| status_str = status.name.lower() | |
| elif isinstance(status, str): | |
| status_str = status.lower() | |
| else: | |
| status_str = str(status).lower() | |
| failure_msg = getattr(st_obj, 'failure_message', None) or getattr(st_obj, 'failureMessage', None) | |
| # Lấy các dòng log trực tiếp từ Live Stream API | |
| lines = fetch_stream_lines(api, user_name, kernel_slug, timeout_sec=6) | |
| current_count = len(lines) | |
| if current_count > last_count: | |
| new_lines = lines[last_count:] | |
| # Lọc các dòng có ý nghĩa huấn luyện quan trọng | |
| key_lines = [l for l in new_lines if any(k in l for k in ['ppocr INFO:', 'epoch:', 'cur metric', 'best metric', 'assert', 'Error', 'STAGE EXIT', '🎉'])] | |
| if not key_lines: | |
| key_lines = new_lines[-10:] # in 10 dòng mới nhất nếu không có dòng quan trọng | |
| print(f"\n📡 [Sau {elapsed_min}m | Status: {status_str.upper()} | Tổng {current_count:,} dòng]:") | |
| for l in key_lines[-15:]: | |
| print(f" | {l}") | |
| last_count = current_count | |
| sys.stdout.flush() | |
| elif status_str != last_status or poll_count % 5 == 0: | |
| print(f"⏱️ [Sau {elapsed_min}m] Trạng thái: {status_str.upper()} (Đã nhận {current_count:,} dòng log)...") | |
| sys.stdout.flush() | |
| last_status = status_str | |
| if status_str in ('complete', 'completed'): | |
| print("\n" + "=" * 75) | |
| print(f"🎉 KERNEL {kernel_id} ĐÃ HOÀN TẤT THÀNH CÔNG sau {elapsed_min} phút!") | |
| print("=" * 75) | |
| sys.stdout.flush() | |
| return 0 | |
| elif status_str in ('error', 'cancel', 'cancelled', 'aborted'): | |
| print("\n" + "=" * 75) | |
| print(f"❌ KERNEL {kernel_id} GẶP LỖI ({status_str.upper()}) sau {elapsed_min} phút!") | |
| if failure_msg: | |
| print(f" • Failure Message: {failure_msg}") | |
| if lines: | |
| print(" • 25 DÒNG LOG CUỐI CÙNG TRƯỚC KHI CRASH:") | |
| for l in lines[-25:]: | |
| print(f" ! {l}") | |
| print("=" * 75) | |
| sys.stdout.flush() | |
| return 1 | |
| except Exception as e: | |
| print(f"⚠️ [Lỗi API tại {elapsed_min}m]: {e}") | |
| sys.stdout.flush() | |
| time.sleep(poll_seconds) | |
| if __name__ == '__main__': | |
| kernel = sys.argv[1] if len(sys.argv) > 1 else 'gustavnguyen/paddleocr-cham-v25-stage1' | |
| interval = int(sys.argv[2]) if len(sys.argv) > 2 else 60 | |
| sys.exit(monitor(kernel, interval)) | |