cham-ocr-studio / ocr-training /scripts /kaggle_train_det.py
phucsd's picture
Upload folder using huggingface_hub
770f650 verified
Raw History Blame Contribute Delete
8.4 kB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Kaggle Training Automation for Cham Text Detection (Phase 4).
Prepares and submits a multi-GPU (T4x2) PaddleOCR DBNet training job to Kaggle,
strictly following the Cham-OCR project rules:
- Kaggle user: "gustavnguyen" (Key nạp tự động qua kaggle_auth / .env)
- Accelerator: NvidiaTeslaT4
- Distributed multi-GPU execution: paddle.distributed.launch --gpus '0,1'
"""
import os
import sys
import json
import subprocess
import shutil
import tempfile
# Force UTF-8 standard output for Windows console
if sys.stdout and sys.stdout.encoding != 'utf-8':
try:
sys.stdout.reconfigure(encoding='utf-8')
except AttributeError:
pass
# Kaggle credentials
from kaggle_auth import init_kaggle_auth
init_kaggle_auth()
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(PROJECT_ROOT, "scripts"))
from kaggle_ops import get_authenticated_api, monitor_kernel, download_kernel_outputs
def build_det_notebook():
"""Generates the Jupyter Notebook for running Cham Detection training on Kaggle."""
nb = {
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cham OCR Text Detection Fine-Tuning (Phase 4 - DBNet PP-OCRv4)\n",
"Automated training pipeline for Cham scene text & manuscript detection on Kaggle T4x2."
]
},
{
"cell_type": "code",
"execution_count": None,
"metadata": {},
"outputs": [],
"source": [
"# 1. Environment & Dependencies Setup\n",
"!pip install --upgrade pip\n",
"!pip install \"paddlepaddle-gpu>=2.6.0\" -i https://www.paddlepaddle.org.cn/packages/stable/cu118/\n",
"!pip install imgaug pyclipper shapely lmdb attrdict\n",
"\n",
"import paddle\n",
"print(f\"PaddlePaddle version: {paddle.__version__}\")\n",
"print(f\"CUDA available: {paddle.is_compiled_with_cuda()}\")\n",
"num_gpus = paddle.device.cuda.device_count()\n",
"print(f\"GPU count: {num_gpus}\")\n"
]
},
{
"cell_type": "code",
"execution_count": None,
"metadata": {},
"outputs": [],
"source": [
"# 2. Clone PaddleOCR repository\n",
"import os\n",
"if not os.path.exists('PaddleOCR'):\n",
" !git clone -b release/2.7 https://github.com/PaddlePaddle/PaddleOCR.git\n",
"\n",
"%cd PaddleOCR\n",
"!pip install -r requirements.txt\n"
]
},
{
"cell_type": "code",
"execution_count": None,
"metadata": {},
"outputs": [],
"source": [
"# 3. Prepare Cham Detection Dataset\n",
"%cd /kaggle/working/PaddleOCR\n",
"os.makedirs('data/detector', exist_ok=True)\n",
"os.makedirs('data/fonts', exist_ok=True)\n",
"os.makedirs('data/corpus', exist_ok=True)\n",
"\n",
"# Download Cham fonts\n",
"!wget -q -O data/fonts/NotoSansCham-Regular.ttf https://raw.githubusercontent.com/googlefonts/noto-fonts/main/hinted/ttf/NotoSansCham/NotoSansCham-Regular.ttf\n",
"!wget -q -O data/fonts/NotoSansCham-Bold.ttf https://raw.githubusercontent.com/googlefonts/noto-fonts/main/hinted/ttf/NotoSansCham/NotoSansCham-Bold.ttf\n",
"\n",
"print(\"Fonts downloaded successfully.\")\n"
]
},
{
"cell_type": "code",
"execution_count": None,
"metadata": {},
"outputs": [],
"source": [
"# 4. Adaptive Multi-GPU Training\n",
"import paddle\n",
"num_gpus = paddle.device.cuda.device_count()\n",
"print(f\"Detected {num_gpus} GPUs for training.\")\n",
"\n",
"config_path = 'configs/det/ch_PP-OCRv4_det_cham.yml'\n",
"\n",
"# Download pre-trained DBNet weights\n",
"!wget -q https://paddleocr.bj.bcebos.com/pretrained/PPLCNetV3_x0_75_ocr_det.pdparams -O ./pretrained_det.pdparams\n",
"\n",
"if num_gpus > 1:\n",
" gpus = ','.join(str(i) for i in range(num_gpus))\n",
" print(f\"Launching distributed training on GPUs {gpus}...\")\n",
" !python3 -m paddle.distributed.launch --gpus '{gpus}' tools/train.py -c {config_path} -o Global.pretrained_model=./pretrained_det.pdparams\n",
"else:\n",
" print(\"Launching single GPU training...\")\n",
" !python3 tools/train.py -c {config_path} -o Global.pretrained_model=./pretrained_det.pdparams\n"
]
},
{
"cell_type": "code",
"execution_count": None,
"metadata": {},
"outputs": [],
"source": [
"# 5. Export Inference Model\n",
"print(\"Exporting detection model to inference format...\")\n",
"!python3 tools/export_model.py -c configs/det/ch_PP-OCRv4_det_cham.yml -o Global.checkpoints=./output/ch_PP-OCRv4_det_cham/latest Global.save_inference_dir=./output/det_cham_inference\n",
"\n",
"# Archive outputs\n",
"!zip -r /kaggle/working/det_cham_inference.zip ./output/det_cham_inference\n",
"print(\"Done! Checkpoint ready for download.\")\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {"name": "ipython", "version": 3},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbformat": 4,
"nbformat_minor": 4
}
},
"nbformat": 4,
"nbformat_minor": 4
}
return nb
def main():
print("🚀 Cham Text Detection - Kaggle Dispatcher (Phase 4)")
api = get_authenticated_api()
if not api:
print("❌ Cannot authenticate with Kaggle API.")
return
work_dir = os.path.join(PROJECT_ROOT, "output", "kaggle_det_submission")
os.makedirs(work_dir, exist_ok=True)
# 1. Write notebook
nb_path = os.path.join(work_dir, "kaggle_det_notebook.ipynb")
nb_data = build_det_notebook()
with open(nb_path, "w", encoding="utf-8") as f:
json.dump(nb_data, f, indent=2, ensure_ascii=False)
print(f"📝 Generated Kaggle notebook at: {nb_path}")
# 2. Write metadata
kernel_slug = "cham-ocr-v4-det-train"
meta = {
"id": f"gustavnguyen/{kernel_slug}",
"title": kernel_slug,
"code_file": "kaggle_det_notebook.ipynb",
"language": "python",
"kernel_type": "notebook",
"is_private": "true",
"enable_gpu": "true",
"enable_internet": "true",
"dataset_sources": [],
"competition_sources": [],
"kernel_sources": []
}
meta_path = os.path.join(work_dir, "kernel-metadata.json")
with open(meta_path, "w", encoding="utf-8") as f:
json.dump(meta, f, indent=2)
print(f"📋 Generated kernel-metadata.json at: {meta_path}")
print("\n📦 To launch training on Kaggle:")
print(f" kaggle kernels push -p \"{work_dir}\"")
print("\n⚙️ Configured GPU: NvidiaTeslaT4 (T4x2) with adaptive paddle.distributed.launch")
if __name__ == '__main__':
main()