From 3275edb32b93ca9100fbf601b53102300fc4b9ec Mon Sep 17 00:00:00 2001 From: songhyeonsoo Date: Mon, 18 May 2026 11:20:23 +0900 Subject: [PATCH] docs: separate README (public) and ONBOARDING (Claude handoff) Co-Authored-By: Claude Sonnet 4.6 --- ONBOARDING.md | 135 +++++++++++++++++++++++++ README.md | 275 ++++---------------------------------------------- 2 files changed, 154 insertions(+), 256 deletions(-) create mode 100644 ONBOARDING.md diff --git a/ONBOARDING.md b/ONBOARDING.md new file mode 100644 index 0000000..0694e43 --- /dev/null +++ b/ONBOARDING.md @@ -0,0 +1,135 @@ +# kr_lp_pgnet — 핸드오프 (Claude 전용) + +한국 자동차 번호판 검출 + OCR을 위한 PaddleOCR PGNet 학습 프로젝트. + +--- + +## 30초 요약 + +- **목표**: PGNet 한 모델로 한국 LP 4종 (자가용/영업/전기/화물) 검출+인식 → ONNX export +- **현재 상태 (2026-05-18)**: Step1 학습 재시작 중 (run `step1-20260518_0216`, 200 epoch) +- **왜 재시작**: 기존 학습 데이터 라벨이 판 전체 box → tight word-level box로 수정 후 재생성 +- **다음 단계**: 학습 완료 후 → eval f_score_e2e 확인 → Step2 fine-tune (실차 데이터) +- **운영 원칙**: 로컬 Mac은 코드 작성·git만, 모든 실행은 외부 GPU 서버에서 + +--- + +## 환경 + +### 1. 로컬 Mac (코드 작성 전용) +- 작업 디렉토리: `/Users/songhyeonsu/Documents/GIT/cuuva_AI/kr_lp_pgnet/` +- **금지**: pip install, 외부 자산 clone, 합성기·학습·평가 실행 +- **허용**: 코드/yaml/sh 작성·수정, git commit/push + +### 2. 외부 GPU 서버 +- **SSH**: `ssh cuuva@192.168.10.189` (사내망 전용) +- **호스트**: 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 + ├── train_data/ + │ ├── kr_lp_synth/ # Step1 학습용 (50k, tight box 라벨) + │ ├── region_check_y/ # 영업용 region 16종 검증 + │ └── region_check_g/ # 친환경 region 16종 검증 + └── wheels/ + └── paddlepaddle_gpu-3.3.0.dev20251209-cp310-...whl + ``` + +### 3. 학습 컨테이너 `kr_lp_pgnet` +- 베이스: `ubuntu:24.04` +- 옵션: `--gpus all --shm-size=8g --restart unless-stopped` +- bind mount: 호스트 `/home/cuuva/workspace` ↔ 컨테이너 `/workspace` +- 재셋업: `bash scripts/recreate_container.sh` + +### 4. 파일 서버 컨테이너 `kr_lp_http` +- 합성 결과 시각 확인용: **http://192.168.10.189:8889/** +- 마운트: `/home/cuuva/workspace/train_data` (read-only) + +--- + +## 저장소 + +- **Git remote**: `http://192.168.10.110/TTA/kr_lp_pgnet.git` (사내 Gitea) +- **브랜치**: `main`만 사용 + +## wandb + +- **Entity**: `hssong_cuuva` / **Project**: `kr_lp_pgnet` +- **현재 run**: `step1-20260518_0216` +- **dashboard**: https://wandb.ai/hssong_cuuva/kr_lp_pgnet + +--- + +## 핵심 이슈 히스토리 + +### 라벨 박스 문제 (2026-05-18 수정) +기존 학습 데이터(`kr_lp_synth`)의 라벨 박스가 판 전체 영역이었음: +``` +수정 전: "points": [[0,0],[520,0],[520,110],[0,110]] ← 판 전체 +수정 후: "points": [[35,13],[467,96],...] ← 글자 행만 +``` +결과: 100 epoch 학습해도 f_score_e2e ≈ 0 (hit_str_count 32/2867). +원인: training은 라벨과 직접 비교하므로 loss가 내려갔지만, 추론 시 post-processing이 +판 전체 heat map을 받아 박스를 쪼개거나 이상하게 복원 → 인식 실패. +`generate_synthetic.py`의 tight polygon 생성 코드는 이미 수정되어 있었으나 +서버 데이터가 구버전으로 생성된 상태였음. 데이터 재생성 후 재학습. + +### NVML stale (재발 가능) +컨테이너 장시간 실행 후 `nvidia-smi` 에러. `docker restart kr_lp_pgnet`으로 해결. + +### OOM +batch 32 → OOM. **batch 16 확정**. + +### cuDNN 9.17 강제 +paddle sm_120 wheel은 cuDNN 9.17 빌드. `setup_server.sh`에서 `nvidia-cudnn-cu13>=9.17` 강제 설치. + +--- + +## 자주 쓰는 운영 명령 + +```bash +# 학습 로그 확인 +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet sh -c "tail -5 /workspace/PaddleOCR/output/kr_lp_pgnet_*/run.log"' + +# GPU 사용량 +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet nvidia-smi --query-gpu=memory.used,utilization.gpu --format=csv' + +# 학습 중단 +ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet pkill -f tools/train.py' + +# 컨테이너 재시작 (NVML 풀기) +ssh cuuva@192.168.10.189 'docker restart kr_lp_pgnet' + +# 재학습 (처음부터) +ssh cuuva@192.168.10.189 'docker exec -d kr_lp_pgnet bash /workspace/kr_lp_pgnet/scripts/run_step1.sh' +``` + +--- + +## 데이터 관련 알려진 이슈 + +- **자산이 만들 수 없는 글자**: `하`, `호`, `배` — Step2 실차 데이터로 보충 +- **REGION_MAP 추정값**: `A='서울'`만 검증, 나머지는 `tools/region_check.py`로 확인 필요 +- **세종 누락**: 자산 region 16개, 실제 광역지자체 17개 (세종 미포함) + +--- + +## 진행 상태 + +### ✅ 완료 +1. 환경 셋업 (컨테이너, paddle sm_120, cuDNN 9.17, PaddleOCR release/2.7) +2. dict 67자 + config (pad_num=67, max_text_length=10, valid_set=partvgg) +3. 합성기 4 plate type + tight word-level polygon 라벨 +4. wandb 연동 +5. make_gt_mat.py (eval GT 생성) +6. run_step1.sh 타임스탬프 기반 output 관리 + +### 🔄 진행 중 +- Step1 학습 (run `step1-20260518_0216`, 200 epoch, 50k tight-box 데이터) + +### 📋 다음 단계 +1. Step1 완료 후 f_score_e2e 확인 (이전 0.0007 → 대폭 개선 기대) +2. Step2 fine-tune — 실차 한국 LP 사진 수집·라벨링 +3. ONNX export diff --git a/README.md b/README.md index 0271ec1..f571871 100644 --- a/README.md +++ b/README.md @@ -1,270 +1,33 @@ -# kr_lp_pgnet — 프로젝트 핸드오프 +# kr_lp_pgnet -한국 자동차 번호판 검출 + OCR을 위한 PaddleOCR PGNet 학습 프로젝트. +PaddleOCR PGNet 기반 한국 번호판(LP) end-to-end 검출 + OCR 학습 프로젝트. ---- +대상 번호판: 승용(흰), 영업용(노란), 전기차(파란 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/ -├── 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' +├── configs/ # PGNet 학습 config (.yml) +├── dict/ # 문자 사전 (kr_lp_dict.txt) +├── data_gen/ # 합성 LP 이미지 생성기 +├── scripts/ # 서버 셋업·학습 실행 셸 스크립트 +└── tools/ # 라벨 검증·시각화 등 보조 스크립트 ``` ---- - -## 알려진 이슈 / 의사결정 기록 - -### 시스템 -- **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 +# 1. 최초 1회: 환경 셋업 +docker exec kr_lp_pgnet bash scripts/setup_server.sh -# 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 -"' +# 2. Step1: 합성 데이터 생성 + 학습 +docker exec -d kr_lp_pgnet bash scripts/run_step1.sh ``` -## 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/`). +- NVIDIA GPU (RTX 4090 이상 권장) +- CUDA 12+ +- Python 3.10 +- PaddlePaddle GPU