You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
songhyeonsoo 3657318d47
docs: merge ONBOARDING into README, remove duplicate
4 weeks ago
configs fix: lower lr 0.001→0.0001, warmup 5→15, epoch 100→200; add 하/호/배 to HANGUL_CHAR_MAP 1 month ago
data_gen fix: tight polygon 라벨 + eval GT mat 생성 파이프라인 추가 1 month ago
dict Add Korean LP dictionary and PGNet config 1 month ago
scripts run_step1: add timestamp to output dir and wandb run name, reset synth data on each run 4 weeks ago
tools fix: tight polygon 라벨 + eval GT mat 생성 파이프라인 추가 1 month ago
.gitignore Add data_gen/setup_assets.sh for synthetic LP assets 1 month ago
README.md docs: merge ONBOARDING into README, remove duplicate 4 weeks ago

README.md

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)
  • 시작 명령:
    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


디렉토리 구조 (이 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 exportpaddle2onnx로 변환 → 추론 검증
  4. (선택) 더 강한 augmentation — config에 IaaAugment 추가 (rotate/perspective/blur)
  5. (선택) REGION_MAP 정확 검증 — region_check_y/g 시각 확인 후 매핑 정정

자주 쓰는 운영 명령

학습 모니터링

# 학습 프로세스 살아있는지
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 등)

# 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 &
"'

학습 중단

ssh cuuva@192.168.10.189 'docker exec kr_lp_pgnet pkill -f "tools/train.py"'

합성 추가 생성

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'

컨테이너 완전 재셋업 (드물게)

ssh cuuva@192.168.10.189 'bash ~/workspace/kr_lp_pgnet/scripts/recreate_container.sh'

파일 서버 재시작

ssh cuuva@192.168.10.189 'docker restart kr_lp_http'

알려진 이슈 / 의사결정 기록

시스템

  • NVML stale 재발 가능성: 컨테이너 오래 돌면 nvidia-smiFailed 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 v3.3.0-dev (Python 3.10, CUDA 13.0). 공식은 sm_120 미지원.

데이터

  • 자산 출처: 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 끝나면)

# 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 끝난 후)

# 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/).