Spaces:
Running
Running
Download ocr-training/scripts/prepare_v24_notebook.py from phucsd/cham-ocr-studio: direct link, hf CLI and curl.
- Browser
- Download file 10.6 kB
-
https://huggingface.co/spaces/phucsd/cham-ocr-studio/resolve/main/ocr-training/scripts/prepare_v24_notebook.py
- Command line
-
hf download hf://spaces/phucsd/cham-ocr-studio/ocr-training/scripts/prepare_v24_notebook.py
-
curl -L -o prepare_v24_notebook.py https://huggingface.co/spaces/phucsd/cham-ocr-studio/resolve/main/ocr-training/scripts/prepare_v24_notebook.py
10.6 kB
| import os | |
| import sys | |
| import json | |
| if sys.stdout and hasattr(sys.stdout, 'reconfigure'): | |
| sys.stdout.reconfigure(encoding='utf-8') | |
| def read_file(path): | |
| with open(path, 'r', encoding='utf-8') as f: | |
| return f.read() | |
| def main(): | |
| print("📦 Bắt đầu đóng gói Kaggle Notebook huấn luyện V24...") | |
| # 1. Đọc mã nguồn các script cục bộ | |
| dict_extension_code = read_file('ocr-training/scripts/dict_extension_v24.py') | |
| weight_surgery_code = read_file('ocr-training/scripts/weight_surgery_v24.py') | |
| generate_data_v24_code = read_file('ocr-training/scripts/generate_data_v24.py') | |
| config_v24_code = read_file('ocr-training/configs/rec_cham_v24.yml') | |
| kaggle_dict_extension = dict_extension_code | |
| kaggle_weight_surgery = weight_surgery_code | |
| cells = [] | |
| def add_md(text): | |
| cells.append({ | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [line + '\n' for line in text.splitlines()] | |
| }) | |
| def add_code(code_str): | |
| cells.append({ | |
| "cell_type": "code", | |
| "execution_count": None, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [line + '\n' for line in code_str.splitlines()] | |
| }) | |
| # Tiêu đề | |
| add_md("""# Huấn Luyện Mô Hình Nhận Diện Chữ Chăm PP-OCRv4 V24 (Dual GPU T4x2) | |
| Mô hình giải quyết triệt để: | |
| - Số thứ tự khổ thơ Chăm 1-99 (`꩑꩞` - `꩙꩙꩞`) | |
| - Dấu kết thúc câu kép Double Danda (`꩝꩝`) | |
| - Dấu phụ đối kháng `ꨲ` (Au, U+AA32) vs `ꨶ` (O, U+AA36) | |
| - Tổ hợp 3 tầng dấu phụ và bảo toàn nguyên âm trước `ꨯ`, `ꨯꨱ` | |
| - Khả năng chống chịu Mờ rung (Motion Blur) và Nhiễu giấy cổ""") | |
| # Phase 1: Environment & GPU Check | |
| add_md("## Phase 1: Cài đặt thư viện & Kiểm tra GPU T4x2") | |
| add_code("""# 1. Cài đặt PaddlePaddle GPU và các thư viện phụ trợ | |
| !pip install --quiet "paddlepaddle-gpu>=2.6.0" "albumentations>=1.4.0" fonttools pyyaml opencv-python Pillow | |
| # 2. Kiểm tra môi trường GPU | |
| import os | |
| import sys | |
| import paddle | |
| print("="*60) | |
| print("PADDLE ENVIRONMENT STATUS:") | |
| print("Paddle Version:", paddle.__version__) | |
| print("Compiled with CUDA:", paddle.is_compiled_with_cuda()) | |
| gpu_count = paddle.device.cuda.device_count() | |
| print(f"Detected GPU Count: {gpu_count}") | |
| print("="*60) | |
| if gpu_count < 1: | |
| print("⚠️ CẢNH BÁO: Không tìm thấy GPU! Vui lòng chọn Accelerator = GPU T4 x2 trong Settings.") | |
| else: | |
| for i in range(gpu_count): | |
| print(f" - GPU {i}: {paddle.device.cuda.get_device_name(i)}") | |
| """) | |
| # Phase 2: Setup Workspace & PaddleOCR | |
| add_md("## Phase 2: Khởi tạo thư mục làm việc & Clone PaddleOCR") | |
| add_code("""import os | |
| import shutil | |
| os.makedirs('/kaggle/working/data/fonts', exist_ok=True) | |
| os.makedirs('/kaggle/working/data/output_v24_temp', exist_ok=True) | |
| os.makedirs('/kaggle/working/configs', exist_ok=True) | |
| os.makedirs('/kaggle/working/scripts', exist_ok=True) | |
| os.makedirs('/kaggle/working/output/rec_cham_v24', exist_ok=True) | |
| os.makedirs('/kaggle/working/output/v24_training', exist_ok=True) | |
| # Tự động phát hiện đường dẫn Assets Input trên Kaggle | |
| candidate_asset_dirs = [ | |
| "/kaggle/input/cham-ocr-v5-assets", | |
| "/kaggle/input/datasets/gustavnguyen/cham-ocr-v5-assets" | |
| ] | |
| ASSETS_DIR = None | |
| for d in candidate_asset_dirs: | |
| if os.path.exists(d): | |
| ASSETS_DIR = d | |
| break | |
| if not ASSETS_DIR and os.path.exists('/kaggle/input'): | |
| for root, dirs, files in os.walk('/kaggle/input'): | |
| if 'v23_checkpoint' in dirs: | |
| ASSETS_DIR = root | |
| break | |
| if not ASSETS_DIR: | |
| raise FileNotFoundError(f"❌ LỖI: Không tìm thấy thư mục Assets trong /kaggle/input") | |
| print(f"✅ Đã tìm thấy Assets Input tại: {ASSETS_DIR}") | |
| # Copy fonts | |
| fonts_src = os.path.join(ASSETS_DIR, "fonts", "fonts") | |
| if not os.path.exists(fonts_src): | |
| fonts_src = os.path.join(ASSETS_DIR, "fonts") | |
| for f in os.listdir(fonts_src): | |
| if f.endswith(('.ttf', '.otf')): | |
| shutil.copy2(os.path.join(fonts_src, f), os.path.join('/kaggle/working/data/fonts', f)) | |
| print("✅ Đã sao chép fonts:", os.listdir('/kaggle/working/data/fonts')) | |
| # Clone PaddleOCR nếu chưa có | |
| if not os.path.exists('/kaggle/working/PaddleOCR'): | |
| print("⏳ Đang clone PaddleOCR...") | |
| !git clone --depth 1 https://github.com/PaddlePaddle/PaddleOCR.git /kaggle/working/PaddleOCR | |
| !pip install --quiet -r /kaggle/working/PaddleOCR/requirements.txt | |
| else: | |
| print("✅ PaddleOCR đã tồn tại sẵn.") | |
| """) | |
| # Phase 3: Ghi mã nguồn các script | |
| add_md("## Phase 3: Nạp kịch bản Sinh dữ liệu, Mở rộng từ điển & Phẫu thuật trọng số") | |
| add_code(f"%%writefile /kaggle/working/scripts/dict_extension_v24.py\n{kaggle_dict_extension}") | |
| add_code(f"%%writefile /kaggle/working/scripts/weight_surgery_v24.py\n{kaggle_weight_surgery}") | |
| add_code(f"%%writefile /kaggle/working/scripts/generate_data_v24.py\n{generate_data_v24_code}") | |
| add_code(f"%%writefile /kaggle/working/configs/rec_cham_v24.yml\n{config_v24_code}") | |
| # Phase 4: Chạy chuẩn bị dữ liệu và phẫu thuật trọng số | |
| add_md("## Phase 4: Mở rộng từ điển, Phẫu thuật trọng số & Sinh 50K dữ liệu V24 đặc trị") | |
| add_code("""import os, sys, time | |
| %cd /kaggle/working | |
| print("=== BƯỚC 1: MỞ RỘNG TỪ ĐIỂN V24 ===") | |
| !python3 scripts/dict_extension_v24.py | |
| print("\\n=== BƯỚC 2: PHẪU THUẬT TRỌNG SỐ V24 ===") | |
| !python3 scripts/weight_surgery_v24.py | |
| print("\\n=== BƯỚC 3: SINH DỮ LIỆU TỔNG HỢP V24 ĐẶC TRỊ (45K TRAIN, 4.5K VAL) ===") | |
| t_start = time.time() | |
| # Chạy với 4 vCPU | |
| !python3 scripts/generate_data_v24.py --output-dir /kaggle/working/data/cham_synthetic_v24 --fonts-dir /kaggle/working/data/fonts --num-train 45000 --num-val 4500 --num-workers 4 | |
| print(f"🎉 Hoàn thành toàn bộ dữ liệu trong {(time.time()-t_start)/60:.2f} phút!") | |
| """) | |
| # Phase 5: Khởi chạy huấn luyện song song phân tán trên GPU T4x2 | |
| add_md("## Phase 5: Huấn luyện phân tán song song trên Dual GPU Tesla T4x2 (20 Epochs)") | |
| add_code("""import os | |
| import paddle | |
| gpu_count = paddle.device.cuda.device_count() | |
| print(f"🔥 Khởi chạy huấn luyện với {gpu_count} GPU...") | |
| os.environ["PYTHONUNBUFFERED"] = "1" | |
| os.environ["FLAGS_fraction_of_gpu_memory_to_use"] = "0.90" | |
| %cd /kaggle/working/PaddleOCR | |
| if gpu_count > 1: | |
| print("🚀 Sử dụng lệnh phân tán song song đa GPU (paddle.distributed.launch --gpus '0,1'):") | |
| !python3 -m paddle.distributed.launch --gpus '0,1' tools/train.py -c /kaggle/working/configs/rec_cham_v24.yml | |
| else: | |
| print("⚡ Huấn luyện trên Single GPU:") | |
| !python3 tools/train.py -c /kaggle/working/configs/rec_cham_v24.yml | |
| """) | |
| # Phase 6: Xuất mô hình Inference & Đóng gói ZIP | |
| add_md("## Phase 6: Xuất mô hình Inference & Đóng gói rec_cham_v24_best.zip") | |
| add_code("""import os | |
| import shutil | |
| import zipfile | |
| %cd /kaggle/working/PaddleOCR | |
| best_ckpt = "/kaggle/working/output/rec_cham_v24/best_accuracy" | |
| latest_ckpt = "/kaggle/working/output/rec_cham_v24/latest" | |
| target_ckpt = best_ckpt if os.path.exists(best_ckpt + ".pdparams") else latest_ckpt | |
| print(f"🎯 Sử dụng checkpoint: {target_ckpt}") | |
| infer_dir = "/kaggle/working/output/rec_cham_inference_v24" | |
| os.makedirs(infer_dir, exist_ok=True) | |
| # Xuất mô hình inference | |
| !python3 tools/export_model.py -c /kaggle/working/configs/rec_cham_v24.yml -o Global.pretrained_model={target_ckpt} Global.save_inference_dir={infer_dir} Global.export_with_pir=False | |
| # Copy từ điển vào thư mục inference | |
| shutil.copy2('/kaggle/working/data/cham_dict_v24.txt', os.path.join(infer_dir, 'cham_dict_v24.txt')) | |
| print("✅ Thư mục Inference:", os.listdir(infer_dir)) | |
| # Đóng gói toàn bộ kết quả thành file zip trong /kaggle/working | |
| zip_path = "/kaggle/working/rec_cham_v24_best.zip" | |
| print(f"📦 Đang nén kết quả vào {zip_path}...") | |
| with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: | |
| # Nén inference model | |
| for root, dirs, files in os.walk(infer_dir): | |
| for f in files: | |
| full_p = os.path.join(root, f) | |
| rel_p = os.path.relpath(full_p, "/kaggle/working") | |
| zipf.write(full_p, rel_p) | |
| # Nén best accuracy pdparams | |
| for ext in [".pdparams", ".pdopt", ".states"]: | |
| p = target_ckpt + ext | |
| if os.path.exists(p): | |
| zipf.write(p, os.path.join("best_checkpoint", os.path.basename(p))) | |
| # Nén từ điển | |
| zipf.write('/kaggle/working/data/cham_dict_v24.txt', 'cham_dict_v24.txt') | |
| print(f"🎉 HOÀN TẤT TRỌN GÓI! File zip sẵn sàng ({os.path.getsize(zip_path) / (1024*1024):.2f} MB): {zip_path}") | |
| """) | |
| # 5. Lưu Notebook JSON | |
| notebook_dict = { | |
| "cells": cells, | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "name": "python", | |
| "version": "3.10.12" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 4 | |
| } | |
| submission_dir = 'ocr-training/output/kaggle_v24_submission' | |
| os.makedirs(submission_dir, exist_ok=True) | |
| nb_path = os.path.join(submission_dir, 'paddleocr_cham_v24_train.ipynb') | |
| with open(nb_path, 'w', encoding='utf-8') as f: | |
| json.dump(notebook_dict, f, indent=1, ensure_ascii=False) | |
| meta_path = os.path.join(submission_dir, 'kernel-metadata.json') | |
| metadata = { | |
| "id": "gustavnguyen/paddleocr-cham-finetune", | |
| "title": "paddleocr-cham-finetune", | |
| "code_file": "paddleocr_cham_v24_train.ipynb", | |
| "language": "python", | |
| "kernel_type": "notebook", | |
| "is_private": "true", | |
| "enable_gpu": "true", | |
| "enable_tpu": "false", | |
| "enable_internet": "true", | |
| "dataset_sources": [ | |
| "gustavnguyen/cham-ocr-v5-assets" | |
| ], | |
| "competition_sources": [], | |
| "kernel_sources": [], | |
| "model_sources": [] | |
| } | |
| with open(meta_path, 'w', encoding='utf-8') as f: | |
| json.dump(metadata, f, indent=2) | |
| print(f"✅ Đã tạo thành công Notebook tại: {nb_path}") | |
| print(f"✅ Đã tạo kernel-metadata tại: {meta_path}") | |
| return nb_path, meta_path | |
| if __name__ == '__main__': | |
| main() | |