From 7c5861909882144f29aa815a5b9d7e6930beea0d Mon Sep 17 00:00:00 2001 From: songhyeonsu Date: Wed, 13 May 2026 17:32:31 +0900 Subject: [PATCH] Add ONBOARDING.md for project handoff Captures the current state (Step1 training in progress), three-tier environment (Mac/server/container), git+wandb endpoints, operational commands, and known issues so a fresh agent or workstation can pick up the work without re-deriving context. Co-Authored-By: Claude Opus 4.7 --- ONBOARDING.md | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 ONBOARDING.md diff --git a/ONBOARDING.md b/ONBOARDING.md new file mode 100644 index 0000000..0271ec1 --- /dev/null +++ b/ONBOARDING.md @@ -0,0 +1,270 @@ +# 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/`).