From 3657318d47fba433a42a79e608edf355e5154d7c Mon Sep 17 00:00:00 2001 From: songhyeonsoo Date: Mon, 18 May 2026 11:18:17 +0900 Subject: [PATCH] docs: merge ONBOARDING into README, remove duplicate Co-Authored-By: Claude Sonnet 4.6 --- ONBOARDING.md | 270 ------------------------------------------------ README.md | 280 ++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 248 insertions(+), 302 deletions(-) delete mode 100644 ONBOARDING.md diff --git a/ONBOARDING.md b/ONBOARDING.md deleted file mode 100644 index 0271ec1..0000000 --- a/ONBOARDING.md +++ /dev/null @@ -1,270 +0,0 @@ -# kr_lp_pgnet — 프로젝트 핸드오프 - -한국 자동차 번호판 검출 + OCR을 위한 PaddleOCR PGNet 학습 프로젝트. - ---- - -## 30초 요약 - -- **목표**: PGNet 한 모델로 한국 LP 4종 (자가용/영업/전기/화물) 검출+인식 → ONNX export -- **현재 상태 (2026-05-08)**: Step1 pretrain **학습 중** (50 epoch, eta ~11시간, run id `l0eqqbrb`) -- **다음 단계**: 학습 완료 후 → Step2 fine-tune (실차 데이터) → ONNX export -- **운영 원칙**: 로컬 Mac은 코드 작성·git만, 모든 실행(학습·합성·검증)은 외부 GPU 서버에서 - ---- - -## 환경 - -### 1. 로컬 Mac (코드 작성 전용) -- 작업 디렉토리: `/Users/songhyeonsu/Documents/GIT/cuuva_AI/kr_lp_pgnet/` -- **금지사항** (메모리 `feedback_local_no_runtime.md`): - - Python 패키지 설치 (`pip install ...`) - - 외부 자산 git clone (qjadud 등) - - 합성기·학습·평가 실행 -- **허용**: 코드/yaml/sh 작성·수정, 우리 repo git commit/push - -### 2. 외부 GPU 서버 -- **SSH**: `ssh cuuva@192.168.10.189` (사내망 전용, key 인증) -- **호스트**: Ubuntu 25.10, RTX 5090 32GB, NVIDIA driver 590.48.01, CUDA 13.1 -- **레이아웃**: - ``` - /home/cuuva/workspace/ - ├── PaddleOCR/ # git clone release/2.7 - ├── kr_lp_pgnet/ # 이 repo (사내망 GitLab에서 clone) - ├── train_data/ - │ ├── kr_lp_synth/ # Step1 학습용 (50k, 본격) - │ ├── kr_lp_synth_v2/ # 400장 (dry-run용) - │ ├── kr_lp_synth_smoke/ # 40장 (smoke test) - │ ├── region_check_y/ # 영업용 region 16종 검증 - │ └── region_check_g/ # 친환경 region 16종 검증 - └── wheels/ - └── paddlepaddle_gpu-3.3.0.dev20251209-cp310-...whl # sm_120 wheel - ``` - -### 3. 학습 컨테이너 `kr_lp_pgnet` -- 베이스: `ubuntu:24.04` -- 옵션: `--gpus all --shm-size=8g --restart unless-stopped` -- bind mount: 호스트 `/home/cuuva/workspace` ↔ 컨테이너 `/workspace` -- 설치된 것: Python 3.10 (deadsnakes), paddlepaddle-gpu 3.3.0.dev (sm_120), cuDNN 9.17, numpy 1.26, opencv 4.10+, wandb 0.26, PaddleOCR + 의존성 -- 재셋업: `bash scripts/recreate_container.sh` (한 줄로 전부) - -### 4. 파일 서버 컨테이너 `kr_lp_http` -- 합성 결과 시각 확인용 -- URL: **http://192.168.10.189:8889/** -- 마운트: `/home/cuuva/workspace/train_data` (read-only) -- 시작 명령: - ```bash - docker run -d --name kr_lp_http -v /home/cuuva/workspace/train_data:/data:ro \ - -p 8889:8889 --restart unless-stopped python:3.11-slim \ - python3 -m http.server 8889 --bind 0.0.0.0 --directory /data - ``` - -### 5. 다른 컨테이너 `my-vision-container` (우리 일과 무관, 그대로 두기) -- 4주 전 시작, 8888 포트로 Jupyter 노출 -- 우리 paddle wheel 설치 중 cuda-bindings/nccl 충돌로 **torch import 깨진 상태** -- 복구는 사용자가 원할 때 본인 방식으로 `docker rm -f 983b0a026d7b && docker run ...` (`/workspace`는 bind mount라 데이터 안전) - ---- - -## 저장소 - -- **Git remote**: `http://192.168.10.110/TTA/kr_lp_pgnet.git` (사내 GitLab/Gitea) -- **HTTP 인증**: 서버에서 평소 git push/pull 정상 (사용자 설정됨) -- **브랜치**: `main`만 사용 -- **로컬 사용자 정보**: `hunsoo0823@naver.com` / `songhyeonsu` - -## wandb - -- **Entity**: `hssong_cuuva` (개인 계정) -- **Project**: `kr_lp_pgnet` -- **현재 본격 학습 run**: `step1-pretrain` (id `l0eqqbrb`) -- **dashboard**: https://wandb.ai/hssong_cuuva/kr_lp_pgnet -- **이 run 직접 URL**: https://wandb.ai/hssong_cuuva/kr_lp_pgnet/runs/l0eqqbrb -- **로그인**: 컨테이너 안 `/root/.netrc`에 저장됨 (`recreate_container.sh`가 자동 보존) - ---- - -## 디렉토리 구조 (이 repo) - -``` -kr_lp_pgnet/ -├── README.md -├── ONBOARDING.md # 이 문서 -├── configs/ -│ └── kr_lp_pgnet.yml # PGNet 학습 설정 (epoch 50, batch 16, pad_num 67) -├── dict/ -│ └── kr_lp_dict.txt # 문자 사전 67자 -├── data_gen/ -│ ├── README.md # 자산 라이센스 / 사용법 / 알려진 제약 -│ ├── setup_assets.sh # qjadud 자산 git clone -│ └── generate_synthetic.py # 합성기 (4 plate types, brightness, type weights) -├── scripts/ -│ ├── recreate_container.sh # 컨테이너 재생성 (shm 8g, gpus all) -│ ├── setup_server.sh # 컨테이너 안 환경 셋업 (idempotent) -│ └── run_step1.sh # Step1 학습 실행 -└── tools/ - └── region_check.py # REGION_MAP 시각 검증용 -``` - ---- - -## 진행 상태 (체크리스트) - -### ✅ 완료 -1. **환경 셋업** — repo, GitLab remote, 서버 컨테이너, paddle sm_120 wheel, cuDNN 9.17, PaddleOCR release/2.7 -2. **dict + config** — 67자 (숫자 10 + 자가용 32 + 영업용 4 + 렌터카 3 + 배달 1 + 지역명 17), `pad_num=67`, `max_text_length=10`, `valid_set=partvgg`, `infer_visual_type=CN` -3. **합성기** — 4 plate type (520×110 / 355×155 / 336×170×2), 한영자판 매핑, REGION_MAP(추정), 도로 분포 가중치 (Type1 80%/Type2 5%/Type3 10%/Type4 5%), random_bright -4. **wandb 연동** — Global.use_wandb=True + project=kr_lp_pgnet -5. **50k 합성 완료** — train 47500 / test 2500, type 분포 도로 현실 일치 - -### 🔄 진행 중 -- **Step1 pretrain 학습** — 50 epoch, batch 16, num_workers 8, 50k synthetic data - - 시작: 2026-05-08 07:58 - - ips 58~59 samples/s - - 진행: epoch 1/50 ~step 2110 (확인 시점 기준) - - eta: ~11시간 - - loss: 1234 → 63 (감소 추세 정상) - - 체크포인트 저장 경로: `/workspace/PaddleOCR/output/kr_lp_pgnet/{latest,best_accuracy}/` - -### 📋 다음 단계 -1. **Step1 완료 평가** — `eval f_score_e2e` 확인, 추론 결과 시각 검증 (synth test set + 임의 LP 이미지) -2. **Step2 fine-tune** — 실제 한국 LP 사진 데이터 수집·라벨링·fine-tune (자산이 못 만든 글자 보충: 하, 호, 배, 세종) -3. **ONNX export** — `paddle2onnx`로 변환 → 추론 검증 -4. **(선택) 더 강한 augmentation** — config에 IaaAugment 추가 (rotate/perspective/blur) -5. **(선택) REGION_MAP 정확 검증** — region_check_y/g 시각 확인 후 매핑 정정 - ---- - -## 자주 쓰는 운영 명령 - -### 학습 모니터링 -```bash -# 학습 프로세스 살아있는지 -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet pgrep -af tools/train.py | wc -l' - -# 학습 로그 (eval tqdm 줄 제외) -ssh cuuva@192.168.10.189 \ - 'docker exec kr_lp_pgnet bash -c "grep -v \"it/s\" /workspace/PaddleOCR/output/kr_lp_pgnet/run.log | tail -5"' - -# GPU 사용량 -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet nvidia-smi --query-gpu=memory.used,utilization.gpu --format=csv' -``` - -### 학습 끊김 대응 (NVML stale 등) -```bash -# 1. 컨테이너 재시작 (NVML 풀기) -ssh cuuva@192.168.10.189 'docker restart kr_lp_pgnet' - -# 2. 이어서 학습 (latest 체크포인트에서 재개) -ssh cuuva@192.168.10.189 'docker exec -d kr_lp_pgnet bash -c " -cd /workspace/PaddleOCR -nohup python3.10 tools/train.py -c configs/e2e/kr_lp_pgnet.yml \ - -o Global.checkpoints=./output/kr_lp_pgnet/latest \ - > output/kr_lp_pgnet/run.log 2>&1 & -"' -``` - -### 학습 중단 -```bash -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet pkill -f "tools/train.py"' -``` - -### 합성 추가 생성 -```bash -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet python3.10 \ - /workspace/kr_lp_pgnet/data_gen/generate_synthetic.py \ - --out_dir /workspace/train_data/kr_lp_synth_extra \ - --num 10000 --types 1,2,3,4 \ - --dict /workspace/kr_lp_pgnet/dict/kr_lp_dict.txt' -``` - -### 컨테이너 완전 재셋업 (드물게) -```bash -ssh cuuva@192.168.10.189 'bash ~/workspace/kr_lp_pgnet/scripts/recreate_container.sh' -``` - -### 파일 서버 재시작 -```bash -ssh cuuva@192.168.10.189 'docker restart kr_lp_http' -``` - ---- - -## 알려진 이슈 / 의사결정 기록 - -### 시스템 -- **NVML stale 재발 가능성**: 컨테이너 오래 돌면 `nvidia-smi`가 `Failed to initialize NVML` 에러. 호스트는 멀쩡, 컨테이너 재시작 한 번으로 풀림. 학습 시작 직전 한 번 재시작했으니 한동안은 안전할 가능성. -- **shm 부족 → DataLoader BUS error**: `--shm-size=8g` 필수 (해결됨). -- **OOM at batch 32**: PGNet 가변 input 사이즈가 peak에 32GB 초과. **batch 16 확정**. -- **cuDNN 9.17 강제**: paddle sm_120 wheel은 9.17로 빌드됐는데 paddle deps는 9.13 install. `pip install 'nvidia-cudnn-cu13>=9.17'`로 덮어쓰지 않으면 conv2d에서 `cublasLtCreate` 심볼 로드 실패 후 process abort. setup_server.sh에 반영됨. -- **paddle wheel 출처**: 비공식 [horhe-dvlp/paddlepaddle-sm120-wheels](https://github.com/horhe-dvlp/paddlepaddle-sm120-wheels) v3.3.0-dev (Python 3.10, CUDA 13.0). 공식은 sm_120 미지원. - -### 데이터 -- **자산 출처**: [qjadud1994/Korean-license-plate-Generator](https://github.com/qjadud1994/Korean-license-plate-Generator) (MIT). 폰트 대신 글자 PNG 사용 → 폰트 라이센스 회피. -- **자산이 만들 수 없는 글자 3개**: `하`, `호`, `배` — 합성 데이터에 안 등장. Step2 fine-tune의 실차 데이터로 보충 가정. -- **REGION_MAP 추정**: 자산 region PNG (A.jpg ~ P.jpg) → 한국 광역지자체 매핑은 일반 컨벤션 기반 추정값. `A='서울'` 한 개만 시각 검증됨. 나머지는 `tools/region_check.py` 실행 후 시각 확인하여 정정 필요. -- **세종 지역 빠짐**: 자산 region 16개라 17개 광역지자체 중 1개(추정 세종) 누락. -- **plate 배경 정확도**: 자가용은 정확, 영업용·전기차는 한국 표준과 약간 차이 (특히 전기차는 자산이 흰바탕+파란띠가 아니라 파란 두 줄). Step2 필수. - -### 합성 분포 (한국 도로 추정) -| Type | 형태 | 비율 | -|---|---|---| -| 1 | 신형 가로 1줄 (자가용 흰) | 80% | -| 2 | 구형 가로 1줄 (흰, 작음) | 5% | -| 3 | 두 줄 노랑 (영업용 구형) | 10% | -| 4 | 두 줄 파/녹 (친환경 추정) | 5% | - ---- - -## 학습 결과 평가 방법 (Step1 끝나면) - -```bash -# 1. wandb dashboard에서 eval/f_score_e2e 추이 확인 -# https://wandb.ai/hssong_cuuva/kr_lp_pgnet/runs/l0eqqbrb - -# 2. best_accuracy 체크포인트로 평가 (paddle 명시 평가) -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " -cd /workspace/PaddleOCR -python3.10 tools/eval.py -c configs/e2e/kr_lp_pgnet.yml \ - -o Global.checkpoints=./output/kr_lp_pgnet/best_accuracy -"' - -# 3. 임의 이미지 추론 -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " -cd /workspace/PaddleOCR -python3.10 tools/infer_e2e.py -c configs/e2e/kr_lp_pgnet.yml \ - -o Global.infer_img=./train_data/kr_lp_synth/test/images/000000.jpg \ - Global.pretrained_model=./output/kr_lp_pgnet/best_accuracy \ - Global.load_static_weights=False -"' -``` - -## ONNX export (Step2 끝난 후) -```bash -# inference model export -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " -cd /workspace/PaddleOCR -python3.10 tools/export_model.py -c configs/e2e/kr_lp_pgnet.yml \ - -o Global.pretrained_model=./output/kr_lp_pgnet/best_accuracy \ - Global.save_inference_dir=./inference/kr_lp_pgnet_infer -"' - -# paddle2onnx -ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " -python3.10 -m pip install paddle2onnx -paddle2onnx --model_dir /workspace/PaddleOCR/inference/kr_lp_pgnet_infer \ - --model_filename inference.pdmodel --params_filename inference.pdiparams \ - --save_file /workspace/kr_lp_pgnet/kr_lp_pgnet.onnx \ - --opset_version 13 -"' -``` - ---- - -## 메모리 (project + feedback) - -이 프로젝트 관련 사용자 기억은 Claude Code memory에 저장돼 있음: -- `project_kr_lp_pgnet.md` — 프로젝트 개요·분업 구조·아키텍처 -- `feedback_local_no_runtime.md` — 로컬 Mac은 코드 작성 전용, 실행 금지 - -이 두 메모리는 새 Claude Code 세션에서도 자동 로드됨 (메모리 디렉토리: `/Users/songhyeonsu/.claude/projects/-Users-songhyeonsu-Documents-GIT-cuuva-AI/memory/`). diff --git a/README.md b/README.md index 0f788d0..0271ec1 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,270 @@ -# kr_lp_pgnet +# kr_lp_pgnet — 프로젝트 핸드오프 -PaddleOCR PGNet 기반 한국 번호판(LP) end-to-end 검출 + OCR 학습 프로젝트. +한국 자동차 번호판 검출 + OCR을 위한 PaddleOCR PGNet 학습 프로젝트. -대상 번호판: 승용(흰), 영업용(노란), 전기차(파란 8자리), 화물·특수. +--- -## 디렉토리 구조 +## 30초 요약 + +- **목표**: PGNet 한 모델로 한국 LP 4종 (자가용/영업/전기/화물) 검출+인식 → ONNX export +- **현재 상태 (2026-05-08)**: Step1 pretrain **학습 중** (50 epoch, eta ~11시간, run id `l0eqqbrb`) +- **다음 단계**: 학습 완료 후 → Step2 fine-tune (실차 데이터) → ONNX export +- **운영 원칙**: 로컬 Mac은 코드 작성·git만, 모든 실행(학습·합성·검증)은 외부 GPU 서버에서 + +--- + +## 환경 + +### 1. 로컬 Mac (코드 작성 전용) +- 작업 디렉토리: `/Users/songhyeonsu/Documents/GIT/cuuva_AI/kr_lp_pgnet/` +- **금지사항** (메모리 `feedback_local_no_runtime.md`): + - Python 패키지 설치 (`pip install ...`) + - 외부 자산 git clone (qjadud 등) + - 합성기·학습·평가 실행 +- **허용**: 코드/yaml/sh 작성·수정, 우리 repo git commit/push + +### 2. 외부 GPU 서버 +- **SSH**: `ssh cuuva@192.168.10.189` (사내망 전용, key 인증) +- **호스트**: Ubuntu 25.10, RTX 5090 32GB, NVIDIA driver 590.48.01, CUDA 13.1 +- **레이아웃**: + ``` + /home/cuuva/workspace/ + ├── PaddleOCR/ # git clone release/2.7 + ├── kr_lp_pgnet/ # 이 repo (사내망 GitLab에서 clone) + ├── train_data/ + │ ├── kr_lp_synth/ # Step1 학습용 (50k, 본격) + │ ├── kr_lp_synth_v2/ # 400장 (dry-run용) + │ ├── kr_lp_synth_smoke/ # 40장 (smoke test) + │ ├── region_check_y/ # 영업용 region 16종 검증 + │ └── region_check_g/ # 친환경 region 16종 검증 + └── wheels/ + └── paddlepaddle_gpu-3.3.0.dev20251209-cp310-...whl # sm_120 wheel + ``` + +### 3. 학습 컨테이너 `kr_lp_pgnet` +- 베이스: `ubuntu:24.04` +- 옵션: `--gpus all --shm-size=8g --restart unless-stopped` +- bind mount: 호스트 `/home/cuuva/workspace` ↔ 컨테이너 `/workspace` +- 설치된 것: Python 3.10 (deadsnakes), paddlepaddle-gpu 3.3.0.dev (sm_120), cuDNN 9.17, numpy 1.26, opencv 4.10+, wandb 0.26, PaddleOCR + 의존성 +- 재셋업: `bash scripts/recreate_container.sh` (한 줄로 전부) + +### 4. 파일 서버 컨테이너 `kr_lp_http` +- 합성 결과 시각 확인용 +- URL: **http://192.168.10.189:8889/** +- 마운트: `/home/cuuva/workspace/train_data` (read-only) +- 시작 명령: + ```bash + docker run -d --name kr_lp_http -v /home/cuuva/workspace/train_data:/data:ro \ + -p 8889:8889 --restart unless-stopped python:3.11-slim \ + python3 -m http.server 8889 --bind 0.0.0.0 --directory /data + ``` + +### 5. 다른 컨테이너 `my-vision-container` (우리 일과 무관, 그대로 두기) +- 4주 전 시작, 8888 포트로 Jupyter 노출 +- 우리 paddle wheel 설치 중 cuda-bindings/nccl 충돌로 **torch import 깨진 상태** +- 복구는 사용자가 원할 때 본인 방식으로 `docker rm -f 983b0a026d7b && docker run ...` (`/workspace`는 bind mount라 데이터 안전) + +--- + +## 저장소 + +- **Git remote**: `http://192.168.10.110/TTA/kr_lp_pgnet.git` (사내 GitLab/Gitea) +- **HTTP 인증**: 서버에서 평소 git push/pull 정상 (사용자 설정됨) +- **브랜치**: `main`만 사용 +- **로컬 사용자 정보**: `hunsoo0823@naver.com` / `songhyeonsu` + +## wandb + +- **Entity**: `hssong_cuuva` (개인 계정) +- **Project**: `kr_lp_pgnet` +- **현재 본격 학습 run**: `step1-pretrain` (id `l0eqqbrb`) +- **dashboard**: https://wandb.ai/hssong_cuuva/kr_lp_pgnet +- **이 run 직접 URL**: https://wandb.ai/hssong_cuuva/kr_lp_pgnet/runs/l0eqqbrb +- **로그인**: 컨테이너 안 `/root/.netrc`에 저장됨 (`recreate_container.sh`가 자동 보존) + +--- + +## 디렉토리 구조 (이 repo) ``` kr_lp_pgnet/ -├── configs/ # PGNet 학습 config (.yml) -├── dict/ # 문자 사전 (kr_lp_dict.txt) -├── data_gen/ # 합성 LP 이미지 생성기 -├── scripts/ # 서버 셋업·학습 실행 셸 스크립트 -└── tools/ # 라벨 검증·시각화 등 보조 스크립트 +├── README.md +├── ONBOARDING.md # 이 문서 +├── configs/ +│ └── kr_lp_pgnet.yml # PGNet 학습 설정 (epoch 50, batch 16, pad_num 67) +├── dict/ +│ └── kr_lp_dict.txt # 문자 사전 67자 +├── data_gen/ +│ ├── README.md # 자산 라이센스 / 사용법 / 알려진 제약 +│ ├── setup_assets.sh # qjadud 자산 git clone +│ └── generate_synthetic.py # 합성기 (4 plate types, brightness, type weights) +├── scripts/ +│ ├── recreate_container.sh # 컨테이너 재생성 (shm 8g, gpus all) +│ ├── setup_server.sh # 컨테이너 안 환경 셋업 (idempotent) +│ └── run_step1.sh # Step1 학습 실행 +└── tools/ + └── region_check.py # REGION_MAP 시각 검증용 ``` -## 작업 분업 +--- + +## 진행 상태 (체크리스트) + +### ✅ 완료 +1. **환경 셋업** — repo, GitLab remote, 서버 컨테이너, paddle sm_120 wheel, cuDNN 9.17, PaddleOCR release/2.7 +2. **dict + config** — 67자 (숫자 10 + 자가용 32 + 영업용 4 + 렌터카 3 + 배달 1 + 지역명 17), `pad_num=67`, `max_text_length=10`, `valid_set=partvgg`, `infer_visual_type=CN` +3. **합성기** — 4 plate type (520×110 / 355×155 / 336×170×2), 한영자판 매핑, REGION_MAP(추정), 도로 분포 가중치 (Type1 80%/Type2 5%/Type3 10%/Type4 5%), random_bright +4. **wandb 연동** — Global.use_wandb=True + project=kr_lp_pgnet +5. **50k 합성 완료** — train 47500 / test 2500, type 분포 도로 현실 일치 + +### 🔄 진행 중 +- **Step1 pretrain 학습** — 50 epoch, batch 16, num_workers 8, 50k synthetic data + - 시작: 2026-05-08 07:58 + - ips 58~59 samples/s + - 진행: epoch 1/50 ~step 2110 (확인 시점 기준) + - eta: ~11시간 + - loss: 1234 → 63 (감소 추세 정상) + - 체크포인트 저장 경로: `/workspace/PaddleOCR/output/kr_lp_pgnet/{latest,best_accuracy}/` -- **로컬 (Mac)**: config·dict·생성기·run script 작성 및 디버깅 -- **원격 GPU 서버 (NVIDIA + CUDA)**: 합성 데이터 생성, 학습 실행 -- 동기화: 이 repo는 git push/pull, 데이터·체크포인트는 git에 올리지 않음 +### 📋 다음 단계 +1. **Step1 완료 평가** — `eval f_score_e2e` 확인, 추론 결과 시각 검증 (synth test set + 임의 LP 이미지) +2. **Step2 fine-tune** — 실제 한국 LP 사진 데이터 수집·라벨링·fine-tune (자산이 못 만든 글자 보충: 하, 호, 배, 세종) +3. **ONNX export** — `paddle2onnx`로 변환 → 추론 검증 +4. **(선택) 더 강한 augmentation** — config에 IaaAugment 추가 (rotate/perspective/blur) +5. **(선택) REGION_MAP 정확 검증** — region_check_y/g 시각 확인 후 매핑 정정 -## 서버 측 실행 순서 +--- + +## 자주 쓰는 운영 명령 + +### 학습 모니터링 +```bash +# 학습 프로세스 살아있는지 +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet pgrep -af tools/train.py | wc -l' + +# 학습 로그 (eval tqdm 줄 제외) +ssh cuuva@192.168.10.189 \ + 'docker exec kr_lp_pgnet bash -c "grep -v \"it/s\" /workspace/PaddleOCR/output/kr_lp_pgnet/run.log | tail -5"' + +# GPU 사용량 +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet nvidia-smi --query-gpu=memory.used,utilization.gpu --format=csv' +``` +### 학습 끊김 대응 (NVML stale 등) ```bash -# 1. 최초 1회: 환경 셋업 (Paddle 설치 + PaddleOCR clone + pretrain weight 다운로드) -bash scripts/setup_server.sh +# 1. 컨테이너 재시작 (NVML 풀기) +ssh cuuva@192.168.10.189 'docker restart kr_lp_pgnet' -# 2. 합성 데이터 생성 (수십만장) -python data_gen/generate_synthetic.py --out_dir ../train_data/kr_lp_synth --num 200000 +# 2. 이어서 학습 (latest 체크포인트에서 재개) +ssh cuuva@192.168.10.189 'docker exec -d kr_lp_pgnet bash -c " +cd /workspace/PaddleOCR +nohup python3.10 tools/train.py -c configs/e2e/kr_lp_pgnet.yml \ + -o Global.checkpoints=./output/kr_lp_pgnet/latest \ + > output/kr_lp_pgnet/run.log 2>&1 & +"' +``` + +### 학습 중단 +```bash +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet pkill -f "tools/train.py"' +``` -# 3. Step1: 합성 데이터로 pretrain -bash scripts/run_step1.sh +### 합성 추가 생성 +```bash +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet python3.10 \ + /workspace/kr_lp_pgnet/data_gen/generate_synthetic.py \ + --out_dir /workspace/train_data/kr_lp_synth_extra \ + --num 10000 --types 1,2,3,4 \ + --dict /workspace/kr_lp_pgnet/dict/kr_lp_dict.txt' +``` -# 4. Step2: 실제 LP 데이터로 fine-tune -bash scripts/run_step2.sh +### 컨테이너 완전 재셋업 (드물게) +```bash +ssh cuuva@192.168.10.189 'bash ~/workspace/kr_lp_pgnet/scripts/recreate_container.sh' +``` -# 5. 추론 모델로 export -bash scripts/export_inference.sh +### 파일 서버 재시작 +```bash +ssh cuuva@192.168.10.189 'docker restart kr_lp_http' ``` -## 디렉토리 가정 +--- + +## 알려진 이슈 / 의사결정 기록 + +### 시스템 +- **NVML stale 재발 가능성**: 컨테이너 오래 돌면 `nvidia-smi`가 `Failed to initialize NVML` 에러. 호스트는 멀쩡, 컨테이너 재시작 한 번으로 풀림. 학습 시작 직전 한 번 재시작했으니 한동안은 안전할 가능성. +- **shm 부족 → DataLoader BUS error**: `--shm-size=8g` 필수 (해결됨). +- **OOM at batch 32**: PGNet 가변 input 사이즈가 peak에 32GB 초과. **batch 16 확정**. +- **cuDNN 9.17 강제**: paddle sm_120 wheel은 9.17로 빌드됐는데 paddle deps는 9.13 install. `pip install 'nvidia-cudnn-cu13>=9.17'`로 덮어쓰지 않으면 conv2d에서 `cublasLtCreate` 심볼 로드 실패 후 process abort. setup_server.sh에 반영됨. +- **paddle wheel 출처**: 비공식 [horhe-dvlp/paddlepaddle-sm120-wheels](https://github.com/horhe-dvlp/paddlepaddle-sm120-wheels) v3.3.0-dev (Python 3.10, CUDA 13.0). 공식은 sm_120 미지원. + +### 데이터 +- **자산 출처**: [qjadud1994/Korean-license-plate-Generator](https://github.com/qjadud1994/Korean-license-plate-Generator) (MIT). 폰트 대신 글자 PNG 사용 → 폰트 라이센스 회피. +- **자산이 만들 수 없는 글자 3개**: `하`, `호`, `배` — 합성 데이터에 안 등장. Step2 fine-tune의 실차 데이터로 보충 가정. +- **REGION_MAP 추정**: 자산 region PNG (A.jpg ~ P.jpg) → 한국 광역지자체 매핑은 일반 컨벤션 기반 추정값. `A='서울'` 한 개만 시각 검증됨. 나머지는 `tools/region_check.py` 실행 후 시각 확인하여 정정 필요. +- **세종 지역 빠짐**: 자산 region 16개라 17개 광역지자체 중 1개(추정 세종) 누락. +- **plate 배경 정확도**: 자가용은 정확, 영업용·전기차는 한국 표준과 약간 차이 (특히 전기차는 자산이 흰바탕+파란띠가 아니라 파란 두 줄). Step2 필수. -서버에서는 다음 레이아웃을 가정: +### 합성 분포 (한국 도로 추정) +| Type | 형태 | 비율 | +|---|---|---| +| 1 | 신형 가로 1줄 (자가용 흰) | 80% | +| 2 | 구형 가로 1줄 (흰, 작음) | 5% | +| 3 | 두 줄 노랑 (영업용 구형) | 10% | +| 4 | 두 줄 파/녹 (친환경 추정) | 5% | +--- + +## 학습 결과 평가 방법 (Step1 끝나면) + +```bash +# 1. wandb dashboard에서 eval/f_score_e2e 추이 확인 +# https://wandb.ai/hssong_cuuva/kr_lp_pgnet/runs/l0eqqbrb + +# 2. best_accuracy 체크포인트로 평가 (paddle 명시 평가) +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " +cd /workspace/PaddleOCR +python3.10 tools/eval.py -c configs/e2e/kr_lp_pgnet.yml \ + -o Global.checkpoints=./output/kr_lp_pgnet/best_accuracy +"' + +# 3. 임의 이미지 추론 +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " +cd /workspace/PaddleOCR +python3.10 tools/infer_e2e.py -c configs/e2e/kr_lp_pgnet.yml \ + -o Global.infer_img=./train_data/kr_lp_synth/test/images/000000.jpg \ + Global.pretrained_model=./output/kr_lp_pgnet/best_accuracy \ + Global.load_static_weights=False +"' ``` -~/workspace/ -├── PaddleOCR/ # git clone PaddlePaddle/PaddleOCR -├── kr_lp_pgnet/ # 이 repo -└── train_data/ - ├── kr_lp_synth/ # 합성 데이터 (생성기 출력) - └── kr_lp_real/ # 실제 촬영 LP 데이터 + +## ONNX export (Step2 끝난 후) +```bash +# inference model export +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " +cd /workspace/PaddleOCR +python3.10 tools/export_model.py -c configs/e2e/kr_lp_pgnet.yml \ + -o Global.pretrained_model=./output/kr_lp_pgnet/best_accuracy \ + Global.save_inference_dir=./inference/kr_lp_pgnet_infer +"' + +# paddle2onnx +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet bash -c " +python3.10 -m pip install paddle2onnx +paddle2onnx --model_dir /workspace/PaddleOCR/inference/kr_lp_pgnet_infer \ + --model_filename inference.pdmodel --params_filename inference.pdiparams \ + --save_file /workspace/kr_lp_pgnet/kr_lp_pgnet.onnx \ + --opset_version 13 +"' ``` + +--- + +## 메모리 (project + feedback) + +이 프로젝트 관련 사용자 기억은 Claude Code memory에 저장돼 있음: +- `project_kr_lp_pgnet.md` — 프로젝트 개요·분업 구조·아키텍처 +- `feedback_local_no_runtime.md` — 로컬 Mac은 코드 작성 전용, 실행 금지 + +이 두 메모리는 새 Claude Code 세션에서도 자동 로드됨 (메모리 디렉토리: `/Users/songhyeonsu/.claude/projects/-Users-songhyeonsu-Documents-GIT-cuuva-AI/memory/`).