wt-e5-small-ko-insurance-v1
๋ณดํ ๋๋ฉ์ธ retrieval ์ ํนํํ ํ๊ตญ์ด ์๋ฒ ๋ฉ LoRA ์ด๋ํฐ. CPU ๋จ๋ ์ด์์ ์ ์ ๋ก ๋ง๋ค์์ต๋๋ค.
๊ฐ์
dragonkue/multilingual-e5-small-ko-v2 (118M, 384-dim, max_seq 512) ์ LoRA ์ด๋ํฐ๋ฅผ ๋ถ์ฌ ๋ณดํ ์๋ด ์ง์ โ tool / ๋ฌธ์ retrieval ์ฑ๋ฅ์ ์ฌ๋ฆฐ ๋ชจ๋ธ์
๋๋ค.
384-dim ยท CPU p50 13 ms ๋ฅผ ์ ์งํ๋ฉด์, ๋๋ฉ์ธ ํ๊ฐ์
์์ nDCG@10 ์ 0.630 โ 0.773 ์ผ๋ก ์ฌ๋ ธ์ต๋๋ค.
1024-dim ์ด์ ๋ชจ๋ธ(KURE-v1, BGE-M3)๋ ํ๋ณด์์ผ๋ CPU latency ๊ฐ 6~7๋ฐฐ๋ผ ๊ฒฝ๋ base ๋ฅผ ํํ๊ณ ๋ถ์กฑํ ์ ํ๋๋ fine-tuning ์ผ๋ก ๋ฉ์ฐ๋ ๋ฐฉํฅ์ ๊ณจ๋์ต๋๋ค.
| Base | dragonkue/multilingual-e5-small-ko-v2 (118M, 384-dim, max_seq 512) |
| Adapter | LoRA r=8, alpha=16, target Q/K/V/dense, ์ ์ฒด 12 layer |
| Trainable params | 669,696 (base ๋๋น 0.57%) ยท ์ด๋ํฐ 2.7 MB |
| Loss | MultipleNegativesRankingLoss, scale 20 (temperature 0.05) |
| ํ์ต ๋ฐ์ดํฐ | 18K triplet โ ๋๋ฉ์ธ ํฉ์ฑ query 2.5K + klue/mrc 10K + klue/sts (labelโฅ3.5) 7.5K |
| ํ์ต | 4 epoch, lr 3e-5, batch 16, in-batch 15 + hard negative 6 |
| CPU latency p50 | 13 ms (base 7 ms) |
๋ฒค์น๋งํฌ
base / ๋ณธ ๋ชจ๋ธ / OpenAI text-embedding-3-large ๋ฅผ ๊ฐ์ ์ฝํผ์คยท๊ฐ์ ์ค์ฝ์ด๋ฌ๋ก ์ธก์ ํ์ต๋๋ค.
์ผ๋ฐ ๋๋ฉ์ธ tool retrieval โ heegyu/glaive-function-calling-v2-ko (๊ณต๊ฐ ๋ฐ์ดํฐ)
ํ์ตยทholdout ๊ณผ ์์ ํ ๋ ๋ฆฝ. corpus = unique function description 195๊ฑด, query = ์ฒซ user ๋ฐํ 1,473๊ฑด.
| Metric | base e5 | ๋ณธ ๋ชจ๋ธ | OpenAI 3-large |
|---|---|---|---|
| nDCG@10 | 0.5175 | 0.5283 | 0.5193 |
| Recall@1 | 0.3150 | 0.3150 | 0.3015 |
| Recall@3 | 0.5390 | 0.5601 | 0.5565 |
| Recall@10 | 0.7312 | 0.7502 | 0.7417 |
| MRR@3 | 0.4160 | 0.4249 | 0.4196 |
๋ณดํ ํนํ ํ์ต ํ์๋ ์ผ๋ฐ ํ๊ตญ์ด tool retrieval ์ด ๋จ์ด์ง์ง ์์์ต๋๋ค (catastrophic forgetting ์์).
๋ณดํ ๋๋ฉ์ธ (๋น๊ณต๊ฐ ํ๊ฐ์ )
| Metric | base e5 | ๋ณธ ๋ชจ๋ธ | OpenAI 3-large |
|---|---|---|---|
| nDCG@10 (104 query) | 0.630 | 0.773 | 0.634 |
| Recall@1 | 0.385 | 0.596 | 0.337 |
| Recall@3 | 0.562 | 0.716 | 0.635 |
| MRR@3 | 0.492 | 0.670 | 0.463 |
| nDCG@10 (holdout 1,056 query) | 0.8886 | 0.9053 | 0.8766 |
holdout ์ ํ์ต์ ์ฐ์ง ์์ ํฉ์ฑ query 1,056๊ฑด (์ ๊ท sector 25๊ฑด ํฌํจ). 95% CI ๋น์ค์ฒฉ. ํ๊ฐ ์ฝํผ์ค์ query ๋ ๋น๊ณต๊ฐ๋ผ ์ฌํ ๋ถ๊ฐ โ ๊ณต๊ฐ ๊ฒ์ฆ์ด ํ์ํ๋ฉด ์ glaive ํ๋ฅผ ๋ณด์ธ์.
Quick Start
pip install sentence-transformers peft
from peft import PeftModel
from sentence_transformers import SentenceTransformer
m = SentenceTransformer("dragonkue/multilingual-e5-small-ko-v2")
m[0].auto_model = PeftModel.from_pretrained(m[0].auto_model, "1T/wt-e5-small-ko-insurance-v1")
docs = ["์ ์ง๋จ ์ ์ง๊ธ๋๋ ์ง๋จ๋น ๋ณดํ๊ธ์ ์กฐํํ๋ค",
"์ธ์์ฌ์ฌ ๊ฐ์ด๋๋ผ์ธ ์กฐํ",
"์ค๋ ์ ์ฌ ๋ญ ๋จน์๊น"]
q = m.encode(["query: ๋น๋จ ์๋๋ฐ ์์ง๋จ๋น ์ผ๋ง์ผ?"], normalize_embeddings=True)
p = m.encode([f"passage: {d}" for d in docs], normalize_embeddings=True)
print((q @ p.T).round(3)) # [[0.529 0.165 0.251]]
e5 prefix ํ์์
๋๋ค. query ๋ "query: ", passage ๋ "passage: " ๋ฅผ ์์ ๋ถ์ด์ธ์. ์๋ตํ๋ฉด 3~5pt ์ํด์
๋๋ค.
๋์กฐ ํ์ต ๊ฒฐ๊ณผ cosine ์ ๋๊ฐ์ base ๋ณด๋ค ๋ฎ๊ฒ ๋์ต๋๋ค (์ ์์ base: 0.641 / 0.401 / 0.424). ์ ๋ต๊ณผ ์ค๋ต์ ๊ฒฉ์ฐจ๊ฐ ๋ฒ์ด์ง๋ ์ชฝ์ด๋ผ ์๊ณ๊ฐ์ ๊ทธ๋๋ก ์ฐ์ง ๋ง๊ณ ์์ ๋๋ ์ฌ์บ๋ฆฌ๋ธ๋ ์ด์ ๋ ์๊ณ๊ฐ์ผ๋ก ํ๋จํ์ธ์.
vLLM ๋ฑ ์ด๋ํฐ๋ฅผ ์ง์ ๋ชป ์ฝ๋ ๋ฐํ์์ ๋ณํฉํด์ ์ฐ์ธ์.
m[0].auto_model = m[0].auto_model.merge_and_unload()
m.save("wt-e5-small-ko-insurance-v1-merged")
ํ๊ณ
- max_seq 512. ๊ธด ์ฒญํฌ ์ธ๋ฑ์ฑ์๋ 1T/wt-kure-insurance-v1 ์ด ๋ง์ต๋๋ค.
- ๋๋ฉ์ธ ํ์ต ๋ฐ์ดํฐ๊ฐ ์งง์ ๋ฌธ์ฅ (์ง์ โ tool/๋ฌธ์ description) ์์ฃผ๋ผ, ๊ธด passage ๊ฐ ์ ์ฌ๋์๋ ์ด์ ์ด ์์ต๋๋ค.
- ์ด๋ํฐ๋ง ๋ฐฐํฌํฉ๋๋ค. tokenizer ยท pooling ์ค์ ์ base ๋ฅผ ๊ทธ๋๋ก ์๋๋ค (mean pooling + L2 norm).
์ธ์ฉ
@misc{wt-e5-small-ko-insurance-v1,
title = {wt-e5-small-ko-insurance-v1: a Korean insurance-domain retrieval LoRA for multilingual-e5-small-ko},
author = {Kim, Wontae},
year = {2026},
url = {https://huggingface.co/1T/wt-e5-small-ko-insurance-v1}
}
๋ผ์ด์ ์ค ยท ๊ณ ์ง
์ด๋ํฐ Apache-2.0. base dragonkue/multilingual-e5-small-ko-v2 Apache-2.0.
์ผ๋ฐ ๋๋ฉ์ธ ํ์ต ๋ฐ์ดํฐ klue/mrc, klue/sts (CC-BY-SA-4.0). ๋๋ฉ์ธ ํ์ต ๋ฐ์ดํฐ๋ ๋น๊ณต๊ฐ์ด๋ฉฐ ๋ณธ repo ์ ํฌํจ๋์ง ์์ต๋๋ค.