체온 임베딩 0.6B: 작은 크기로 MMTEB 3위에 오른 다국어 임베딩 모델

체온 임베딩 0.6B는 문장을 1,024차원 벡터로 바꾸는 다국어 임베딩 모델이에요. 한 번에 32,768토큰까지 읽고, 다국어 임베딩 벤치마크 MMTEB의 128개 과제 평균 71.73으로 13배 큰 Qwen3-Embedding-8B를 앞섰어요. 영어 질문 하나로 다섯 언어의 답을 찾는 예제와, 공개 데이터셋 AutoRAG의 문단 720개에서 정답을 1위로 찾은 사례를 코드와 함께 소개해요.

체온 임베딩 0.6B를 공개했어요. 문장 하나를 1,024차원 벡터 하나로 바꾸는 다국어 텍스트 임베딩 모델이에요. 한 번에 32,768토큰까지 읽고, transformers의 AutoModel로 바로 불러 쓸 수 있어요.

크기는 0.6B지만 성능은 훨씬 큰 모델들과 겨뤄요. 다국어 임베딩 벤치마크 MMTEB에서 128개 과제 평균 71.73으로, 이 과제를 모두 보고한 모델 가운데 3위에 올랐어요. 위에 있는 두 모델은 27B와 12B이고, 13배 큰 Qwen3-Embedding-8B와 Gemini Embedding이 그 아래에 있어요.

한눈에 보기

항목 내용
파라미터 596M (0.6B)
출력 1,024차원 단위 벡터 (내적 = 코사인 유사도)
최대 입력 32,768토큰
언어 다국어
가중치 float32, Hugging Face에 공개
라이선스 CC-BY-NC-4.0

MMTEB: 0.6B로 3위

MMTEB(Multilingual, v2)는 수백 개 언어에 걸친 131개 과제로 임베딩 모델을 평가하는 벤치마크예요. 검색뿐 아니라 번역문 찾기, 분류, 군집, 문장 유사도까지 두루 봐요. 아래는 그중 128개 과제의 평균이에요. 체온 임베딩은 공식 mteb 하네스로 직접 쟀고(float32, 최대 32,768토큰), 다른 모델은 공식 MTEB 결과 저장소의 점수예요.

순위 모델 크기 평균 (128개 과제)
1 microsoft/harrier-oss-v1-27b 27B 75.29
2 tencent/KaLM-Embedding-Gemma3-12B-2511 12B 73.32
3 체온 임베딩 0.6B 0.6B 71.73
4 Qwen/Qwen3-Embedding-8B 8B 71.56
5 Bytedance/Seed1.6-embedding-1215 비공개 71.23
6 Qwen/Qwen3-Embedding-4B 4B 70.40
7 nvidia/llama-embed-nemotron-8b 8B 70.38
8 microsoft/harrier-oss-v1-0.6b 0.6B 69.97
10 google/gemini-embedding-001 비공개 69.29
21 Qwen/Qwen3-Embedding-0.6B 0.6B 65.24

8B 이하 모델 가운데서는 가장 높아요. 같은 0.6B인 Qwen3-Embedding-0.6B보다는 6.49점 높아요.

과제 유형별로 보면 다국어 검색에 바로 쓰이는 유형에서 13배 큰 Qwen3-Embedding-8B를 앞섰어요. 언어가 다른 두 문장이 같은 뜻인지 찾는 번역문 찾기, 그리고 검색과 분류예요.

체온 임베딩 0.6B가 8B 모델을 앞선 과제 유형MMTEB(Multilingual, v2) 128개 과제 중 유형별 평균, 괄호 안은 과제 수
체온 임베딩 0.6BQwen3-Embedding-8B020406080100 체온 임베딩 0.6B · 번역문 찾기 (13): 83.3683.36체온 임베딩 0.6B · 분류 (43): 76.2576.25체온 임베딩 0.6B · 다중 레이블 분류 (4): 43.9243.92체온 임베딩 0.6B · 검색 (17): 72.2072.20Qwen3-Embedding-8B · 번역문 찾기 (13): 80.8980.89Qwen3-Embedding-8B · 분류 (43): 74.0074.00Qwen3-Embedding-8B · 다중 레이블 분류 (4): 34.6334.63Qwen3-Embedding-8B · 검색 (17): 70.8970.89 번역문 찾기(13)분류(43)다중 레이블 분류(4)검색(17)

