import torch import os from pathlib import Path # 학습 및 추론 페이지 PDF_MAX_PAGES = 10 SERVICE = "ucar" # ── 인증 ────────────────────────────────────────── SERVICE_ACCOUNT_FILE = "ocrlogin-431508-8db9e68e7a47.json" # ── 경로 ────────────────────────────────────────── BASE_DIR = Path(__file__).parent FILES_DIR = BASE_DIR / "files" DATA_DIR = FILES_DIR / "data" / SERVICE MODEL_BASE_PATH = FILES_DIR / "models" / SERVICE MODEL_SAVE_PATH = MODEL_BASE_PATH CLASSIFIER_MODEL_BASE_PATH = FILES_DIR / "classifier_models" / SERVICE OCR_CACHE_DIR = FILES_DIR / "json" / SERVICE REPLAY_BUFFER_FILE= MODEL_BASE_PATH / "replay_buffer.json" LOG_DIR = BASE_DIR / "logs" TMP_DIR = FILES_DIR / "tmp" # ── Classifier ──────────────────────────────────── CLASSIFIER_JSON_DIR = OCR_CACHE_DIR # files/json/{SERVICE} CLASSIFIER_CACHE_PATH = CLASSIFIER_MODEL_BASE_PATH / "classifier_dataset.pkl" if SERVICE == "ucar": CLASSIFIER_MIN_WORDS = 5 else: CLASSIFIER_MIN_WORDS = 20 # 폴더 자동 생성 for d in [DATA_DIR, MODEL_SAVE_PATH, LOG_DIR, OCR_CACHE_DIR, TMP_DIR, CLASSIFIER_MODEL_BASE_PATH]: d.mkdir(parents=True, exist_ok=True) # ── 모델 ────────────────────────────────────────── MODEL_NAME = "microsoft/layoutlmv3-base" MAX_LEN = 512 BATCH_SIZE = 4 EPOCHS = 10 LR = 1e-5 DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") # ── OCR ─────────────────────────────────────────── # 단어 수 미달 페이지 제외 기준 OCR_MIN_WORDS = CLASSIFIER_MIN_WORDS OCR_ENGINE = "paddle" # "google" | "paddle" if SERVICE == "ucar": PADDLE_OCR_URL = "http://localhost:10930/run_ocr" else: PADDLE_OCR_URL = "http://localhost:10931/run_ocr" OCR_DPI = 150 OCR_MAX_WORKERS = 8 OCR_CONF_THRESH = 0.7 # PaddleOCR 신뢰도 임계값 (Google Vision은 미사용) PDF_IMAGE_FORMAT = "jpeg" # "png" | "jpeg" PDF_JPEG_QUALITY = 75 PDF_MAX_WIDTH = 800 # 최대 가로 픽셀 제한 (추가) # ── 모델 저장 경로 (날짜/차수) ───────────────────── def get_model_save_path() -> Path: """ 날짜/차수 폴더 자동 생성 files/models/20260305/0001/ files/models/20260305/0002/ ← 같은 날 두 번째 학습 """ from datetime import datetime date_dir = MODEL_BASE_PATH / datetime.now().strftime("%Y%m%d") date_dir.mkdir(exist_ok=True) # 기존 차수 폴더 중 최대값 + 1 existing = sorted([ d for d in date_dir.iterdir() if d.is_dir() and d.name.isdigit() ]) next_idx = int(existing[-1].name) + 1 if existing else 1 save_path = date_dir / f"{next_idx:04d}" save_path.mkdir(exist_ok=True) return save_path def get_latest_model_path() -> Path | None: """저장된 모델 중 가장 최신 경로 반환""" candidates = sorted(MODEL_BASE_PATH.rglob("config.json")) if not candidates: return None return candidates[-1].parent