File size: 7,250 Bytes
770f650
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Điều phối tự động bài Benchmark Cham-OCR Recognition V24 trên Kaggle Dual GPU Tesla T4x2:
1. Đóng gói Kaggle Notebook
2. Đẩy lên Kaggle với bộ tăng tốc bắt buộc NvidiaTeslaT4 (T4x2 phân tán)
3. Giám sát thời gian thực luồng log SSE và trạng thái Kernel
4. Tự động tải file benchmark_t4_results.zip và hiển thị bảng kết quả phân tích.
"""

import os
import sys
import time
import json
import zipfile
import socket
import threading
import subprocess

if sys.stdout and hasattr(sys.stdout, 'reconfigure'):
    sys.stdout.reconfigure(encoding='utf-8')

# Thiết lập timeout cho socket
socket.setdefaulttimeout(60)

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
if SCRIPT_DIR not in sys.path:
    sys.path.insert(0, SCRIPT_DIR)

from kaggle_auth import init_kaggle_auth
init_kaggle_auth()

from kaggle.api.kaggle_api_extended import KaggleApi

KERNEL_USER = "gustavnguyen"
KERNEL_SLUG = "cham-ocr-t4-benchmark"
KERNEL_ID = f"{KERNEL_USER}/{KERNEL_SLUG}"
SUBMISSION_DIR = os.path.abspath("ocr-training/output/kaggle_benchmark_submission")
OUTPUT_DIR = os.path.abspath("ocr-training/benchmark_results/kaggle_t4")

def get_api():
    api = KaggleApi()
    api.authenticate()
    return api

def stream_logs_worker(api, kernel_id, log_file_path, stop_event):
    """Lắng nghe luồng SSE log trực tiếp từ Kaggle và in các sự kiện quan trọng"""
    while not stop_event.is_set():
        try:
            with open(log_file_path, 'a', encoding='utf-8') as f_log:
                for event in api.kernels_logs_stream(kernel_id):
                    if stop_event.is_set():
                        break
                    data = event.get('data', '')
                    if data:
                        f_log.write(data)
                        f_log.flush()
                        for line in data.splitlines():
                            line_str = line.strip()
                            if any(k in line_str for k in [
                                '🔥 BẮT ĐẦU:', 'HOÀN THÀNH:', 'THẤT BẠI', 'Steady Step',
                                'BẢNG TỔNG KẾT', 'CẤU HÌNH TỐI ƯU NHẤT', 'Detected GPU Count',
                                'Place(gpu', 'Hoàn thành sinh dữ liệu', 'OOM', 'Exception', 'Error',
                                'Max Steady-State', 'Thời gian hoàn thành'
                            ]) or ('|' in line_str and any(t in line_str for t in ['T1', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'T8', 'Trial Name', 'Thí nghiệm'])):
                                print(f"⚡ [KAGGLE T4x2] {line_str}", flush=True)
        except Exception:
            pass
        if not stop_event.is_set():
            time.sleep(3)

def main():
    skip_push = "--monitor-only" in sys.argv or "--skip-push" in sys.argv
    print("="*80)
    print("🚀 ĐIỀU PHỐI BENCHMARK DUAL GPU TESLA T4x2 TRÊN KAGGLE")
    print(f"🎯 Kernel Target: {KERNEL_ID}")
    print(f"⚙️  Accelerator: NvidiaTeslaT4 (Dual GPU T4x2)")
    print("="*80)
    
    api = get_api()
    print("✅ Xác thực thành công tài khoản:", os.environ["KAGGLE_USERNAME"])

    if not skip_push:
        # 1. Sinh notebook mới nhất
        print("\n📦 Bước 1: Chuẩn bị Kaggle Benchmark Notebook...")
        import prepare_benchmark_notebook
        prepare_benchmark_notebook.main()
        
        # 2. Đẩy Kernel lên Kaggle
        print("\n📤 Bước 2: Đẩy Notebook lên Kaggle với cờ --accelerator NvidiaTeslaT4...")
        push_cmd = f"kaggle kernels push -p \"{SUBMISSION_DIR}\" --accelerator NvidiaTeslaT4"
        env = os.environ.copy()
        env["PYTHONUTF8"] = "1"
        res = subprocess.run(push_cmd, shell=True, capture_output=True, text=True, encoding='utf-8', errors='replace', env=env)
        if res.returncode != 0:
            print(f"❌ Lỗi khi đẩy kernel: {res.stderr}")
            sys.exit(1)
        print("✅ Đã đẩy kernel thành công!")
        print(res.stdout.strip())
    else:
        print("ℹ️  Chế độ Monitor-Only: Bỏ qua bước sinh notebook và push, kết nối trực tiếp vào Kernel đang chạy.")
    
    # 3. Giám sát & Stream Live Log
    print("\n📡 Bước 3: Giám sát Kernel & Lắng nghe luồng SSE Live Log...")
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    live_log = os.path.join(OUTPUT_DIR, "live_benchmark.log")
    if os.path.exists(live_log):
        os.remove(live_log)
        
    stop_event = threading.Event()
    stream_t = threading.Thread(target=stream_logs_worker, args=(api, KERNEL_ID, live_log, stop_event), daemon=True)
    stream_t.start()
    
    start_time = time.time()
    last_status = None
    
    while True:
        try:
            status_obj = api.kernels_status(KERNEL_ID)
            status = getattr(status_obj, 'status', None)
            if hasattr(status, 'name'):
                status_name = status.name.lower()
            elif isinstance(status, str):
                status_name = status.lower()
            else:
                status_name = str(status).lower()
                
            elapsed = int(time.time() - start_time)
            if status_name != last_status:
                print(f"⏱️  [{elapsed//60}m {elapsed%60}s] Trạng thái Kernel: {status_name.upper()}", flush=True)
                last_status = status_name
                
            if status_name in ['complete']:
                print("\n🎉 Kernel đã hoàn thành toàn bộ quá trình chạy!")
                break
            elif status_name in ['error', 'cancel', 'aborted']:
                print(f"\n❌ Kernel kết thúc bất thường với trạng thái: {status_name.upper()}")
                stop_event.set()
                sys.exit(1)
        except Exception as e:
            print(f"⚠️  Cảnh báo kiểm tra trạng thái: {e}")
            
        time.sleep(15)
        
    stop_event.set()
    
    # 5. Tải file kết quả ZIP
    print("\n📥 Bước 5: Tải tệp kết quả benchmark_t4_results.zip về máy cục bộ...")
    time.sleep(5)
    
    try:
        api.kernels_output(KERNEL_ID, path=OUTPUT_DIR)
        print("✅ Tải kết quả hoàn tất!")
        
        # Giải nén kết quả
        zip_files = [f for f in os.listdir(OUTPUT_DIR) if f.endswith('.zip')]
        for z in zip_files:
            z_path = os.path.join(OUTPUT_DIR, z)
            print(f"📦 Đang giải nén: {z}...")
            with zipfile.ZipFile(z_path, 'r') as zipf:
                zipf.extractall(OUTPUT_DIR)
            print("✅ Giải nén xong!")
            
        # Hiển thị tóm tắt nếu có
        summary_md = os.path.join(OUTPUT_DIR, "benchmark_t4_summary.md")
        if os.path.exists(summary_md):
            print("\n" + "="*80)
            print("📄 KẾT QUẢ BÁO CÁO BENCHMARK T4x2:")
            print("="*80)
            with open(summary_md, "r", encoding="utf-8") as f:
                print(f.read())
                
    except Exception as e:
        print(f"❌ Lỗi khi tải hoặc đọc kết quả: {e}")

if __name__ == '__main__':
    main()