과제 유형 아홉 가지의 전체 표는 모델 페이지에 있어요.

다국어: 언어가 달라도 같은 뜻을 찾아요

모델 카드의 예제를 그대로 돌려 볼게요. 영어 질문 하나에 문장 여덟 개를 섞어 넣었어요. 다섯 개는 질문에 답하는 같은 내용을 영어·중국어·아랍어·일본어·한국어로 쓴 문장이고, 나머지 셋은 여권 분실 신고 안내와 질문과 상관없는 문장 두 개예요.

import torch
from transformers import AutoModel, AutoTokenizer

repo = "cheonai/cheon-embedding-0.6b-v1"
tok = AutoTokenizer.from_pretrained(repo)
model = AutoModel.from_pretrained(repo, trust_remote_code=True, torch_dtype=torch.float32)
model.eval()

query = "How do I renew my passport online?"
passages = [
    "여권을 잃어버렸다면 바로 분실 신고를 해야 합니다.",
    "Passports can be renewed online through the government portal.",
    "富士山は日本で一番高い山です。",
    "여권 재발급은 정부 포털에서 온라인으로 신청할 수 있습니다.",
    "يمكن تجديد جواز السفر عبر الإنترنت من خلال البوابة الحكومية.",
    "القاهرة هي عاصمة مصر.",
    "护照可以通过政府门户网站在线申请换发。",
    "パスポートの更新は、政府のポータルサイトからオンラインで申請できます。",
]

query_vector = model.encode(
    [query], tok,
    instruction="Given a web search query, retrieve relevant passages that answer the query",
)
passage_vectors = model.encode(passages, tok)
scores = (query_vector @ passage_vectors.T)[0]  # 벡터 길이가 1이라 내적이 곧 코사인 유사도예요

for i in scores.argsort(descending=True).tolist():
    print(f"{scores[i]:.3f}  {passages[i]}")

결과는 이래요.

순위 언어 문장 유사도
1 영어 Passports can be renewed online through the government portal. 0.676
2 중국어 护照可以通过政府门户网站在线申请换发。 0.526
3 아랍어 يمكن تجديد جواز السفر عبر الإنترنت من خلال البوابة الحكومية. 0.472
4 일본어 パスポートの更新は、政府のポータルサイトからオンラインで申請できます。 0.465
5 한국어 여권 재발급은 정부 포털에서 온라인으로 신청할 수 있습니다. 0.443
6 한국어 여권을 잃어버렸다면 바로 분실 신고를 해야 합니다. 0.218
7 아랍어 القاهرة هي عاصمة مصر. 0.003
8 일본어 富士山は日本で一番高い山です。 -0.041

다섯 언어로 쓴 답이 1위부터 5위까지 차지했고, 다섯 번째 답과 여섯 번째 문장 사이에는 점수 차가 크게 벌어졌어요. 여권 이야기지만 질문에 답하지 않는 분실 신고 안내는 6위, 상관없는 두 문장은 맨 아래예요. 언어가 아니라 뜻으로 줄을 세운다는 뜻이에요. 질문을 중국어·일본어·아랍어로 바꿔 넣어도 다섯 언어의 답이 모두 나머지 세 문장보다 위에 왔어요.

설치 없이 이 결과를 보고 싶다면 체온 임베딩 플레이그라운드에서 같은 예제를 바로 돌려 볼 수 있어요.

실전: 문단 720개에서 정답 찾기

공개 RAG 평가 데이터 AutoRAG로 실제 문서 검색을 해 봤어요. 금융·공공·법률·커머스 PDF를 페이지 단위로 자른 한국어 문단 720개와 사람이 만든 질문 114개로 되어 있고, 질문마다 정답 문단이 하나씩 있어요. MTEB에도 AutoRAGRetrieval이라는 이름으로 들어가 있어서 Hugging Face에서 바로 받을 수 있어요(MIT 라이선스).

착한가격업소 활성화를 위한 주요 지원책에는 어떤 것들이 있으며, 이를 통해 어떠한 결과를 도모하려는 것인지 설명하세요.

정답은 행정안전부 2024년 업무계획의 한 페이지예요. 거기에는 "(착한가격업소 활성화) 지정 확대('23년말 7,172개→24년 1만 개 이상) 및 배달료 지원, 이용객 인센티브 제공(캐시백 등)으로 외식물가 안정 도모"라고 적혀 있어요. 질문이 묻는 '지원책'은 배달료 지원과 캐시백으로, '도모하려는 결과'는 외식물가 안정으로 표현이 바뀌어 있죠. 체온 임베딩은 문단 720개 가운데 이 페이지를 1위로 찾았어요.

