5.9 KiB
5.9 KiB
RO-BEING OCR 스킬 구현 제안 (무료·로컬 → 자체 호스팅 → 상용)
- 작성일: 2025-09-09
- 목적: 비용/효율 최적화 관점에서 RO-BEING에 맞는 OCR 스킬을 단계적으로 설계·배포
- 원칙: 무료·로컬 우선 → 자체 호스팅 → 최고 성능 상용 API, HTTP API만 사용(직접 import 금지), 스킬은 독립 컨테이너(포트 8501–8599)
0) 목표와 기준
- 정확도: 문서 OCR CER/WER 낮춤, 표/키밸류 구조 복원 정확도↑
- 지연/처리량: A4 300–400DPI 기준 실사용 가능 지연(ms/페이지) 확보
- 비용: 로컬 무료 우선, 필요 시 온프레미스/상용 단계적 도입
- 보안/데이터경계: 업로드는 사내 스토리지(
/mnt/hdd/uploads/), PII 외부 반출 금지 - 운영 표준:
/healthz헬스체크 일관화(main.py/Dockerfile/compose/workflows), 로그 30일 롤링(/mnt/hdd/logs/)
1) 아키텍처 개요
- 흐름: 업로드 → (PDF/이미지 분기) → skill-ocr HTTP 호출 → 텍스트/블록/메타 → RAG(ChromaDB) 저장 → 응답
- 컴포넌트
- rb*: 클라이언트 요청 처리, 파일 유형 판별, skill-ocr 호출만 담당
- skill-ocr(8506): OCR 파이프라인 수행(PDF: OCRmyPDF, 이미지: PaddleOCR 등)
- Storage:
/mnt/hdd/uploads/{user_id}/, 로그/mnt/hdd/logs/skill-ocr/ - Vector DB: ChromaDB(텍스트 조각) + PostgreSQL(메타)
2) 1단계 — MVP(즉시)
- PDF: OCRmyPDF + Tesseract 5(kor+eng)
- 장점: 자동 전처리(회전/디스큐/노이즈), 검색가능 PDF 생성, 안정/단순
- 권장 옵션:
--rotate-pages --deskew --optimize 3 --jobs N
- 이미지/모바일: PaddleOCR(PP-OCR 계열, det+cls+rec_korean)
- 장점: CPU에서도 빠름, 한글 정확도 우수, 다국어·경량 모델 제공
- API 스펙(초안)
- POST
/ocr/pdf→ req:{ path, langs:["kor","eng"], optimize:3, rotate:true, deskew:true }- resp:
{ pdf_path_searchable, full_text, pages:[{text,conf}], conf_stats, meta{engine,version,latency_ms} }
- resp:
- POST
/ocr/image→ req:{ path, langs, det:"DB", rec:"PP-OCRv4", use_cls:true }- resp:
{ blocks:[{bbox,text,conf}], full_text, meta{engine,version,latency_ms} }
- resp:
- GET
/healthz→{ status:"ok", version, models }
- POST
- rb 연동(rag.py)
- 파일 확장자로 분기(PDF/이미지) → skill-ocr HTTP 호출 → 결과 텍스트/블록/메타를 RAG 파이프라인에 전달
- 실패 시 재시도 및 폴백 규칙: PDF 파서 실패→OCR 모드, 저신뢰(conf<阈值) 경고 로그
- 운영
- 로그 표준: DEBUG(사전처리/모델) / WARN(저신뢰) / ERROR(폴백) 예시 메시지 규격화
- 저장: 생성된 검색가능 PDF는 원본과 함께 사용자 폴더에 보관
3) 2단계 — 고도화(1–2개월)
- Donut(문서 파싱, OCR-free)
- 대상: 영수증/인보이스/계약서 등 정형 문서 → JSON 직접 추출
- 데이터: 도메인별 1–2k 샘플 파인튜닝, 지표 CER/WER + 필드 정확도(F1)
- API: POST
/parse/donut→{ path, schema }→{ fields... , meta }
- TrOCR small(텍스트 라인 고정밀)
- 대상: 서명란/단일행/중요 구획의 라인 인식 정밀도 향상
- API: POST
/recognize/line→{ image_crops:[...], lang }→{ lines:[{text,conf}], meta }
- 구조
- skill-ocr 내 모듈 확장 혹은
skill-ocr-parse로 분리(부하/배포 단위 고려)
- skill-ocr 내 모듈 확장 혹은
4) 3단계 — 선택적 확장
- 복잡 레이아웃/표: MMOCR 풀스택(table/layout) 또는
table-transformers/pdfplumber병행 - 상용 API(정확도 최우선)
- Google Document AI / Azure Document Intelligence / AWS Textract 비교 후 선택
- 의사결정 기준: 표/키밸류 정밀도, 손글씨, 지연·비용, 보안요구
- 가격은 최신 공식 가격표 기준으로 산정(시점에 따라 변동)
5) 평가·모니터링
- 데이터셋: 사내 샘플
- 스캔 문서 200–500쪽(ko/en 혼합), 모바일 영수증 200장, 필기 메모 100장
- 지표
- 문자: CER/WER
- 필드: 필드 정확도/재현/정밀(F1)
- 표: 셀 매핑/구조 F1
- 운영: 페이지당 지연(ms), 처리량(pages/min), 실패율, 저신뢰 비율, 리소스(GPU/메모리)
- 관측/로그
/healthz응답에 로드/모델 버전 포함- 로그는
/mnt/hdd/logs/skill-ocr/30일 롤링, 샘플:Fallback to OCR,OCR quality low: confidence=0.72
6) 배포 가이드(요약)
- 컨테이너:
skill-ocr(8506)- 볼륨:
-v /mnt/hdd/uploads:/mnt/hdd/uploads:ro,-v /mnt/hdd/logs/skill-ocr:/logs - 환경:
LANGS=kor,eng,THREADS=N,USE_GPU=false|true - 헬스체크:
GET /healthz(main.py/Dockerfile/compose/workflows 동기화)
- 볼륨:
- rb 연동: rb10508_micro에서 선검증 → rb8001 반영, Nginx 프록시 규칙 준수(proxy_pass 끝에
/)
7) 리스크 & 폴백
- Tesseract 품질 한계: 저해상도/왜곡/필기체에서 오류↑ → PaddleOCR/TrOCR/Donut로 보완
- 긴 PDF 처리시간: 페이지 병렬화(
--jobs N), 타임아웃/재시도 정책 설정 - 다국어 혼합: kor+eng 모델, 도메인 사전 기반 후처리(기업명/약어 교정)
- GPU 리소스: 배치 사이즈/혼잡 제어, CPU 폴백 경로 확보
8) 단계별 To-Do(요약)
- 1단계(MVP)
- skill-ocr API
/ocr/pdf,/ocr/image,/healthz스펙 고정 - rb10508_micro 연동(파일 분기, 폴백/에러 처리, 로그 규격)
- 지표 수집(CER/WER, 지연) 대시보드 기초
- skill-ocr API
- 2단계(고도화)
- Donut 파인튜닝 데이터셋 구성/평가 루프
- TrOCR 라인 인식기 통합(세그먼트 추출 포함)
- 3단계(확장)
- MMOCR/표 복원 실험
- 상용 API PoC 및 비용/정확도 비교
9) 참고(근거 자료)
- OCRmyPDF + Tesseract: ocrmypdf.readthedocs.io
- PaddleOCR 비교/리뷰: koncile.ai, modal.com 블로그
- 프레임워크 비교: Medium 리뷰(docTR/MMOCR/EasyOCR 등)
- TrOCR: Hugging Face 문서, AAAI 논문
- Donut: GitHub, arXiv, 산업 적용 리뷰
- Kraken/Calamari: GitHub, 공식 문서