Spaces:
Running
Running
File size: 7,969 Bytes
75b8dbb 770f650 75b8dbb | 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 | #!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Automated Remote Orchestrator for Cham-DBNet on Lightning AI Studio.
Manages:
1. Phase 1 (CPU): Git clone, dependencies install, dataset generation (12,000 pages, 50% tight lines).
2. Phase 2 (H100 Switch): Switch machine to NVIDIA H100 (80GB VRAM SXM5).
3. Phase 3 (Training & Monitoring): Launch PaddleOCR DBNet distributed training, stream log metrics.
4. Phase 4 (Export & Download): Export lightweight inference model, package ZIP, download locally.
5. Phase 5 (Auto Stop): Stop Studio immediately to prevent credit consumption.
"""
import os
import sys
import time
from lightning_sdk import Studio, Machine
if sys.stdout and sys.stdout.encoding != 'utf-8':
try:
sys.stdout.reconfigure(encoding='utf-8')
except AttributeError:
pass
def log(msg):
timestamp = time.strftime("%H:%M:%S")
print(f"[{timestamp}] {msg}", flush=True)
def main():
log("=================================================================")
log("🚀 KHỞI ĐỘNG REMOTE ORCHESTRATOR TRÊN LIGHTNING AI")
log("=================================================================")
studio = Studio(name="cham-det-h100", teamspace="phucsd", org="phucsd-org")
log(f"Trạng thái Studio hiện tại: {studio.status} (Machine: {studio.machine})")
# PHASE 1: CPU SETUP & DATASET GENERATION
log("\n📦 --- PHASE 1: THIẾT LẬP MÔI TRƯỜNG & SINH DỮ LIỆU TRÊN CPU (0 CREDIT) ---")
setup_cmds = [
# 1. Clone or Pull Cham-OCR
"if [ ! -d 'Cham-OCR' ]; then git clone https://github.com/phucsd/Cham-OCR.git; else cd Cham-OCR && git pull origin main && cd ..; fi",
# 2. Clone PaddleOCR inside Cham-OCR/ocr-training if not exists
"cd /teamspace/studios/this_studio/Cham-OCR/ocr-training && if [ ! -d 'PaddleOCR' ]; then git clone -b release/2.7 https://github.com/PaddlePaddle/PaddleOCR.git; fi",
# 3. Download fonts
"cd /teamspace/studios/this_studio/Cham-OCR/ocr-training && mkdir -p data/fonts && wget -q -nc -O data/fonts/NotoSansCham-Regular.ttf https://raw.githubusercontent.com/googlefonts/noto-fonts/main/hinted/ttf/NotoSansCham/NotoSansCham-Regular.ttf && wget -q -nc -O data/fonts/NotoSansCham-Bold.ttf https://raw.githubusercontent.com/googlefonts/noto-fonts/main/hinted/ttf/NotoSansCham/NotoSansCham-Bold.ttf",
# 4. Download pretrained weights
"cd /teamspace/studios/this_studio/Cham-OCR/ocr-training && mkdir -p PaddleOCR/pretrain_models && wget -q -nc -O PaddleOCR/pretrain_models/PPLCNetV3_x0_75_ocr_det.pdparams https://paddleocr.bj.bcebos.com/pretrained/PPLCNetV3_x0_75_ocr_det.pdparams",
# 5. Install general pip dependencies
"pip install -q pyclipper shapely imgaug lmdb attrdict pillow opencv-python pyyaml",
]
for cmd in setup_cmds:
log(f"Đang thực thi: {cmd[:70]}...")
out = studio.run(cmd)
if out.strip():
log(f" -> {out.strip()[:200]}")
log("✅ Thiết lập mã nguồn, phông chữ và pretrained model hoàn tất!")
# 6. Generate dataset on CPU
log("⚙️ Bắt đầu sinh 12,000 trang huấn luyện và 1,200 trang kiểm thử (50% cự ly siêu hẹp 3-10px)...")
gen_cmd = "cd /teamspace/studios/this_studio/Cham-OCR/ocr-training && python3 scripts/generate_detector_data_v2.py --num_train 12000 --num_val 1200 --output_dir PaddleOCR/data/detector_v2 --workers 8"
out = studio.run(gen_cmd)
log("Kết quả sinh dữ liệu:")
for line in out.strip().splitlines()[-6:]:
log(f" {line}")
# Copy config
studio.run("cd /teamspace/studios/this_studio/Cham-OCR/ocr-training && mkdir -p PaddleOCR/configs/det && cp configs/det/ch_PP-OCRv4_det_h100.yml PaddleOCR/configs/det/")
log("✅ Bộ dữ liệu và cấu hình H100 đã sẵn sàng!")
# PHASE 2: SWITCH MACHINE TO H100
log("\n🔥 --- PHASE 2: CHUYỂN ĐỔI PHẦN CỨNG SANG GPU NVIDIA H100 (80GB VRAM) ---")
log("Đang gửi lệnh switch_machine sang H100...")
studio.switch_machine(Machine.H100)
log(f"Trạng thái sau khi chuyển: {studio.status} (Machine: {studio.machine})")
# Install paddlepaddle-gpu for Hopper/CUDA
log("📦 Cài đặt PaddlePaddle GPU bản CUDA 11.8/12.x tối ưu H100...")
studio.run("pip install -q paddlepaddle-gpu -i https://www.paddlepaddle.org.cn/packages/stable/cu118/")
gpu_info = studio.run("nvidia-smi --query-gpu=name,memory.total --format=csv,noheader")
log(f"🔥 GPU đã nhận diện: {gpu_info.strip()}")
# PHASE 3: LAUNCH TRAINING WITH BACKGROUND MONITORING
log("\n🚀 --- PHASE 3: KHỞI CHẠY HUẤN LUYỆN CHAM-DBNET TRÊN H100 ---")
train_script = """cd /teamspace/studios/this_studio/Cham-OCR/ocr-training/PaddleOCR && nohup python3 -m paddle.distributed.launch --gpus '0' tools/train.py -c configs/det/ch_PP-OCRv4_det_h100.yml > train.log 2>&1 &"""
studio.run(train_script)
log("✅ Lệnh huấn luyện đã kích hoạt chạy ngầm (background) an toàn trên H100!")
# MONITORING LOOP
log("📊 Bắt đầu vòng lặp theo dõi liên tục tiến trình huấn luyện...")
prev_log_tail = ""
idle_count = 0
start_time = time.time()
while True:
time.sleep(15)
# Check if process is still running
ps_out = studio.run("ps aux | grep tools/train.py | grep -v grep | wc -l")
is_running = int(ps_out.strip() or "0") > 0
# Read log tail
try:
log_tail = studio.run("cd /teamspace/studios/this_studio/Cham-OCR/ocr-training/PaddleOCR && tail -n 8 train.log")
if log_tail.strip() != prev_log_tail:
prev_log_tail = log_tail.strip()
log("--- Cập nhật tiến trình mới nhất ---")
for l in log_tail.strip().splitlines()[-4:]:
log(f" {l}")
except Exception as e:
log(f"Không thể đọc log: {e}")
elapsed_mins = (time.time() - start_time) / 60
if not is_running:
log(f"\n🎉 Tiến trình huấn luyện đã kết thúc sau {elapsed_mins:.1f} phút!")
break
# PHASE 4: EXPORT MODEL & DOWNLOAD
log("\n📦 --- PHASE 4: XUẤT MÔ HÌNH INFERENCE & ĐÓNG GÓI ---")
export_cmd = """cd /teamspace/studios/this_studio/Cham-OCR/ocr-training/PaddleOCR && \
BEST_MODEL="output/ch_PP-OCRv4_det_cham_h100/best_accuracy" && \
if [ ! -f "${BEST_MODEL}.pdparams" ]; then BEST_MODEL="output/ch_PP-OCRv4_det_cham_h100/latest"; fi && \
python3 tools/export_model.py -c configs/det/ch_PP-OCRv4_det_h100.yml -o Global.pretrained_model=${BEST_MODEL} Global.save_inference_dir=../output/ch_PP-OCRv4_det_cham_infer && \
cd ../output && zip -r ../cham_dbnet_v1_infer.zip ch_PP-OCRv4_det_cham_infer/"""
out = studio.run(export_cmd)
log("Kết quả đóng gói:")
for l in out.strip().splitlines()[-5:]:
log(f" {l}")
# Download file to local workspace
local_zip_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "cham_dbnet_v1_infer.zip")
log(f"⬇️ Đang tải tệp mô hình về máy local: {local_zip_path}...")
studio.download_file("Cham-OCR/ocr-training/cham_dbnet_v1_infer.zip", local_zip_path)
log(f"✅ Đã tải thành công tệp mô hình ({os.path.getsize(local_zip_path) / (1024*1024):.2f} MB)!")
# PHASE 5: STOP STUDIO TO SAVE CREDITS
log("\n🛑 --- PHASE 5: TỰ ĐỘNG DỪNG STUDIO ĐỂ BẢO VỆ CREDIT ---")
studio.stop()
log("✅ Studio đã được DỪNG (STOPPED) an toàn! Không còn tiêu tốn bất kỳ credit nào.")
log("=================================================================")
log("🎊 HOÀN THÀNH TOÀN BỘ QUY TRÌNH HUẤN LUYỆN CHAM-DBNET TRÊN H100!")
log("=================================================================")
if __name__ == '__main__':
main()
|