네 분야에서 고른 질문도 모두 정답 문단을 1위로 찾았어요.

분야 질문 체온 임베딩
공공 착한가격업소 활성화를 위한 지원책과 기대 효과 1위
공공 2024년까지 교체할 CCTV 수와 관제 범위에 미칠 영향 1위
커머스 이커머스 소비자가 가장 관심을 두는 정보와 선호하는 채널 1위
법률 구 관세법 제30조에 따른 과세가격의 조정 방식 1위
금융 시중은행·지방은행·인터넷은행의 인가 요건과 절차의 차이 1위

문단은 체온 임베딩 토크나이저로 세면 평균 584토큰, 가장 긴 것은 1,681토큰이에요. 32,768토큰까지 읽으니까 문단을 자르지 않고 통째로 임베딩했어요. 돌린 코드는 이게 전부예요.

from datasets import load_dataset

name = "mteb/AutoRAGRetrieval"
corpus = load_dataset(name, "corpus", split="test")
queries = load_dataset(name, "queries", split="test")
qrels = load_dataset(name, "qrels", split="test")

doc_ids = corpus["_id"]
answer = dict(zip(qrels["query-id"], qrels["corpus-id"]))  # 질문마다 정답 문단 하나

model = model.to("cuda")  # 문단이 720개라 GPU를 권해요
INSTRUCTION = "Given a web search query, retrieve relevant passages that answer the query"

# 문단은 한 번만 임베딩해서 저장해 두고, 질문만 그때그때 임베딩해요
doc_vectors = model.encode(list(corpus["text"]), tok)
query_vectors = model.encode(list(queries["text"]), tok, instruction=INSTRUCTION)

scores = query_vectors @ doc_vectors.T  # 질문 114개 × 문단 720개
ranked = {
    q["_id"]: [doc_ids[j] for j in torch.argsort(scores[i], descending=True).tolist()]
    for i, q in enumerate(queries)
}

for query_id in ["33_public", "30_public", "98_commerce", "72_law", "0_finance"]:
    print(query_id, ranked[query_id].index(answer[query_id]) + 1)

# 33_public 1
# 30_public 1
# 98_commerce 1
# 72_law 1
# 0_finance 1

encode는 길이가 비슷한 문장끼리 묶어서 처리하고, 벡터는 넣은 순서대로 돌려줘요. 저희가 쓴 GPU에서는 문단 720개와 질문 114개를 임베딩하는 데 30초가 걸리지 않았어요. 문단 벡터는 미리 만들어 두면 되니까, 검색할 때는 질문 하나를 임베딩하고 벡터를 곱하는 일만 남아요.

지시문으로 할 일을 알려 줘요

체온 임베딩은 질문 앞에 할 일을 한 줄로 적은 지시문을 붙여서 써요. 같은 모델로 검색도 하고, 비슷한 문장도 찾고, 번역문도 찾을 수 있어요. 문서 쪽에는 아무것도 붙이지 않아요.

Instruct: {지시문}
Query:{질문}

Query: 뒤에는 공백이 없어요. encode(..., instruction=...)가 이 형식을 대신 만들어 줘요. 모델 카드에 있는 지시문 예시는 이래요.

쓰임 지시문
웹 검색 Given a web search query, retrieve relevant passages that answer the query
비슷한 문장 찾기 Retrieve semantically similar text
번역문 찾기 Retrieve parallel sentences
분류 Classify the sentiment of a given review

시작하기

모델은 Hugging Face에 있고, 위의 코드처럼 transformers만으로 불러 쓸 수 있어요. 바로 돌려 볼 수 있는 예제는 GitHub의 체온 임베딩 쿡북에 있어요. embed_and_score.py는 이 글의 다국어 예제를 유사도 순으로 보여 줘요.

git clone https://github.com/cheon-ai-official/cheon-embedding
cd cheon-embedding
pip install -e .
python cookbook/00_quickstart/embed_and_score.py

이 글의 AutoRAG 코드를 그대로 돌리려면 datasets, transformers, torch가 필요해요. 모델은 CC-BY-NC-4.0 라이선스라 연구와 평가에는 자유롭게 쓰실 수 있고, 서비스에 넣거나 API로 쓰고 싶다면 문의해 주세요.