PaddleOCR 코드 문법 인식 모델 학습 메모
프로젝트 개요
PaddleOCR v5를 사용하여 코드 문법 이미지를 인식하는 OCR 모델을 학습하는 프로젝트입니다. Windows GPU 환경에서 실행되며, 한글과 영문 코드 문법을 포함한 텍스트 인식을 목표로 합니다.
1. 데이터셋 생성
1.1 사용 도구 및 모듈
- Python 3.12
- PIL (Pillow): 이미지 생성 및 처리
- NumPy: 이미지 배열 처리
- PaddleOCR: OCR 검증 (선택적)
1.2 데이터셋 생성 스크립트 구조
스크립트 위치: yuzyproject-aimodels/prepare_code_syntax_dataset.py
주요 구성 요소
코드 샘플 정의 (
CODE_SAMPLES)- Python 코드 문법 패턴 150개 이상
- 함수 정의, 클래스, 조건문, 반복문, 예외 처리, 주석 등 포함
- 한글 주석 및 문자열 포함
테마 설정 (
THEMES)- 다크 테마: 배경 (30,30,30), 텍스트 (200,200,200)
- 라이트 테마: 배경 (255,255,255), 텍스트 (0,0,0)
폰트 설정
- Windows 기본 폰트 사용: Consolas, Courier New, Lucida Console, MS Gothic
- 랜덤 폰트 크기: 12-18px
1.3 이미지 생성 프로세스
def generate_code_image(code_text, font_name, font_size, theme, width=2000, padding=50):
# 1. 텍스트 크기 계산 (정확한 측정)
# 2. 임시 이미지로 텍스트 영역 측정
# 3. 충분한 크기의 이미지 생성
# 4. 텍스트 그리기
# 5. 텍스트 영역 자동 크롭 (Auto-Crop)
# 6. 스마트 리사이징 (높이 48px 고정, 비율 유지)
# 7. 최종 패딩 (48x640으로 통일)
이미지 크기 처리 핵심 로직
초기 생성: 텍스트가 잘리지 않도록 충분한 크기로 생성
텍스트 영역 자동 크롭:
# NumPy 배열로 변환하여 텍스트 영역의 Bounding Box 찾기 img_array = np.array(img) bbox = find_text_bbox(img_array, bg_color) # 텍스트가 있는 영역만 추출 img_cropped = img.crop(bbox) # 불필요한 여백 제거스마트 리사이징:
# 높이를 48px로 고정하고 가로세로 비율 유지 target_height = 48 target_width = int(original_width * (target_height / original_height)) img_resized = img_cropped.resize((target_width, target_height), Image.LANCZOS)최종 패딩 (48x640 통일):
# 모든 이미지를 48x640 캔버스에 왼쪽 정렬하여 배치 final_canvas = Image.new("RGB", (640, 48), bg_color) final_canvas.paste(img_resized, (0, 0))
최종 이미지 크기: 48px (높이) x 640px (너비) - PaddleOCR 학습 요구사항
1.4 데이터셋 생성 실행
create_dataset(num_train=25000, num_val=5000, verify_with_ocr=False)
- 학습 데이터: 25,000개 이미지
- 검증 데이터: 5,000개 이미지
- 라벨 파일 형식:
이미지경로\t텍스트내용
생성된 파일 구조:
code_syntax_dataset/
├── train_images/
│ └── train_00000.jpg ~ train_02499.jpg
├── val_images/
│ └── val_00000.jpg ~ val_00499.jpg
├── train_list.txt
└── val_list.txt2. 학습 설정
2.1 설정 파일
위치: PaddleOCR/configs/rec/rec_code_syntax_finetune.yml
2.2 핵심 설정 항목
Global 설정
model_name: code_syntax_PP-OCRv5_rec
use_gpu: true
epoch_num: 100
character_dict_path: ./ppocr/utils/dict/ppocrv5_korean_dict.txt
max_text_length: 65 # 데이터셋 최대 길이(61) + 여유(4)
use_space_char: True
d2s_train_image_shape: [3, 48, 640] # [C, H, W] 형식
pretrained_model: https://paddle-model-ecology.bj.bcebos.com/paddlex/official_pretrained_model/korean_PP-OCRv5_mobile_rec_pretrained.pdparams
Architecture 설정
model_type: rec
algorithm: SVTR_LCNet
Backbone:
name: PPLCNetV3
scale: 0.9
Head:
name: MultiHead
head_list:
- CTCHead: # 구조상 필요 (MultiHead 최소 2개 요구)
- NRTRHead: # 실제 사용하는 Head
nrtr_dim: 384
max_text_length: 65
Loss 설정 (Windows 호환성 대응)
Loss:
name: MultiLoss
loss_config_list:
- NRTRLoss: # CTCLoss 제거 (warp-ctc Windows 호환성 문제)
PostProcess 설정
PostProcess:
name: NRTRLabelDecode # NRTR 전용 디코더
character_dict_path: ./ppocr/utils/dict/ppocrv5_korean_dict.txt
use_space_char: True
Optimizer 설정
Optimizer:
name: Adam
lr:
learning_rate: 0.0008 # 0.0005에서 상향 조정
name: Cosine # Linear에서 변경
warmup_epoch: 5 # 2에서 증가
데이터셋 설정
Train:
dataset:
name: SimpleDataSet
data_dir: ../yuzyproject-aimodels/code_syntax_dataset/
label_file_list: ["../yuzyproject-aimodels/code_syntax_dataset/train_list.txt"]
transforms:
- DecodeImage:
img_mode: BGR
channel_first: False
- RecAug: # 데이터 증강
- MultiLabelEncode:
gtc_encode: NRTRLabelEncode
- RecResizeImg:
image_shape: [3, 48, 640] # [C, H, W] 형식
keep_ratio: True
padding: True
- KeepKeys:
keep_keys:
- image
- label_ctc
- label_gtc
- length
- valid_ratio
loader:
batch_size_per_card: 16
shuffle: True
num_workers: 4
2.3 학습 실행
cd PaddleOCR
call ..\yuzyproject-aimodels\venv_ocr\Scripts\activate.bat
python tools\train.py -c configs\rec\rec_code_syntax_finetune.yml
3. 트러블슈팅
3.1 오류 1: warp-ctc RuntimeError
오류 메시지:
RuntimeError: (PreconditionNotMet) warp-ctc [version 2] Error in get_workspace_size: execution failed원인:
- Windows GPU 환경에서 warp-ctc 라이브러리 호환성 문제
- CTCLoss가 내부적으로 warp-ctc를 사용하는데 Windows에서 작동하지 않음
해결 방법:
- Loss 설정에서 CTCLoss 제거, NRTRLoss만 사용
- Architecture의 CTCHead는 구조상 유지 (MultiHead가 최소 2개 head를 요구)
- PostProcess를 NRTRLabelDecode로 변경
수정 내용:
# Before
Loss:
loss_config_list:
- CTCLoss:
- NRTRLoss:
PostProcess:
name: CTCLabelDecode
# After
Loss:
loss_config_list:
- NRTRLoss: # CTCLoss 제거
PostProcess:
name: NRTRLabelDecode # 변경
3.2 오류 2: MultiHead AssertionError
오류 메시지:
File "ppocr/modeling/heads/rec_multi_head.py", line 77, in __init__
assert len(self.head_list) >= 2
AssertionError원인:
- MultiHead 클래스는 최소 2개의 head를 요구하는 assertion이 있음
- NRTRHead만 남겨두면 assertion 에러 발생
해결 방법:
- CTCHead는 Architecture에 유지 (구조상 필요)
- Loss에서는 CTCLoss를 사용하지 않으므로 warp-ctc 오류는 발생하지 않음
- 실제 학습에는 NRTRHead와 NRTRLoss만 사용됨
최종 구조:
Architecture:
Head:
name: MultiHead
head_list:
- CTCHead: # 구조상 필요 (실제 사용 안 함)
- NRTRHead: # 실제 사용
Loss:
loss_config_list:
- NRTRLoss: # CTCLoss 제거
3.3 오류 3: 사전 학습 모델 Shape Mismatch
경고 메시지:
WARNING: The shape of model params head.ctc_encoder.encoder.conv2.conv.weight [120, 58, 1, 1]
not matched with loaded params [120, 60, 1, 1]원인:
- 사전 학습 모델의 문자 집합 크기와 현재 설정의 문자 집합 크기가 다름
- 사전 학습 모델: 60차원
- 현재 모델: 58차원
해결 방법:
- 경고는 무시 가능 (일치하는 부분만 로드되고 나머지는 랜덤 초기화)
- 학습에는 문제 없음 (새로운 문자 집합에 맞춰 학습됨)
3.4 이미지 크기 처리
요구사항:
- PaddleOCR 학습용 이미지 크기: [3, 48, 640] (채널, 높이, 너비)
처리 방법:
- 텍스트 영역 자동 크롭 (NumPy 배열로 Bounding Box 찾기)
- 높이 48px로 리사이징 (비율 유지)
- 48x640 캔버스에 왼쪽 정렬하여 패딩
핵심 함수:
def find_text_bbox(img_array, bg_color):
# 배경색이 아닌 픽셀 찾기
# 텍스트 영역의 좌표 계산
return (left, top, right, bottom)
4. 학습 모니터링
4.1 주요 메트릭
- acc: 정확도 (Accuracy)
- norm_edit_dis: 정규화된 편집 거리 (Normalized Edit Distance)
- NRTRLoss: NRTR Loss 값
- lr: 현재 학습률
4.2 로그 확인
# 학습 로그 확인
tail -f PaddleOCR/output/rec/code_syntax/train.log
# 최근 학습 상태 확인
powershell -Command "Get-Content PaddleOCR\output\rec\code_syntax\train.log -Tail 30"
4.3 체크포인트 저장
- 주기:
save_epoch_step: 10(10 epoch마다 저장) - 위치:
PaddleOCR/output/rec/code_syntax/ - 파일 형식:
iter_epoch_10.pdparams,iter_epoch_10.pdopt,iter_epoch_10.statesbest_accuracy.pdparams(최고 성능 모델)latest.pdparams(가장 최근 모델)
5. 사용된 주요 모듈 및 도구
5.1 데이터셋 생성
- PIL (Pillow): 이미지 생성 및 처리
Image.new(): 새 이미지 생성ImageDraw.Draw(): 텍스트 그리기ImageFont.truetype(): 폰트 로드Image.resize(): 이미지 리사이징Image.crop(): 이미지 크롭
- NumPy: 배열 처리 및 Bounding Box 계산
- Pathlib: 파일 경로 처리
5.2 학습
- PaddlePaddle: 딥러닝 프레임워크
- PaddleOCR: OCR 모델 및 학습 도구
- PyYAML: 설정 파일 파싱
5.3 환경
- Python 3.12
- Windows GPU (CUDA)
- 가상환경: venv_ocr
6. 학습 설정 최적화 사항
6.1 하이퍼파라미터 조정
max_text_length: 80 → 65
- 데이터셋 최대 라벨 길이(61)를 고려하여 조정
- 불필요한 패딩 감소
learning_rate: 0.0005 → 0.0008
- 학습률 상향 조정으로 학습 속도 개선
LR Scheduler: Linear → Cosine
- Cosine 스케줄러로 더 부드러운 학습률 감소
warmup_epoch: 2 → 5
- 학습 초반 안정성 향상
6.2 아키텍처 설정
- Backbone: PPLCNetV3 (scale: 0.9) - 메모리 사용량 감소
- Mixed Precision Training: use_amp: true, amp_level: O1
- Batch Size: 16 (GPU 메모리 고려)
7. 데이터셋 통계
- 학습 데이터: 25,000개 이미지
- 검증 데이터: 5,000개 이미지
- 코드 샘플 종류: 150개 이상
- 라벨 길이 범위: 1~61자
- 이미지 크기: 48px (높이) x 640px (너비)
- 이미지 형식: JPEG (quality: 95)
8. 학습 시작 전 체크리스트
데이터셋 생성 완료 확인
code_syntax_dataset/train_images/폴더에 25,000개 이미지 확인code_syntax_dataset/val_images/폴더에 5,000개 이미지 확인train_list.txt,val_list.txt파일 확인
설정 파일 검증
- YAML 문법 오류 확인
- 경로 설정 확인
- 이미지 크기 설정 확인: [3, 48, 640]
이전 체크포인트 정리 (필요 시)
- 구조 변경 시 기존 체크포인트 삭제
output/rec/code_syntax/*.pdparams,*.pdopt,*.states삭제
GPU 메모리 확인
- GPU 사용 가능 여부 확인
- 충분한 메모리 확인 (약 6-7GB 필요)
9. 참고 사항
9.1 Windows 환경 제약사항
- warp-ctc 호환성: Windows GPU 환경에서 CTCLoss 사용 불가
- 해결책: NRTRLoss만 사용하는 구조로 변경
9.2 MultiHead 구조 제약
- MultiHead는 최소 2개의 head를 요구
- CTCHead는 구조상 유지하되 Loss에서는 사용하지 않음
- 실제 학습에는 NRTRHead + NRTRLoss만 사용
9.3 이미지 전처리 파이프라인
- DecodeImage: 이미지 디코딩 (BGR 형식, channel_first: False)
- RecAug: 데이터 증강
- MultiLabelEncode: 라벨 인코딩 (NRTRLabelEncode)
- RecResizeImg: 이미지 리사이즈 및 정규화 ([3, 48, 640])
- KeepKeys: 필요한 키만 유지
9.4 학습 명령어
# 가상환경 활성화
call ..\yuzyproject-aimodels\venv_ocr\Scripts\activate.bat
# 학습 시작
python tools\train.py -c configs\rec\rec_code_syntax_finetune.yml
# 또는 배치 파일 사용
..\yuzyproject-aimodels\start_training_clean.bat
10. 향후 개선 사항
Loss 정체 문제 해결
- 현재 Loss가 특정 값에서 정체되는 현상 관찰
- 학습률 스케줄러 조정 필요 가능성
Accuracy 0.0 문제
- 초기 학습 단계에서 Accuracy가 0.0으로 표시되는 문제
- norm_edit_dis는 정상적으로 감소하는 것으로 보아 학습은 진행 중
데이터셋 확장
- 더 다양한 코드 패턴 추가
- 다양한 폰트 및 테마 조합 확대
하이퍼파라미터 튜닝
- Learning rate 스케줄러 최적화
- Batch size 조정
- Warmup epoch 조정
작성일: 2026-01-01
프로젝트 경로: C:\Pyg\Projects\semi
PaddleOCR 버전: v5
Python 버전: 3.12
OS: Windows 11
GPU: RTX 5060
'3. 자습 & 메모(실전, 실습, 프로젝트) > 3-2 메모(실전, 프로젝트)' 카테고리의 다른 글
| [PaddleOCR] 학습용 REC 데이터셋 생성 스크립트(업데이트 버전) (0) | 2026.01.04 |
|---|---|
| [PaddleOCR] 학습용 REC 데이터셋 생성 스크립트 (0) | 2026.01.02 |
| [MEMO] 학습 데이터셋 정제 작업 메모 (0) | 2025.12.31 |
| [파인 튜닝] PaddleOCR 성능 분석 및 체크포인트 (0) | 2025.12.30 |
| [파인 튜닝] PaddleOCR Detection 모델 학습 가이드 (1) | 2025.12.30 |