문제 정의: “사전”을 데이터 파이프라인으로 다시 보기
사전 구축은 단순한 단어-뜻 수집이 아니라 생성·검증·정규화·색인·배포로 이어지는 파이프라인이다. 002 버전은 이 관점을 전제에 두고, LLM을 편향 최소화된 검증기로, 임베딩·FAISS를 검색 인프라로, 체크포인트·로그·레이트리밋을 운영 안정화 레이어로 배치했다. 목표는 재현 가능한 품질과 중단/재개가 자유로운 대량 수집이다.
전체 아키텍처 개요
- 후보 생성(Candidate Generation)
- 접두(prefix) 기반 생성:
2letter/alpha/adaptive모드 - 희귀 접두(예:
kqvx…)는 “엄격(strict)” 프롬프트로 필터 - 과생성(over-generation) 후 정규식·스톱워드·길이 규칙으로 정제
- 접두(prefix) 기반 생성:
- LLM 검증(Self-Consistency Validation)
- 다중 온도(
0.2,0.4,0.8)로 독립 샘플 생성 - 합의 최소치(과반) 충족 시 채택, 아니면 폐기
- 규칙: 고유명사/약어/고어/오탈자 리젝트, 정의·예문 25어 이내, 순환 정의 금지
- 다중 온도(
- 양방향 콘텐츠 구성
definition_en/example_en+ 대상어(ko/es/fr/de/ja/zh/ru) 정의·예문- 대상어 누락 시 영→대상어 번역으로 보완(LLM)
- 벡터화 & 검색 인덱스
- Sentence-Transformers 임베딩 → L2 정규화 → FAISS (IP)
vec_id ↔ (word|prefix)매핑 저장으로 검색 결과-엔트리 안정 연결
- 저장·배포 형식
- JSON(메인), CSV, LangChain 문서 JSON, (옵션) SQLite 동시 출력
- 메타데이터에 길이·초성 분포·상위 접두 통계 포함
- 운영 안정화
- 토큰 버킷 레이트리밋(분당 요청 상한)
- 체크포인트 파일(
progress.json) 주기 저장, 안전 백업 - SIGINT/SIGTERM 수신 시 그레이스풀 셧다운
- 구조적 로깅, Ollama 헬스 체크
- 옵션: 경량 API
- 학습 후 즉시 /health /stats /search로 검증 가능한 소형 서버(선택)
- 운영 편의 목적이며, 학습만 필요하면 비활성
후보 생성: 품질을 좌우하는 초입 필터
접두 기반 생성은 불필요한 탐색 공간을 줄인다. 002는 세 가지 모드로 시작 순서를 최적화한다.
- 2letter: 영어 빈도 기반 2글자 조합 우선 → 전 조합 보강
- alpha: 26×26 전 조합 순회
- adaptive: 단일 알파벳+상위 바이그램 선행 → 전 조합 확장
희귀 접두는 프롬프트를 “더 엄격하게” 전환해 고유명사/전문약어 유입을 최소화한다. 이후 정규식으로 기호·숫자·허위 접미 제거, 길이·스톱워드·초기조건 검사를 통과해야만 LLM 검증으로 넘어간다.
LLM 검증: 한 번의 답보다 합의
단일 샘플은 변동성이 높다. 002는 다중 온도 샘플에서 다음 항목의 합의를 취한다.
- 품사(
pos)는 최빈값 투표 - 정의/예문은 “가장 짧고 명확한 문장”을 선택(각 25어 내)
rarity평균,confidence평균 →score = confidence × 합의비율score < cut또는rarity ≥ cut시 거절
이 과정은 고유명사·고어·오탈자의 계통적 유입을 막고, 예문이 의미를 드러내는지(용례성) 중심으로 품질을 다듬는다.
다국어 출력: 번역이 아니라 ‘쌍으로 보정’
영어 정의·예문이 기준이지만, 대상어 정의·예문은 직접 생성을 우선한다. 누락 시에만 번역으로 보정한다. 이렇게 하면 문화권별 자연스러운 표현을 유지하면서도 누락 내성을 확보한다. 결과에는 target_lang 메타와 함께 수집 시각, 신뢰도, 희귀도, 점수를 저장한다.
벡터 검색: “검색 결과를 다시 원문으로”의 가교
벡터 인덱스만 저장하면 엔트리를 잃는다. 002는 다음을 보장한다.
- 임베딩: 정의/예문 중 가벼운 텍스트를 선택해 임베딩(표준화)
- FAISS IndexFlatIP: 코사인에 준하는 점수(내적)
- 매핑 테이블:
vec_id_to_key와key_to_vec_id를 JSON으로 별도 저장 - Semantic Search API: 쿼리 임베딩 → 상위 K의
(word|prefix, score)반환
이 구조는 나중에 SQLite/JSON에서 엔트리를 역참조하는 데 단순하고 견고하다.
파일 형식과 메타: 다운스트림을 위한 계약
- 메인 JSON:
metadata + entries[] - CSV: ETL/시트 협업용
- LangChain JSON:
page_content + metadata + (embedding?)→ RAG에 즉시 투입 - SQLite(옵션): 서비스 측 색인/조회 최적화
메타에는 글자 길이 분포, 초성(첫 문자) 분포, 상위 접두 빈도 등을 포함한다. 이는 후속 배치 튜닝(예: 특정 접두 보강) 근거가 된다.
운영 안정화: 실패를 전제로 설계
- 레이트리밋: 초과 트래픽 시 단기 sleep으로 스로틀
- 체크포인트: N 접두마다 진행상황·메트릭 저장,
.bak롤백 - 헬스체크: Ollama 사전 POST로 응답성 진단
- 그레이스풀 셧다운: 시그널 수신 시 현재 배치를 닫고 저장 후 종료
중단 후 --resume만으로 이어서 재생산이 가능하다. 동일 prefix 재시도 시 중복 방지 캐시가 동일 단어의 재검증 낭비를 막는다.
성능·비용 튜닝의 관문
- 온도 배열:
0.2,0.4,0.8는 품질/다양성 타협안. 전문어 유입이 많다면 상한을 낮춘다. - over-generation: 후보 품질이 낮으면
1.8→2.2로, 지나치게 많으면 내린다. - 임베딩 모델:
all-MiniLM-L6-v2는 속도/크기 균형. 문맥 정밀도가 중요하면 상향. - 배치 크기: 접두별
batch를 낮추면 저장 주기가 촘촘해지고 장애 복원력이 오른다.
실전 사용 스니펫
# 의존성
pip install requests faiss-cpu sentence-transformers numpy python-dotenv
# (옵션) 서버 없이 순수 학습
python 002_cli.py --target-lang ko --mode 2letter --batch 20 --vector-store --resume
# (옵션) 경량 API 포함 버전, 학습 후 즉시 점검
pip install "fastapi>=0.111" "uvicorn[standard]>=0.30" "pydantic>=2.7"
python 002.py --target-lang ko --vector-store --serve
생성 산출물은 dict_*.json/csv, dict_langchain_*.json, (옵션) dict_*.sqlite, dict_vectors_*.index + .map.json으로 정리된다.
자주 마주치는 실패 패턴
- 전역 의존성으로 인한 크래시: 웹 서버용 클래스가 전역 선언되어 있을 때(예:
BaseModel) 모듈 미설치 시 즉시 예외. → 지연 임포트/내부 선언으로 분리. - 벡터-엔트리 매핑 누락: 검색 결과를 원문과 연결 못 함. → ID-키 매핑 파일을 별도 관리.
- 불안정한 프롬프트: “기술 용어/고유명사” 유입. → 희귀 접두에 엄격 모드 적용, 스톱워드·정규식 강화.
- 재현성 부족: 온도 세트가 바뀌면 결과 분산이 커짐. → 온도·임계값을 메타에 고정 기록.
결론: 한 번의 수집이 아니라, 반복 가능한 빌드
002 버전은 “한 번 잘 되는 코드”가 아니라 반복 가능한 데이터 빌드 시스템을 지향한다. 접두 기반 후보 생성으로 탐색 공간을 관리하고, 다중 샘플 합의로 품질을 확보하며, 임베딩·FAISS로 검색 가능성을 내장했다. 레이트리밋, 체크포인트, 안전 종료, 파일 포맷 계약은 운영의 피로를 낮춘다. 결과적으로, 수집—검증—색인—배포의 고리를 루틴화해 다음 배치로 자연스럽게 이어붙인다.
답글 남기기