Spaces:
Running
Running
File size: 7,654 Bytes
a183ff9 770f650 a183ff9 | 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 179 180 181 182 183 184 185 186 187 | import os
import sys
import time
import zipfile
import socket
from kaggle.api.kaggle_api_extended import KaggleApi
# Thiết lập timeout cho socket để tránh bị treo kết nối vô hạn trên Windows
socket.setdefaulttimeout(30)
# Configure UTF-8 standard output for Windows console stability
if sys.stdout and sys.stdout.encoding != 'utf-8':
try:
sys.stdout.reconfigure(encoding='utf-8')
except AttributeError:
pass
def get_authenticated_api():
"""Khởi tạo và xác thực với Kaggle API"""
try:
try:
from scripts.kaggle_auth import init_kaggle_auth
except ImportError:
from kaggle_auth import init_kaggle_auth
init_kaggle_auth()
api = KaggleApi()
api.authenticate()
return api
except Exception as e:
print(f"❌ Lỗi xác thực Kaggle API: {e}")
print("Vui lòng đảm bảo thông tin xác thực Kaggle hợp lệ.")
return None
def monitor_kernel(user, slug, poll_interval_seconds=60):
"""
Theo dõi liên tục trạng thái chạy của Kaggle notebook.
Trả về True nếu hoàn thành thành công, False nếu thất bại.
"""
api = get_authenticated_api()
if not api:
return False
print(f"👁️ Bắt đầu theo dõi Kernel: {user}/{slug}")
print("⏱️ Đợi 15 giây để máy chủ Kaggle cập nhật trạng thái mới sau khi push...")
time.sleep(15)
start_time = time.time()
last_status = None
while True:
try:
res = api.kernels_status(f"{user}/{slug}")
if hasattr(res, 'status') and hasattr(res.status, 'name'):
status = res.status.name.lower()
else:
status = 'unknown'
# Chỉ in trạng thái khi có sự thay đổi để tránh tràn màn hình log
if status != last_status:
elapsed_minutes = int((time.time() - start_time) / 60)
print(f"⏱️ [Sau {elapsed_minutes} phút] Trạng thái Kernel: {status.upper()}")
last_status = status
if status == 'complete':
print("🎉 Tiến trình máy ảo Kaggle đã kết thúc chạy code.")
return True
elif status in ['error', 'cancel', 'aborted']:
print(f"❌ Kernel kết thúc với trạng thái lỗi từ hệ thống: {status.upper()}")
return False
except Exception as e:
print(f"⚠️ Lỗi khi kiểm tra trạng thái Kernel: {e}")
time.sleep(poll_interval_seconds)
def download_kernel_outputs(user, slug, download_dir):
"""
Tải toàn bộ file đầu ra (ZIP checkpoint) từ Kaggle và giải nén cục bộ.
"""
api = get_authenticated_api()
if not api:
return False
os.makedirs(download_dir, exist_ok=True)
print(f"📥 Đang tải các tệp đầu ra từ Kaggle {user}/{slug} về thư mục: {download_dir}...")
# Tăng default timeout khi tải để tránh lỗi timeout do khối lượng file lớn (ảnh + PaddleOCR)
import socket
socket.setdefaulttimeout(600)
try:
# Tải đầu ra thông qua Kaggle API, chỉ lọc các file .zip để tải về cực nhanh
api.kernels_output(f"{user}/{slug}", path=download_dir, file_pattern=r'.*\.zip$', page_size=100)
print("✅ Tải hoàn tất.")
# Tìm file .zip để giải nén tự động
zip_files = [f for f in os.listdir(download_dir) if f.endswith('.zip')]
if not zip_files:
print("❌ LỖI: Không tìm thấy bất kỳ tệp kết quả .zip nào trong thư mục tải về!")
print("Có thể tiến trình huấn luyện đã bị sập sớm trên Kaggle nên không xuất được tệp trọng số.")
return False
for zip_f in zip_files:
zip_path = os.path.join(download_dir, zip_f)
# Kiểm tra kích thước file zip
if os.path.getsize(zip_path) < 1024: # Dưới 1KB là file rỗng/lỗi
print(f"❌ LỖI: Tệp {zip_f} có dung lượng quá nhỏ ({os.path.getsize(zip_path)} bytes), có thể bị lỗi.")
return False
extract_path = os.path.join(download_dir, zip_f.replace('.zip', ''))
os.makedirs(extract_path, exist_ok=True)
print(f"📦 Đang giải nén {zip_f} vào {extract_path}...")
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
zip_ref.extractall(extract_path)
print(f"✅ Giải nén xong: {extract_path}")
return True
except Exception as e:
print(f"❌ Lỗi khi tải hoặc giải nén kết quả: {e}")
return False
def upload_dataset_version(dataset_id, folder_path, version_notes="New model version from local training"):
"""
Tải thư mục lên Kaggle dưới dạng một phiên bản mới của Dataset.
dataset_id: định dạng 'username/dataset-slug'
"""
api = get_authenticated_api()
if not api:
return False
if not os.path.exists(folder_path):
print(f"❌ Thư mục không tồn tại: {folder_path}")
return False
print(f"📤 Đang tạo phiên bản mới cho Dataset: {dataset_id} từ: {folder_path}...")
try:
api.dataset_create_version(folder_path, version_notes, dir_mode='zip')
print("✅ Đã đẩy lên Kaggle Dataset thành công!")
return True
except Exception as e:
print(f"❌ Lỗi khi cập nhật Dataset Kaggle: {e}")
return False
def push_kernel(folder_path="."):
"""
Đẩy kernel lên Kaggle sử dụng CLI và luôn luôn ép buộc bộ tăng tốc GPU tối ưu (NvidiaTeslaT4)
để cấp phát GPU T4x2 song song.
"""
import subprocess
print("🚀 Đang chạy lệnh đẩy Notebook lên Kaggle...")
print("🔥 Bắt buộc sử dụng bộ tăng tốc: NvidiaTeslaT4 (GPU T4x2 phân tán)...")
cmd = "kaggle kernels push -p . --accelerator NvidiaTeslaT4"
try:
res = subprocess.run(cmd, check=True, capture_output=True, text=True, shell=True)
print("✅ Thành công!")
print(res.stdout)
return True
except subprocess.CalledProcessError as e:
print(f"❌ Lỗi khi đẩy kernel: {e}")
print(f"Stderr: {e.stderr}")
return False
if __name__ == '__main__':
# Hướng dẫn chạy thử nghiệm
if len(sys.argv) < 2:
print("Sử dụng:")
print(" python scripts/kaggle_ops.py push")
print(" python scripts/kaggle_ops.py monitor <username> <slug>")
print(" python scripts/kaggle_ops.py download <username> <slug> <output_dir>")
sys.exit(1)
action = sys.argv[1]
if action == 'push':
folder = sys.argv[2] if len(sys.argv) > 2 else "."
push_kernel(folder)
elif action == 'monitor':
if len(sys.argv) < 4:
print("Thiếu tham số: python scripts/kaggle_ops.py monitor <username> <slug>")
sys.exit(1)
monitor_kernel(sys.argv[2], sys.argv[3])
elif action == 'download':
if len(sys.argv) < 5:
print("Thiếu tham số: python scripts/kaggle_ops.py download <username> <slug> <output_dir>")
sys.exit(1)
download_kernel_outputs(sys.argv[2], sys.argv[3], sys.argv[4])
|