from pydantic import BaseModel, Field, field_validator, model_validatorfrom typing import Literalfrom pathlib import Path# 학습 파이프라인 설정class DataConfig(BaseModel): train_path: str val_path: str test_path: str | None = None max_length: int = Field(default=512, ge=1, le=8192) num_workers: int = Field(default=4, ge=0) @field_validator("train_path", "val_path") @classmethod def path_must_exist(cls, v: str) -> str: if not Path(v).exists(): raise ValueError(f"경로가 존재하지 않습니다: {v}") return vclass ModelConfig(BaseModel): name: str = "bert-base-uncased" hidden_size: int = Field(default=768, ge=1) num_layers: int = Field(default=12, ge=1) num_heads: int = Field(default=12, ge=1) dropout: float = Field(default=0.1, ge=0.0, lt=1.0) @model_validator(mode="after") def check_head_divisibility(self) -> "ModelConfig": if self.hidden_size % self.num_heads != 0: raise ValueError( f"hidden_size({self.hidden_size})는 " f"num_heads({self.num_heads})로 나누어져야 합니다" ) return selfclass TrainPipelineConfig(BaseModel): """전체 학습 파이프라인 설정""" data: DataConfig model: ModelConfig optimizer: Literal["adam", "sgd", "adamw"] = "adamw" learning_rate: float = Field(default=5e-5, gt=0) epochs: int = Field(default=3, ge=1) seed: int = 42# YAML/JSON 설정 파일에서 로딩import jsondef load_pipeline_config(path: str) -> TrainPipelineConfig: """JSON 설정 파일을 검증하여 로딩합니다.""" with open(path, "r", encoding="utf-8") as f: raw = json.load(f) return TrainPipelineConfig.model_validate(raw)# config = load_pipeline_config("pipeline_config.json")# print(config.model.hidden_size)# print(config.data.max_length)
Pydantic v1과 v2의 차이는 무엇인가요?
Pydantic v2는 Rust 기반 코어(pydantic-core)로 5~50배 빨라졌습니다. 주요 API 변경: dict() → model_dump(), json() → model_dump_json(), parse_obj() → model_validate(), validator → field_validator. 새 프로젝트에서는 반드시 v2를 사용하세요.
dataclass와 Pydantic의 차이는 무엇인가요?
dataclass는 데이터 저장 컨테이너이고, Pydantic은 데이터 검증 프레임워크입니다. Pydantic은 자동 타입 변환, 제약 조건 검증, JSON 직렬화를 기본 제공합니다. 외부 입력(API, 파일)을 다룰 때는 Pydantic, 내부 데이터 구조에는 dataclass가 적합합니다.