veil-pii-ko-small-3
한국어 텍스트에서 이름(PERSON)·주소(ADDRESS)·기관명(ORGANIZATION) 스팬을 찾는 CPU용 경량 토큰 분류 모델입니다. 1T/veil-pii-ko-lite를 교사로 지식 증류했습니다.
모델 정보
| 항목 | 내용 |
|---|---|
| 기반 모델 | monologg/koelectra-small-v3-discriminator |
| 교사 모델 | 1T/veil-pii-ko-lite |
| 구조 | ElectraForTokenClassification, 8층, hidden 256, FFN 256, attention head 4 |
| 파라미터 | 7.7M |
| 파일 | model.fp32.onnx (ONNX FP32, 31MB), model.safetensors |
| 최대 입력 | 128토큰 창으로 나눠 처리 (겹침 16), 문서 길이 제한 없음 |
라벨
BIOES 13 태그, 제약 Viterbi 디코딩으로 스팬을 만듭니다.
| id | 태그 | id | 태그 | id | 태그 |
|---|---|---|---|---|---|
| 0 | O |
5 | B-ADDRESS |
9 | B-ORGANIZATION |
| 1 | B-PERSON |
6 | I-ADDRESS |
10 | I-ORGANIZATION |
| 2 | I-PERSON |
7 | E-ADDRESS |
11 | E-ORGANIZATION |
| 3 | E-PERSON |
8 | S-ADDRESS |
12 | S-ORGANIZATION |
| 4 | S-PERSON |
사용법
pip install huggingface_hub numpy onnxruntime tokenizers numba
import sys
from huggingface_hub import snapshot_download
path = snapshot_download("kakao1513/veil-pii-ko-small-3")
sys.path.insert(0, path)
from veil3 import Veil3
det = Veil3(path, threads=8)
text = "홍길동 과장은 부산광역시 해운대구 센텀중앙로 79에 있는 한국해양진흥공사에서 일한다."
for s in det.predict(text):
print(s["label"], text[s["start"]:s["end"]])
# PERSON 홍길동
# ADDRESS 부산광역시 해운대구 센텀중앙로 79
# ORGANIZATION 한국해양진흥공사
반환값은 {start, end, label, score} 목록이며 start/end는 원문 문자 오프셋입니다.
학습
학습 과정
| 단계 | 방법 | 학습 데이터 / 윈도 | 에폭 | 최대 학습률 | 최고 검증 F1 |
|---|---|---|---|---|---|
| 초기 학생 모델 | KoELECTRA-small 12층 중 8층 선택 후 지식 증류. FFN 폭 1,024 → 256으로 가지치기하고 학습 데이터 2,048건의 활성값을 이용해 출력 보정 | — | 6 계획, 2까지 기록 확인 | 3e-5 | 0.8598¹ |
| 개체 치환 증강 | KDPII의 이름·주소·기관명을 같은 유형의 다른 표현으로 치환 | 154,734행 / 228,760윈도 | 5 | 3e-5 | 0.829540 (5에폭) |
| 교사 라벨 추가 | 위 데이터에 교사가 라벨링한 한국어 텍스트 119,617구간 추가 | 274,351행 / 360,142윈도 | 3 | 3e-5 | 0.834841 (2에폭) |
| 최종 증류 | 교사 라벨 텍스트를 추가해 최종 학습 | 461,303행 / 566,108윈도 | 3 | 5e-5 | 0.847036 (3에폭) |
¹ 초기 학생은 129개 태그 전체에 대해 KDPII valid 300건을 평가한 수치입니다. 이후 단계의 3개 개체 대상 전체 검증셋 수치와 직접 비교할 수 없습니다. 각 단계는 앞 단계의 최고 체크포인트를 초기값으로 사용했습니다.
최종 학습 설정
| 항목 | 설정 |
|---|---|
| 손실 함수 | 0.2 × CE + 0.7 × KL + 0.1 × 은닉 상태 MSE |
| CE | 정답 또는 교사 라벨 사용, label smoothing 0.05 |
| KL 증류 | 온도 T=2, KL에 T²=4 적용. 교사 129개 태그 중 대상 3종 외 확률을 O에 합산해 13개 태그로 변환 |
| 은닉 상태 증류 | 학생 2·5·8층 ↔ 교사 3·8·12층. 학생을 768차원으로 투영하고 layer normalization 후 세 층의 MSE 평균 |
| 옵티마이저 | AdamW, weight decay 0.01, gradient clipping norm 1.0 |
| 학습률 | 최대 5e-5, 3,184스텝(전체의 6%) 선형 warmup 후 선형 감소 |
| 에폭 / 배치 | 3에폭, 배치 32윈도, 에폭당 17,691스텝, 총 53,073스텝 |
| 입력 | 최대 128토큰(CLS·SEP 포함), 본문 윈도 간 16토큰 중첩. 패딩·특수 토큰은 손실에서 제외 |
| 학습 환경 | NVIDIA RTX 3070 8GB, CUDA bfloat16 autocast, 시드 42 |
| 모델 선택 | KDPII valid의 대상 3종 정확 일치 스팬 micro F1 최고 체크포인트 |
최종 학습 데이터
| 구분 | 데이터 | 행 / 구간 수 | 라벨 |
|---|---|---|---|
| 원본 | KDPII train | 43,494 | 원본 정답 |
| 원본 | BCCard privacy-filter-openpii-masking | 57,851 | 원본 정답 |
| 합성 | 1T/veil-pii-ko-synth | 25,780 | 합성 정답 |
| 증강 | KDPII 개체 치환 | 27,609 | 치환에 맞춰 정답 스팬 수정 |
| 교사 라벨 | NSMC 영화평 | 65,800 | 교사 예측 |
| 교사 라벨 | 네이버 뉴스 | 81,194 | 교사 예측 |
| 교사 라벨 | 국민청원 | 113,521 | 교사 예측 |
| 교사 라벨 | 한국어 안전 대화 | 46,054 | 교사 예측 |
| 합계 | 461,303 |
| 학습 전략 | 처리 방법 |
|---|---|
| KDPII 업샘플링 | 원본 KDPII에서 대상 개체가 포함된 행의 윈도를 2배로 사용. 개체 치환 행은 추가 업샘플링하지 않음 |
| 개체 치환 | 대상 개체가 있는 KDPII 행마다 3개 변형 생성. 같은 유형의 표면형으로 바꾸고 스팬 오프셋 수정 |
| 교사 라벨 | 학습 중 교사가 생성한 13태그 확률의 argmax를 CE 타깃으로 사용하고, 확률 분포는 KL 증류에 사용 |
| 데이터 단위 | 행·구간 수는 고유 문서 수와 다를 수 있음. 윈도 수에는 토큰 중첩과 업샘플링이 포함됨 |
최종 단계 학습 곡선
| 에폭 | 평균 학습 손실 | 이전 에폭 대비 | 검증 Precision | 검증 Recall | 검증 F1 |
|---|---|---|---|---|---|
| 1 | 0.231940 | — | 0.832545 | 0.855199 | 0.843720 |
| 2 | 0.209916 | −0.022023 | 0.824723 | 0.868805 | 0.846190 |
| 3 | 0.204750 | −0.005166 | 0.833490 | 0.861030 | 0.847036 |
손실은 배치별 가중 합산 학습 손실의 에폭 평균이며 1→3에폭 동안 0.027189 감소했습니다. CE·KL·MSE 각각의 에폭 평균은 기록되지 않았습니다. 에폭별 원본 기록
평가
평가 데이터
| 용도 | 데이터 | 행 수 | 대상 3종 정답 스팬 | 역할 |
|---|---|---|---|---|
| 검증 | KDPII valid | 5,011 | 1,029 | 에폭별 평가 및 체크포인트 선택 |
| 테스트 | KDPII test | 4,891 | 949 | 최종 정확도 평가 |
| 테스트 | Veil 합성 heldout | 670 | 495 | 합성 문장 정확도 평가 |
| 중복 확인 | 결과 |
|---|---|
| KDPII valid / test | 각각 91행 / 92행의 텍스트가 KDPII 학습 데이터와 완전히 일치. 이 행들에는 대상 3종 정답 스팬이 없음 |
| 합성 heldout | 학습 데이터와 완전히 일치하는 텍스트 0행 |
| 검사 범위 | 원문 문자열의 정확 일치만 확인. 유사 문장·부분 중복 및 교사 학습 데이터와의 중복은 확인하지 않음 |
평가 방법
| 항목 | 방법 |
|---|---|
| 평가 대상 | PERSON, ADDRESS, ORGANIZATION. 나머지 라벨은 집계에서 제외 |
| 정확 일치 | 문서별 (시작 문자 위치, 끝 문자 위치, 라벨)이 모두 일치하면 TP, 예측에만 있으면 FP, 정답에만 있으면 FN |
| 지표 | 세 라벨의 TP·FP·FN을 합산한 micro Precision, Recall, F1. P=TP/(TP+FP), R=TP/(TP+FN), F1=2PR/(P+R) |
| 보조 지표 | partial F1은 같은 라벨에서 문자 범위가 겹치는 스팬을 일대일 매칭. 아래 정확도 표는 정확 일치 기준 |
| 검증 추론 | PyTorch GPU, 128토큰 창, 겹침 16, 배치 32 |
| 테스트 추론 | ONNX Runtime FP32, AMD Ryzen 5 5600X CPU, WSL2, 8스레드, 128토큰 창, 겹침 16, 배치 16 |
| 스팬 생성 | BIOES 제약 Viterbi 디코딩, 창 경계 중복 정리, 스팬 병합 및 조사 처리 |
| 식별자 전처리 | skip_ids=True: 영문·숫자가 섞인 6자 이상 ASCII 식별자형 토큰을 추론 전에 제외. 적용 여부에 따라 KDPII test 0행, 합성 heldout 58행의 예측이 달라짐 |
| 교사 비교 | 동일 평가 코드에서 교사의 32개 개체 출력 중 대상 3종만 남겨 계산 |
정확도
| 데이터 | 모델 | Precision | Recall | F1 |
|---|---|---|---|---|
| KDPII test | veil-pii-ko-small-3 | 0.850 | 0.874 | 0.862 |
| KDPII test | veil-pii-ko-lite (교사) | 0.891 | 0.898 | 0.894 |
| Veil 합성 heldout | veil-pii-ko-small-3 | 0.889 | 0.972 | 0.929 |
| Veil 합성 heldout | veil-pii-ko-lite (교사) | 0.898 | 0.978 | 0.936 |
KDPII test 라벨별:
| 라벨 (정답 수) | Precision | Recall | F1 |
|---|---|---|---|
| PERSON (274) | 0.802 | 0.872 | 0.836 |
| ADDRESS (208) | 0.810 | 0.904 | 0.855 |
| ORGANIZATION (467) | 0.903 | 0.861 | 0.882 |
속도
교사 모델과 동일한 실행 조건에서 비교
동일한 한국어 상담 문장을 반복해 길이를 맞춘 문서 1건을 입력했습니다. 아래 시간은 각 모델의 3회 실측 중앙값이며 단위는 ms입니다. 배율 = 교사 시간 ÷ 학생 시간, 감소율 = (1 − 학생 시간 ÷ 교사 시간) × 100입니다.
| 입력 길이 (문자) | 교사 (ms) | 학생 (ms) | 속도 배율 | 지연시간 감소 |
|---|---|---|---|---|
| 100 | 40.3 | 4.8 | 8.3배 | 88.0% |
| 1,000 | 297.1 | 21.7 | 13.7배 | 92.7% |
| 5,000 | 1,148.0 | 71.8 | 16.0배 | 93.7% |
| 10,000 | 2,296.8 | 140.8 | 16.3배 | 93.9% |
| 50,000 | 11,803.3 | 701.2 | 16.8배 | 94.1% |
| 100,000 | 23,740.2 | 1,332.6 | 17.8배 | 94.4% |
| 200,000 | 44,920.6 | 2,659.2 | 16.9배 | 94.1% |
| 공통 측정 조건 | 설정 |
|---|---|
| 장비 / OS | AMD Ryzen 5 5600X, WSL2 Linux, CPU 논리 코어 4–11에 고정 |
| 실행 | CPU PyTorch 2.11.0 FP32, Transformers 5.22.1, NumPy 2.5.4, Numba 0.68.1, 연산 스레드 8개, inter-op 1개 |
| 입력 / 배치 | 같은 원문, 128토큰 창(CLS·SEP 포함), 창 겹침 16토큰, 배치 최대 16윈도 |
| 처리 범위 | 모델 로딩 이후 토큰화, 윈도 분할, 모델 추론, Numba 제약 Viterbi 디코딩, 스팬 병합·조사 처리, 3개 라벨 필터링, UTF-8 JSON 직렬화 포함 |
| 반복 | 모델별 1,000자 입력으로 3회 워밍업 후 각 길이 3회 측정. 반복마다 실행 순서 교대. 모델 로딩·첫 JIT 컴파일은 제외 |
| 전처리 | 두 모델 모두 식별자 건너뛰기 미적용 |
교사는 32종(129태그)을 모두 추론·디코딩한 뒤 PERSON·ADDRESS·ORGANIZATION만 필터링하고, 학생은 3종(13태그)을 추론합니다. 따라서 이 수치는 동일 파이프라인에서 각 모델을 실행한 결과이며, 출력 범위가 다른 두 모델의 전체 처리시간 비교입니다. 교사의 3종 전용 모델과의 순수 구조 비교나 ONNX 배포 경로의 직접 비교는 아닙니다. 반복 문장 하나로 만든 합성 부하이므로 실제 문서의 토큰 밀도·개체 수, 하드웨어와 동시 요청에 따라 값이 달라집니다. 짧은 입력은 타이머와 시스템 부하에 영향을 받으며 3회만으로 p95/p99를 추정할 수 없습니다.
길이별 개별 실측값 (ms, 실행 순서)| 문자 수 | 교사 1·2·3회 | 학생 1·2·3회 |
|---|---|---|
| 100 | 40.92, 39.84, 40.28 | 4.83, 5.72, 4.63 |
| 1,000 | 297.43, 297.07, 295.44 | 19.06, 21.72, 22.16 |
| 5,000 | 1166.29, 1147.98, 1139.29 | 71.99, 71.27, 71.81 |
| 10,000 | 2296.85, 2317.34, 2252.16 | 140.80, 137.66, 142.35 |
| 50,000 | 11565.52, 11803.29, 11878.45 | 706.01, 691.74, 701.21 |
| 100,000 | 23809.52, 23740.17, 23202.30 | 1322.08, 1332.64, 1332.76 |
| 200,000 | 45910.81, 44564.90, 44920.62 | 2659.20, 2643.17, 2694.88 |
측정 원본 JSON · 측정 스크립트. 스크립트는 실험 저장소의 upstream 평가 코드와 student8n256/fast_decode.py, 교사·학생 가중치를 필요로 합니다.
속도와 정확도를 함께 고려해야 합니다. 별도 ONNX 평가에서 KDPII test의 3종 정확 일치 micro F1은 학생 0.862, 교사 0.894로 학생이 약 3.2%p 낮았습니다. 이 정확도는 위 속도 측정과 별도의 평가입니다.
학생 ONNX 배포 경로: 입력 구성별 기존 기록
최종 체크포인트 n256kd의 기존 기록입니다. 20만 자 문서 1건, WSL2 CPU ONNX Runtime FP32, 8스레드, 창 128 / 겹침 16, 배치 16, 모델 적재 이후 JSON 직렬화까지 포함한 3회 중앙값입니다. 이 값은 위 PyTorch 표와 별도 측정입니다.
| 입력 | 식별자 건너뛰기 사용 | 미사용 |
|---|---|---|
| 일반 문장 반복 | 2.40초 | 2.40초 |
| 평가 문장 이어붙임 | 2.58초 | 2.65초 |
| 식별자 + 전화번호 혼합 | 1.74초 | 2.67초 |
| 영숫자 식별자 밀집 | 0.18초 | 4.33초 |
skip_ids=True는 식별자형 토큰을 모델 입력에서 제외하므로 입력 구성에 따라 효과가 다릅니다. KDPII test에서는 적용 여부에 따른 예측 변화가 없었지만 합성 heldout에서는 58개 문서의 예측이 달라졌습니다. skip 적용 원본 · 미적용 원본
한계
- 교사 모델보다 F1이 약 3pt 낮으며, 주로 이름과 기관명의 재현율 차이에서 납니다.
- 교사 모델의 라벨링 기준을 따릅니다.
- 한국어 데이터로만 평가했습니다.
- 속도는 위 환경의 측정값이며, 배포 환경의 CPU에 따라 달라집니다.
라이선스
이 모델은 Apache License 2.0으로 제공됩니다. 사용·수정·재배포 및 상업적 이용이 가능하며, 재배포 시 라이선스와 저작권 고지를 유지하고 변경한 내용을 표시해야 합니다. 특허 허여와 보증 부인 등 세부 조건은 Apache License 2.0 원문을 따릅니다.
| 구성 요소 | 출처 | 라이선스 / 저작권 |
|---|---|---|
| 교사 모델 및 후처리 기반 코드 | 1T/veil-pii-ko-lite | Apache-2.0, Copyright 2026 Wontae Kim |
| 학생 기반 모델 | monologg/koelectra-small-v3-discriminator | Apache-2.0, KoELECTRA: Jangwon Park |
| KDPII 및 개체 치환 증강 | KDPII, Fei, Kang et al., IEEE Access, 2024 | CC-BY-4.0 |
| BCCard 데이터 | privacy-filter-openpii-masking | CC-BY-4.0 |
| Veil 합성 데이터 | 1T/veil-pii-ko-synth | Apache-2.0 |
| 영화 리뷰 | e9t/nsmc | 원본 GitHub는 CC0-1.0, Hugging Face 데이터셋 메타데이터는 CC-BY-2.0으로 표시 |
| 뉴스 | daekeun-ml/naver-news-summarization-ko | Apache-2.0 |
| 청원 | heegyu/korean-petitions | MIT |
| 안전 대화 | jojo0217/korean_safe_conversation | Apache-2.0 |
교사 라벨 생성에 사용한 영화 리뷰·뉴스·청원·안전 대화 원문은 이 모델 저장소에 포함되어 있지 않습니다. 위 데이터셋을 별도로 사용할 때는 각 출처의 라이선스와 저작자 표시 조건을 확인하세요.