CPUํ๊ฒฝ์์ ๋น ๋ฅด๊ฒ ๊ตฌ๋์ด ๊ฐ๋ฅํ ํ๊ตญ์ด ๊ฐ์ธ์ ๋ณด ํ์ง์ฉ ํ ํฐ ๋ถ๋ฅ ๋ชจ๋ธ์ ๋๋ค.
๊ฐ์
On-Premise ํํ๋ก ๊ตฌ์ถ์ด ํ์ํ ํ๊ฒฝ์์ ๊ฐ๋ฒผ์ฐ๋ฉด์๋ ๋์ PII ํ์ง ์ฑ๋ฅ์ ๋ชฉํ๋ก ๋ง๋ค์ด์ง ๋ชจ๋ธ์ ๋๋ค. KoELECTRA-base-v3 (110M) ๋ฅผ ํตํด 32๊ฐ์ PII Category์ ๋ํ ๋ถ๋ฅ๊ฐ ๊ฐ๋ฅํ๋๋ก Fine-Tuniningํ๊ณ , INT8 ONNX ๋ก CPU ํ๊ฒฝ์์ ๋น ๋ฅธ ๊ตฌ๋์ด ๊ฐ๋ฅํ๋๋ก ์ต์ ํ ํ์์ต๋๋ค.
๋ฒค์น๋งํฌ
ํ๊ฐ ์งํ๋ entity-level exact match F1 (micro) ์ ๋๋ค. ์์ธกํ ์คํฌ์ ์์ยท๋ ์์น์ ๋ผ๋ฒจ์ด ์ ๋ต๊ณผ ๋ชจ๋ ์ผ์นํด์ผ ์ ๋ต์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค. ๋น๊ต ๋ชจ๋ธ๋ ์ ๋ถ ๊ฐ์ ์ค์ฝ์ด๋ฌ์ ๊ฐ์ ๋์ฝ๋๋ฅผ ํ์ ์ธก์ ํ์ต๋๋ค.
| ๋ฒค์น | n | Veil fp32 | Veil INT8 | BCCard 1.4B | FrameByFrame 1.4B | Azure AI Language |
|---|---|---|---|---|---|---|
| KDPII test โ ์ค์ ๋ํ์ฒด | 4,891 | 0.9339 | 0.9342 | 0.4533 | 0.5156 | 0.4631 |
| KDPII test โ ๋ํ ๋จ์ | 458 | 0.9423 | 0.9433 | 0.4661 | โ | 0.4626 |
| KDPII test โ FrameByFrame 9๋ผ๋ฒจ ํ์ | 4,891 | 0.9383 | โ | โ | 0.6824 | โ |
| BCCard validation ยท ko | 10,743 | 0.9826 | 0.9824 | 0.9594 | โ | 0.4031 |
| BCCard validation ยท en | 3,781 | 0.9700 | 0.9697ยน | 0.9653 | โ | 0.5295 |
| ํฉ์ฑ heldout v2 โ 32 ๋ผ๋ฒจ | 670 | 0.9652 | 0.9643 | 0.5328 | โ | 0.5035 |
ยน 2026-09-23 ์ฌ์ธก์ ๊ฐ์ ๋๋ค(์ฐฝ ๋ถํ ๋ฒ๊ทธ ์์ ๋ฐ์). ๋๋จธ์ง ๊ฐ์ 2026-09-17 ๊ธฐ์ค์ ๋๋ค.
๋น๊ต ๋ชจ๋ธ๊ตฐ์ด ์๋ก ๋ถ๋ฆฌํ์ง ์๋๋ก, ๊ฐ ๋ชจ๋ธ์ด ํ์ตํ ๋ผ๋ฒจ๋ง์ผ๋ก ๋ฒ์๋ฅผ ํ์ ํ์ฌ ์ธก์ ์งํํ์์ต๋๋ค. ๋ค๋ง, ๋ณธ ๋ชจ๋ธ๊ณผ ๋น๊ต๋ชจ๋ธ๊ฐ์ ์ฑ๋ฅ ์ฐจ์ด๋ ๋์ผํ์์ต๋๋ค.(BCCard 29๋ผ๋ฒจ 0.4636, Azure ๋งคํ ๋ผ๋ฒจ 0.4741) ๊ทธ๋ฆฌ๊ณ , FrameByFrame ์ 9๊ฐ ๋ผ๋ฒจ๋ง ์ง์ํ๊ธฐ ๋๋ฌธ์ KDPII ์ธ์ ๋ฒค์น๋ ์ธก์ ํ์ง ์์์ต๋๋ค.
2026-09-23 ์ฌ์ธก์ . ์๋ ๋ฌธ์ ๊ธธ์ด ์ ์ ์ ์ ์ฐฝ ๋ถํ ๋ฒ๊ทธ๊ฐ ์ด ํ์๋ ๊ฑธ๋ ค ์์์ต๋๋ค. BCCard validation ์ ์์ด ํ์ 5.6%, ํ๊ตญ์ด ํ์ 4.5% ๊ฐ 512 ํ ํฐ์ ๋๋๋ฐ(์์ด ์ต๋ 1,351 ํ ํฐ), ๊ทธ ๋ท๋ถ๋ถ์ด ๋ชจ๋ธ๊น์ง ๊ฐ์ง ๋ชปํ์ต๋๋ค. ๊ณ ์น ๋ค ์์น์ ๋๋ค.
| ๋ฒค์น | n | INT8 (์ด์ ) | INT8 (ํ์ฌ) | BCCard 1.4B |
|---|---|---|---|---|
| KDPII test | 4,891 | 0.9342 | 0.9327 | 0.4533 |
| KDPII test โ ๋ํ ๋จ์ | 458 | 0.9433 | 0.9420 | 0.4661 |
| BCCard validation ยท ko | 10,743 | 0.9824 | 0.9825 | 0.9594 |
| BCCard validation ยท en | 3,781 | 0.9632 | 0.9697 | 0.9653 |
์์ด๊ฐ 0.65pt ์ค๋ฅธ ๊ฑด ์๋ ค ๋๊ฐ๋ ๊ธด ํ์ด ์ด์๋ฌ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ ์๋ ์์ด์์ BCCard 1.4B ์ 0.2pt ๋ฐ๋ ธ๋๋ฐ ์ง๊ธ์ ์์ญ๋๋ค. ํ๊ตญ์ด๊ฐ ์ด์ง ๋ด๋ ค๊ฐ ๊ฑด ์ ๊ฐ ์ ๊ทํ๋ฅผ ๋ฃ์ ๋๊ฐ์ ๋๋ค(โ0.08pt).
๋ผ๋ฒจ๋ณ ์์น๋ PER_LABEL.md ์ ์์ต๋๋ค. 32 ๋ผ๋ฒจ์ ๋ฐ์ดํฐ์
5์ข
(KDPII test ยท KDPII ๋ํ ๋จ์ ยท BCCard ko ยท BCCard en ยท ํฉ์ฑ heldout) ร ๋ชจ๋ธ 6์ข
์ผ๋ก ํผ์ณ ๋จ์ต๋๋ค. ์ธก์ ์กฐ๊ฑด์ EVIDENCE.md, ์๋ณธ JSON ์ eval_*.json ๊ณผ baselines/ ์ ์์ต๋๋ค.
๋ผ๋ฒจ๋ณ ์ฌํ์จ
KDPII test ๊ธฐ์ค์ผ๋ก ๋ชป ์ก๋ ์ชฝ๊ณผ ๋ค ์ก๋ ์ชฝ์ ๊ฐ์ด ์ ์ต๋๋ค.
| ๊ตฌ๋ถ | ๋ผ๋ฒจ | n | Recall |
|---|---|---|---|
| ๋์น๋ ๋ผ๋ฒจ | ORGANIZATION | 467 | 0.887 |
| ADDRESS | 208 | 0.899 | |
| PERSON | 274 | 0.912 | |
| RRN | 18 | 0.944 | |
| ์ ๋ถ ๊ฒ์ถ | PHONE ยท EMAIL ยท CARD_NUMBER ยท ACCOUNT_NUMBER ยท USER_ID ยท VEHICLE_PLATE ยท URL ยท PASSPORT ยท DRIVER_LICENSE ยท IPADDRESS ยท FRN | 1.000 |
ํ์์ด ์ ํด์ง ์๋ณ์๋ ๊ฑฐ์ ๋ค ์ก์ต๋๋ค. ๋์น๋ ๊ฑด ๋ฌธ๋งฅ์ ๋ด์ผ ํ๋ ์ด๋ฆยท์ฃผ์ยท๊ธฐ๊ด๋ช ์ชฝ์ ๋๋ค. BCCard validation(ko) ์์๋ GENERIC_ID 0.905 ยท DRIVER_LICENSE 0.911 ยท PORT 0.933 ์์ผ๋ก ๋ฎ์ต๋๋ค.
ํ์ต์ ๊ณผ ํ๊ฐ์ ์ ์ค๋ณต
leakage_check.py ๋ก ํ
์คํธ๋ฅผ ์ธ ๋จ๊ณ(์๋ฌธ / ๊ณต๋ฐฑยท๋์๋ฌธ์ ๋ฌด์ / ์ซ์ ๋ง์คํน)๋ก ํด์ํด ๋์กฐํ์ต๋๋ค.
| ๋ฐ์ดํฐ | train | test | ์์ ์ค๋ณต | ๊ณต๋ฐฑ๋ฌด์ | ์ซ์๋ง์คํน |
|---|---|---|---|---|---|
| KDPII | 40,109 | 4,891 | 92 (1.88%) | 94 (1.92%) | 108 (2.21%) |
| BCCard | 57,851 | 14,524 | 0 | 0 | 0 |
KDPII ์ค๋ณต 92๊ฑด์ ์ ๋ถ ์ ๋ต ์คํฌ์ด 0๊ฐ์
๋๋ค. ์์์ด. ์ ๋ง ์ฃ์กํฉ๋๋ค, ๊ณ ๊ฐ๋. ๊ฐ์ ๋ง์ฅ๊ตฌ๊ฐ
๋ํ ์ฝํผ์ค๋ผ train ๊ณผ test ์์ชฝ์ ๊ฑธ๋ฆฐ ๊ฒ์
๋๋ค. ์ด ํ์ ๋นผ๊ณ ๋ค์ ์ฌ๋ F1 ์ 0.9327 ๋ก ๊ฐ๊ณ ,
์ซ์๋ง ๋ค๋ฅธ ํ
ํ๋ฆฟ ์ค๋ณต๊น์ง ๋นผ๋ฉด 0.9321 ๋ก 0.05pt ๋ด๋ ค๊ฐ๋๋ค.
๋ฌธ์ ๊ธธ์ด
๋ณธ๋ฌธ ํ ํฐ์ 510๊ฐ์ฉ ์๋ฅด๊ณ ์ธ์ ํ ์ฐฝ์ 128 ํ ํฐ ๊ฒน์นฉ๋๋ค. ๊ฒน์น ๊ตฌ๊ฐ์ ์์ชฝ์์ 64 ํ ํฐ์ฉ ์๋ผ ํ ๋ฒ๋ง ์ธ๊ธฐ ๋๋ฌธ์, ๊ฒฝ๊ณ์ ๊ฑธ์น ์คํฌ๋ ํ์ชฝ ์ฐฝ์ด ํต์งธ๋ก ๋ด ๋๋ค.
| ๋ฌธ์ ๊ธธ์ด | ๋ฌธ์ ์ | P | R | F1 |
|---|---|---|---|---|
| ~200์ | 605 | 0.9390 | 0.9495 | 0.9442 |
| ~800์ | 160 | 0.9334 | 0.9520 | 0.9426 |
| ~1,800์ | 72 | 0.9328 | 0.9526 | 0.9426 |
| ~3,000์ | 44 | 0.9291 | 0.9483 | 0.9386 |
2026-09-23 ์ด์ ๋ฒ์ ์๋ ์ฌ๊ธฐ์ ๋ฒ๊ทธ๊ฐ ์์์ต๋๋ค. ์ฐฝ ๋ถํ ์ ํ ํฌ๋์ด์ ์ ๋งก๊ฒผ๋๋ 1,617 ํ ํฐ ์ ๋ ฅ์์ ์ฐฝ์ด 2๊ฐ๋ง ์๊ธฐ๊ณ 953์ ์ดํ๊ฐ ๋ชจ๋ธ๊น์ง ๊ฐ์ง ๋ชปํ์ต๋๋ค(3,000์ ๋ฌธ์ ์ฌํ์จ 0.284). ์ฐฝ ๋ถํ ์ ์ง์ ์ง์ ๊ณ ์ณค์ต๋๋ค. ๊ธด ๋ฌธ์๋ฅผ ๋ค๋ฃฌ๋ค๋ฉด ์ต์ ๋ฒ์ ์ ๋ฐ์ผ์ธ์.
ํ๊ธฐ ๋ณํ
์ ๋ต ์คํฌ์ ๊ทธ๋๋ก ๋๊ณ ํ๊ธฐ๋ง ๋ฐ๊ฟ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ROBUSTNESS.md ์ ์์ต๋๋ค.
| ๋ณํ | ์ | ฮ F1 |
|---|---|---|
| ํ์ดํ โ ์ | 010.1234.5678 |
โ0.2pt |
| ํ์ดํ โ ๊ณต๋ฐฑ | 010 1234 5678 |
โ0.6pt |
| ๊ตฌ๋ถ์ ์ ๊ฑฐ | 01012345678 |
โ7.4pt |
| ์ ๊ฐ ์ซ์ | ๏ผ๏ผ๏ผ |
0.0pt |
| ๊ธ์ ์ฌ์ด ๊ณต๋ฐฑ | ํ ๊ธธ ๋ |
โ61.1pt |
์ ๊ฐ ์ซ์๋ ๊ธธ์ด๋ฅผ ์ ์งํ๋ ์ ๊ทํ๋ก ์ฒ๋ฆฌํฉ๋๋ค(๊ธฐ๋ณธ on, Veil(..., normalize=False) ๋ก ๋ ์ ์์ต๋๋ค).
๊ธ์ ์ฌ์ด์ ๊ณต๋ฐฑ์ ๋ฃ์ ํ๊ธฐ๋ ์์ง ๋ชป ์ก์ต๋๋ค. ์๋ธ์๋ ํ ํฌ๋์ด์ ๊ฐ ๊ธ์๋ง๋ค ํ ํฐ์ ์๋ก ๋์ด์
ํ์ต ๋ ๋ณธ ์ ์๋ ํํ๊ฐ ๋๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๋ฐ ํ๊ธฐ๊ฐ ์์ฃผ ๋ค์ด์ค๋ ํ๊ฒฝ์ด๋ฉด ์๋จ์ ์ ๊ท์ ๋ฃฐ์ ๋๋ ๊ฒ ๋ซ์ต๋๋ค.
์ ๊ท์๊ณผ์ ๊ด๊ณ
์ ํ PII 12์ข ์ ์ ๊ท์๊ณผ ์ฒดํฌ์ฌ(Luhn, ์ฃผ๋ฏผ๋ฒํธ ๊ฐ์คํฉ)์ ๊ฑธ๊ณ ๊ฐ์ ์ค์ฝ์ด๋ฌ๋ก ์์ต๋๋ค.
| ๋ฐ์ดํฐ | ๋ฐฉ์ | P | R | F1 |
|---|---|---|---|---|
| KDPII test | ์ ๊ท์ | 0.6189 | 0.1103 | 0.1873 |
| KDPII test | ์ด ๋ชจ๋ธ | 0.9284 | 0.9370 | 0.9327 |
| KDPII test | ์ ๊ท์ โช ๋ชจ๋ธ | 0.9284 | 0.9370 | 0.9327 |
| BCCard val ko | ์ ๊ท์ โช ๋ชจ๋ธ | 0.9795 | 0.9829 | 0.9812 |
์ ๊ท์๋ EMAIL ์ฌํ์จ 1.000, URL 0.744 ๋ก ํ์์ด ์ ํด์ง ๊ฑด ์ ์ก์ต๋๋ค. ๋ค๋ง ๋ํ์ฒด(๋ฒํธ ๋ท์๋ฆฌ๊ฐ 5678)๋
์ด๋ฆยท์ฃผ์ยท๊ธฐ๊ด๋ช
์๋ ์์ ๊ฑธ๋ฆฌ์ง ์์ต๋๋ค. ๋ชจ๋ธ ์์ ์น์ด๋ ์ ์๊ฐ ์ค๋ฅด์ง ์์ผ๋,
์ ๊ท์์ ํ์ง์จ๋ณด๋ค ๊ฐ์ฌ ๊ทผ๊ฑฐ๋ฅผ ๋จ๊ธฐ๋ ์ฉ๋๋ก ์ฐ๋ ๊ฒ ๋ง์ต๋๋ค.
์ฌ์ฉ๋ฒ
pip install onnxruntime transformers numpy
hf download 1T/veil-pii-ko-lite --local-dir veil
import sys; sys.path.insert(0, "veil")
from veil import Veil # ONNX Runtime + ์ ์ฝ Viterbi + ํ์ฒ๋ฆฌ. torch ์์ด ๋์
det = Veil("veil/model.int8.onnx", tokenizer_dir="veil", threads=4)
det.predict("๋ด๋น์ ๊น์ฒ ์(010-1234-5678)์๊ฒ ๋ฌธ์")
# [{'start': 4, 'end': 7, 'label': 'PERSON', 'score': 0.9999},
# {'start': 8, 'end': 21, 'label': 'PHONE', 'score': 0.9999}]
det.mask("๋ด๋น์ ๊น์ฒ ์(010-1234-5678)์๊ฒ ๋ฌธ์")
# '๋ด๋น์ [PERSON]([PHONE])์๊ฒ ๋ฌธ์'
fp32 (transformers)
from transformers import AutoTokenizer, AutoModelForTokenClassification
tok = AutoTokenizer.from_pretrained("1T/veil-pii-ko-lite")
model = AutoModelForTokenClassification.from_pretrained("1T/veil-pii-ko-lite")
๋ก์ง์ ๊ทธ๋ฅ argmax ํ๋ฉด BIOES ๊ท์น์ด ๊นจ์ง ์คํฌ์ด ์์ฌ ๋์ต๋๋ค. Veil ํด๋์ค๋ ONNX ์ ์ฉ์ด์ง๋ง, ๊ฐ์ ํ์ผ์ ์๋ ์ ์ด ํ๋ ฌ๊ณผ tags_to_spans, strip_particles ๋ฅผ fp32 ๋ก์ง์ ๊ฑธ๋ฉด ๊ฒฐ๊ณผ๊ฐ ๊ฐ์์ง๋๋ค.
์ถ๋ ฅ ยท ์ต์
predict(text) ๋ list[{"start", "end", "label", "score"}] ๋ฅผ ๋๋ ค์ค๋๋ค. startยทend ๋ ์๋ฌธ ๊ธฐ์ค ๋ฌธ์ ์ธ๋ฑ์ค๋ผ text[start:end] ๋ก ๋ฐ๋ก ์๋ผ ์ฐ๋ฉด ๋๊ณ , ์คํฌ๋ผ๋ฆฌ ๊ฒน์น์ง ์์ต๋๋ค. ๋ง์คํน๋ ๋ฌธ์์ด์ด ํ์ํ๋ฉด mask(text, fmt="[{label}]") ๋ฅผ ์ฐ๋ฉด ๋ฉ๋๋ค.
์์ฑ์ ์ต์ ์ ๋๋ค.
| ์ต์ | ๊ธฐ๋ณธ๊ฐ | ์ค๋ช |
|---|---|---|
max_len |
512 | ํ ๋ฒ์ ์ฒ๋ฆฌํ ํ ํฐ ์ |
stride |
128 | ์ฌ๋ผ์ด๋ฉ ์ฐฝ์ด ๊ฒน์น๋ ํญ |
threads |
4 | ONNX ์ค๋ ๋ ์ |
o_bias |
0.0 | ์์๋ก ์ฌ๋ฆฌ๋ฉด ์ฌํ์จ ์ชฝ์ผ๋ก ๊ธฐ์ธ์ด์ง๋๋ค (precision ์ ๋ด๋ ค๊ฐ๋๋ค) |
merge_adjacent |
("ADDRESS",) |
๊ณต๋ฐฑ 1๊ฐ ์ด๋ด๋ก ๋ถ์ ๊ฐ์ ๋ผ๋ฒจ์ ํฉ์นฉ๋๋ค. ๋ฒค์น๋งํฌ๋ฅผ ์ฌํํ ๋๋ () ๋ก ๋์ธ์ |
์ ๋ ฅ ๊ธธ์ด ์ ํ์ ์์ต๋๋ค. 512 ํ ํฐ ์ฐฝ์ 128 ์ฉ ๊ฒน์ณ ๋ฐ๋ฉด์ ์ ์ฒด๋ฅผ ํ๊ณ , ๊ฒฝ๊ณ์ ๊ฑธ์น ์คํฌ์ ๋ค์์ ์ด์ด ๋ถ์ ๋๋ค.
์ปจํ ์ด๋
๊ฐ์ค์น๊ฐ ์ด๋ฏธ์ง์ ๋ค์ด ์์ด ๋ฐ๋ก ์ค์นํ ๊ฒ ์๊ณ , ๋คํธ์ํฌ๊ฐ ์๋ ํ๊ฒฝ์์๋ ๊ทธ๋๋ก ๋น๋๋ค.
docker run -d -p 8080:8080 --name veil zzang9680/veil-pii:slim
curl -s localhost:8080/detect -H 'Content-Type: application/json' \
-d '{"text":"๋ด๋น์ ๊น์ฒ ์(010-1234-5678)์๊ฒ ๋ฌธ์"}'
curl -s localhost:8080/mask -H 'Content-Type: application/json' \
-d '{"text":"๊น์ฒ ์ 010-1234-5678","policy":"partial"}'
# {"text":"๊น*์ 010-****-5678", ...}
| ํ๊ทธ | ํฌ๊ธฐ(์์ถ) | ๋ด์ฉ |
|---|---|---|
slim |
235 MB | ํ์ง + ์ต๋ช
ํ 3์ข
(default/hash/partial) |
presidio |
300 MB | slim + Presidio ์ด๋ํฐยทAnonymizer ์ฐ์ฐ์ |
๋ ํ๊ทธ ๋ชจ๋ amd64ยทarm64 ๋ฅผ ํจ๊ป ๋ด์ ๋ฉํฐ ์ํคํ
์ฒ ์ด๋ฏธ์ง๊ณ , ํ์ง ๊ฒฐ๊ณผ๋ ์๋ก ๊ฐ์ต๋๋ค. ๋ฒ์ ์ ๊ณ ์ ํ๋ ค๋ฉด slim-1.0.0 ์ด๋ presidio-1.0.0 ์ ์ฐ์ธ์.
์๋ํฌ์ธํธ๋ /detect /mask /batch /healthz /labels /docs, ํ๊ฒฝ๋ณ์๋ VEIL_THREADS VEIL_HASH_SALT VEIL_MAX_CHARS ์
๋๋ค. ์ ์ฒด ํ๊ทธ๋ https://hub.docker.com/r/zzang9680/veil-pii/tags ์ ์์ต๋๋ค.
Presidio ์ด๋ํฐ
REST ์๋ต์ ๋ ์ด๋ฏธ์ง๊ฐ ๊ฐ์ต๋๋ค. ๊ฐ์ ๋ฌธ์ฅ์ ๋ฃ์ผ๋ฉด ์คํฌ๋, hash ์ ์ฑ
์ ํ ํฐ ๊ฐ๋ ๋๊ฐ์ด ๋์ต๋๋ค. HTTP ๋ก๋ง ์ธ ๊ฑฐ๋ฉด slim ์ด๋ฉด ๋๊ณ , ์๋ ์ธ ๊ฐ์ง๊ฐ ํ์ํ ๋๋ง presidio ๋ฅผ ์ฐ๋ฉด ๋ฉ๋๋ค.
docker run -d -p 8080:8080 -e VEIL_HASH_SALT=my-secret --name veil zzang9680/veil-pii:presidio
# 1) Presidio ํ์ค ์ํฐํฐ ํ์
โ ์ฐ๋ Presidio ํ์ดํ๋ผ์ธ์ ๊ทธ๋๋ก ๊ฝํ๋ค
docker exec veil python -c "from veil_pii.presidio import build_analyzer; t='๋ด๋น์ ๊น์ฒ ์(010-1234-5678)์๊ฒ ๋ฌธ์. ์ฃผ๋ฏผ๋ฒํธ 900101-1234567'; [print(' ', r.entity_type, t[r.start:r.end], round(r.score,4)) for r in build_analyzer().analyze(text=t, language='ko')]"
# PERSON ๊น์ฒ ์ 0.9999 / KR_RRN 900101-1234567 0.9999 / PHONE_NUMBER 010-1234-5678 0.9998
# 2) Anonymizer ์ฐ์ฐ์
docker exec veil python -c "
from veil_pii.presidio import build_analyzer,build_anonymizer,get_operators
t='๋ด๋น์ ๊น์ฒ ์(010-1234-5678)์๊ฒ ๋ฌธ์. ์ฃผ๋ฏผ๋ฒํธ 900101-1234567'
r=build_analyzer().analyze(text=t,language='ko'); a=build_anonymizer()
[print(' ',p,'โ',a.anonymize(text=t,analyzer_results=r,operators=get_operators(p)).text) for p in ('default','partial')]"
# default โ ๋ด๋น์ <PERSON>(<PHONE_NUMBER>)์๊ฒ ๋ฌธ์. ์ฃผ๋ฏผ๋ฒํธ <KR_RRN>
# partial โ ๋ด๋น์ ๊น*์(010-****-5678)์๊ฒ ๋ฌธ์. ์ฃผ๋ฏผ๋ฒํธ 900101-*******
# 3) ์ํธํ์ ๋ณตํธํ (hash ์ ๋ฌ๋ฆฌ ์๋ฌธ ๋ณต์ ๊ฐ๋ฅ)
docker exec veil python -c "
from veil_pii.presidio import build_analyzer,build_anonymizer
from presidio_anonymizer import DeanonymizeEngine
from presidio_anonymizer.entities import OperatorConfig
K='0123456789abcdef0123456789abcdef'
t='๋ด๋น์ ๊น์ฒ ์(010-1234-5678)์๊ฒ ๋ฌธ์'
r=build_analyzer().analyze(text=t,language='ko')
e=build_anonymizer().anonymize(text=t,analyzer_results=r,operators={'DEFAULT':OperatorConfig('encrypt',{'key':K})})
d=DeanonymizeEngine().deanonymize(text=e.text,entities=e.items,operators={'DEFAULT':OperatorConfig('decrypt',{'key':K})})
print('๋ณต์:',d.text,'| ์ผ์น:',d.text==t)"
# ๋ณต์: ๋ด๋น์ ๊น์ฒ ์(010-1234-5678)์๊ฒ ๋ฌธ์ | ์ผ์น: True
partial ์ REST ๊ฒฝ๋ก์ ์๋ฆฟ์ ๊ท์น์ ๋ง์ถฐ ๋์์ต๋๋ค. ๋ ๊ฒฝ๋ก์ ๋ถ๋ถ ๋ง์คํน ๊ฒฐ๊ณผ๊ฐ ๋ฌ๋ผ์ง๋ฉด ๊ฐ์ฌ ๋์กฐ๊ฐ ์ด๊ธ๋๊ธฐ ๋๋ฌธ์
๋๋ค. default ์ hash ์ ์ถ๋ ฅ ํ๊ธฐ๋ Presidio ์ชฝ์ด ๋ค๋ฆ
๋๋ค(๊บพ์ ๊ธฐํธ, ์ ์ฒด SHA-256).
๋ ์ด๋ฏธ์ง๋ฅผ ์ง์ ์ฌ ๋ดค์ต๋๋ค(Apple Silicon, 74์ ๋ฌธ์ฅ 20ํ).
| slim | presidio | |
|---|---|---|
| ํ์ง(์ค์๊ฐ) | 13 ms | 13 ms |
| ๋ฉ๋ชจ๋ฆฌ | 304 MB | 360 MB |
| ์ด๋ฏธ์ง(์์ถ) | 235 MB | 300 MB |
ํ์ง ์๋๋ ๊ฐ๊ณ ๋ฉ๋ชจ๋ฆฌ๋ง 56MB ์ ๋ ๋ ์๋๋ค.
zsh ์์ ์ฌ๋ฌ ์ค์ง๋ฆฌ heredoc ์ ๋ถ์ฌ ๋ฃ์ผ๋ฉด ํฐ๋ฏธ๋์ bracketed paste ์ ์ด๋ฌธ์๊ฐ ์์ฌ ๋ค์ด๊ฐ zsh: bad pattern: [200~docker ๊ฐ ๋ ์ ์์ต๋๋ค. ์ ์์๋ python -c "..." ํ ๋ฉ์ด๋ฆฌ๋ผ ์ด ๋ฌธ์ ๋ฅผ ํ์ง ์์ต๋๋ค. heredoc ์ ์ฐ์
์ผ ํ๋ค๋ฉด docker exec -i veil python < script.py ์ฒ๋ผ ํ์ผ๋ก ๋๊ธฐ์๋ฉด ๋ฉ๋๋ค. ์ด๋ -i ๋ฅผ ๋นผ๋ฉด ์ถ๋ ฅ์ด ๋น์ด ๋์ต๋๋ค.
๋ผ๋ฒจ (32)
| ๊ทธ๋ฃน | ๋ผ๋ฒจ |
|---|---|
| ์ฌ๋ยท์กฐ์ง | PERSON ORGANIZATION USER_ID |
| ์ฐ๋ฝ์ฒยท์์น | PHONE EMAIL ADDRESS ZIPCODE URL IPADDRESS MACADDRESS PORT |
| ํ๊ตญ ์ ์ ์๋ณ์ | RRN(์ฃผ๋ฏผ๋ฒํธ) FRN(์ธ๊ตญ์ธ๋ฑ๋ก๋ฒํธ) CI IPIN PASSPORT DRIVER_LICENSE BUSINESS_ID(์ฌ์
์๋ฒํธ) SSN |
| ๊ธ์ต | CARD_NUMBER CARD_EXPIRY CVC VIRTUAL_CARD_NUMBER ACCOUNT_NUMBER TRANSACTION_APPROVAL_ID |
| ๊ธฐ๊ธฐยท๊ฐ์ | IMEI DEVICE_SERIAL SUBSCRIBER_ID VEHICLE_PLATE |
| ๊ธฐํ | DATE GENERIC_ID SECRET |
BCCard ๊ณต๊ฐ ๋ฐ์ดํฐ์ 29์ข
์ ์ฐจ๋๋ฒํธ(VEHICLE_PLATE), ๊ฐ์
๋ฒํธ(SUBSCRIBER_ID), ๋จ๋ง ์ผ๋ จ๋ฒํธ(DEVICE_SERIAL) ๋ฅผ ์ถ๊ฐํ์ต๋๋ค. ํ๊น
์ BIOES ๋ฐฉ์์ด๋ผ ์ค์ ํด๋์ค ์๋ 129๊ฐ์ด๊ณ , ๋ผ๋ฒจ ๋งคํ์ config.json ์ id2label ์ ์์ต๋๋ค.
์ค์ฌ์ฉ ์๋๋ฆฌ์ค
์๋ด์ด๋ ์์์์ ๋์ฌ ๋งํ ๋ฌธ์ฅ 11๊ฐ๋ฅผ 4๊ฐ ๋ชจ๋ธ์ ๋๊ฐ์ด ๋ฃ์ด ๋ดค์ต๋๋ค. ๋งํ ๊ฐ์ / ์ ๋ต ๊ฐ์ ์ด๊ณ ๋ค์ +์ซ์ ๋ ์คํ์
๋๋ค. ๋ชจ๋ธ ๊ฐ ์ฐจ์ด๊ฐ ๋ ํญ๋ชฉ๋ง ์ถ๋ ธ์ต๋๋ค.
| ์๋๋ฆฌ์ค | Veil | BCCard 1.4B | FrameByFrame 1.4B | Azure |
|---|---|---|---|---|
| ์ค๋ฐ๊ฟ์ผ๋ก ๊ฐ๋ผ์ง ์ฃผ์ + ์ฐํธ๋ฒํธ | 4/4 | 3/4 +2 | 2/4 +6 | 2/4 +2 |
| ์ฌ์ ์๋ฒํธยทCIยท์ฐจ๋๋ฒํธยท๊ฐ์ ๋ฒํธ ์์ | 5/5 | 1/5 +6 | 1/5 +6 | 1/5 +1 |
์กฐ์ฌ ๋ถ์ ๋ ์งยท์ ํยท์ด๋ฉ์ผ (15์ผ์, 5432๋ก) |
4/4 | 3/4 | 3/4 | 4/4 |
์งํจ ๋ถ์ ์ด๋ฆยท์์ด๋ยท์ด๋ฉ์ผ (์ต์์ ๋๋ฆฌ) |
3/3 | 1/3 | 3/3 | 2/3 |
| ๊ธด ์๋ด ๋ก๊ทธ 595์ (์ฐฝ ๊ฒฝ๊ณ ๋๊น) | 16/18 | 14/18 +6 | 5/18 +3 | 8/18 +10 |
| ์ด๋ฆ ๋ฎ์ ์ผ๋ฐ๋ช ์ฌ โ ์ ๋ต์ ๋ฌด๊ฒ์ถ | ์คํ 2 | ์คํ 2 | ์คํ 2 | 0 |
| ์ฝ๋ยทํด์ยทISBN โ ์ ๋ต์ ๋ฌด๊ฒ์ถ | ์คํ 2 | ์คํ 4 | ์คํ 5 | 0 |
ํ๋ฆฐ ๊ฒ๋ ๊ฐ์ด ์ ์ต๋๋ค. ์ฃผ์ ๋์ 12์ธต ์ ๋น ๋จ๋ ธ๊ณ , ์๋ฌธ ์กฐ์ง๋ช
์ ๋ชป ์ก์๊ณ , ๋๊ดํธ ์ ISO ๋ ์ง์ ์ง๋๋ฌ 25์ผ ๋ ๋์ณค์ต๋๋ค. ๋ฐ๋๋ก ์ ๊ฒฐ ์ ์ฌ๋ ์ด๋ฆ์ผ๋ก, ์ปค๋ฐ ํด์๋ฅผ SECRET ์ผ๋ก, ISBN ์ ACCOUNT_NUMBER ๋ก ์ก๋ ์คํ๋ ์์์ต๋๋ค.
๋ฐ์ดํฐ์
์ง์ ๋ง๋ ๋ฐ์ดํฐ ๋ ๊ฐ์ง๋ฅผ ๋ฐ๋ก ๊ณต๊ฐํ์ต๋๋ค.
1T/veil-pii-ko-synth โ ์ด ๋ชจ๋ธ์ด ํ์ตํ ํฉ์ฑ ๋ฐ์ดํฐ 26,875ํ๊ณผ ์ ๋ฒค์น๋งํฌ ํ์ ํฉ์ฑ heldout 670ํ, ๊ทธ๋ฆฌ๊ณ ๊ฐ์ ์ฑ์ฐ๊ธฐ ์ ํ ํ๋ฆฟ 10,133๊ฐ์ ๋๋ค. ํ์ต ๋น์ ํ์ผ์์ ๊ทธ๋๋ก ๊บผ๋ธ ๊ฒ์ด๋ผ ๊ณต๊ฐ ์์น์ ๋ฐ๋ก ๋ง์ถฐ ๋ณด์ค ์ ์์ต๋๋ค. ๋ฌธ์ฅ์ LLM ์ผ๋ก ํ ํ๋ฆฟ์ ๋ง๋ค๊ณ , ๊ฐ์ธ์ ๋ณด ๊ฐ์ ๊ท์น ๊ธฐ๋ฐ ์์ฑ๊ธฐ๋ก ์ฑ์ ์ต๋๋ค.
1T/veil-pii-ko-stress โ ํ๊ธฐ ๋ณํ๊ณผ ๋ฌธ์ ๊ธธ์ด๋ฅผ ๋ฐ๊ฟ ๊ฐ๋ฉฐ ์ด๋์ ๋ฌด๋์ง๋์ง ๋ณด๋ ค๊ณ ๋ง๋ ํ๊ฐ์ ์ ๋๋ค.
| ๊ตฌ์ฑ | ๋ด์ฉ | ํ |
|---|---|---|
stress |
ํ์ดํโ์ ยท๊ณต๋ฐฑ, ๊ตฌ๋ถ์ ์ ๊ฑฐ, ์ ๊ฐ ์ซ์, ๊ธ์ ์ฌ์ด ๊ณต๋ฐฑ 6์ข + ๊ฐ ๋์กฐ๊ตฐ | 5,376 |
longdoc |
์ ๋ต ์คํฌ(1,604)์ ๊ทธ๋๋ก ๋๊ณ ๊ธธ์ด๋ง 200~3,000์๋ก ๋๋ฆฐ ๋ฌธ์ | 1,301 |
leakage |
KDPII train/test ์ค๋ณต์ ๋บ ๋ถํ ๊ณผ ์ค๋ณต ํ๋ง ๋ชจ์ ๋ถํ | 9,782 |
์ ๋ต ์คํฌ์ ๊ทธ๋๋ก ๋๊ณ ํ๋ฉดํ๋ง ๋ฐ๊ฟ ์คํ์ ์ ๋ค์ ๊ณ์ฐํ๊ธฐ ๋๋ฌธ์, ๋ผ๋ฒจ์ ์๋ก ๋ฌ์ง ์์๋ ๊ฐ์ด ๊ณง ์๋ณธ ๋๋น ํ๋ฝํญ์ ๋๋ค. ์ ํ๊ธฐ ๋ณํยท๋ฌธ์ ๊ธธ์ด ์ ์ ์์น๊ฐ ์ด ํ๊ฐ์ ์ผ๋ก ์ฐ ๊ฒ์ ๋๋ค. ์๋ฌธ์ KDPII(CC-BY-4.0) ์ด๊ณ ๋ณํ ์ค๊ณ์ ๋ถํ ์ ์๊ฐ ์ด์ชฝ ๋ชซ์ ๋๋ค. ๋ค๋ฅธ ํ๊ตญ์ด PII ๋ชจ๋ธ์๋ ๊ทธ๋๋ก ์ฐ์ค ์ ์์ต๋๋ค.
์ฌํ
git clone https://github.com/WontaeKim89/veil-pii-ko-lite && cd veil-pii-ko-lite
pip install -r scripts/requirements-repro.txt
bash scripts/reproduce_claims.sh release # ๊ณต๊ฐ ๋ฐ์ดํฐ ๋ค์ด๋ก๋ โ Veil INT8/fp32 ยท BCCard ๋ฒ ์ด์ค๋ผ์ธ ํ๊ฐ โ ํ (CPU 8์ค๋ ๋ ~40๋ถ)
ํ์ผ
| ํ์ผ | ์ค๋ช |
|---|---|
model.safetensors + config.json |
fp32 ๊ฐ์ค์น (transformers) |
model.int8.onnx |
weight-only INT8 ONNX (ORT โฅ 1.28), fp16 ์๋ฒ ๋ฉ |
veil.py |
๋์ฝ๋ (Veil ํด๋์ค), ๋จ์ผ ํ์ผ |
tokenizer.json vocab.txt โฆ |
KoELECTRA ํ ํฌ๋์ด์ |
labels.yaml |
32 ๋ผ๋ฒจ ์คํค๋ง, KDPII ๋งคํ |
EVIDENCE.md |
์ฃผ์ฅ๋ณ ๊ทผ๊ฑฐ์ ์ธก์ ์กฐ๊ฑด |
PER_LABEL.md |
๋ผ๋ฒจ๋ณ P/R/F1 โ ๋ณธ ๋ชจ๋ธ ยท BCCard ยท Azure ยท FrameByFrame ยท ์ ๊ท์ ๋น๊ต |
ROBUSTNESS.md |
ํ๊ธฐ ๋ณํ ยท ๋ฌธ์ ๊ธธ์ด ์คํธ๋ ์ค ๊ฒฐ๊ณผ |
eval_*.json baselines/ stress/ regex/ |
per-entity ์๋ณธ ์์น |
reproduce_claims.sh requirements-repro.txt |
์ฌํ ์คํฌ๋ฆฝํธ |
์ธ์ฉ
@misc{veil-pii-ko-lite-2026,
title = {Veil-PII-Ko-Lite: a 110M Korean PII detector with 32 labels},
author = {Kim, Wontae},
year = {2026},
url = {https://huggingface.co/1T/veil-pii-ko-lite}
}
๋ผ์ด์ ์ค ยท ๊ณ ์ง
Apache 2.0.
- ํ์ต ๋ฐ์ดํฐ: BCCard/privacy-filter-openpii-masking (CC-BY-4.0), KDPII (CC-BY-4.0, FeiยทKang et al., IEEE Access 2024), ์์ฒด ํฉ์ฑ.
- ๋ฐฑ๋ณธ: monologg/koelectra-base-v3-discriminator (Apache 2.0).
- ๋น๊ต ๋์: BCCard/MoAI-Privacy-Filter-INT8, FrameByFrame/privacy-filter-korean (Apache 2.0), Azure AI Language PII (API 2024-11-01).