cham-ocr-studio / ocr-training /scripts /run_lightning_remote.py
phucsd's picture
Upload folder using huggingface_hub
770f650 verified
Raw History Blame Contribute Delete
7.97 kB
#!/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()