Granite Embedding 다국어 R2 릴리스: 32K 컨텍스트를 지원하는 오픈 Apache 2.0 다국어 임베딩

Granite Embedding 다국어 R2 릴리스: 32K 컨텍스트를 지원하는 오픈 Apache 2.0 다국어 임베딩

TL;DR

IBM Granite은 ModernBERT 기반의 두 가지 Apache 2.0 다국어 임베딩 모델을 공개했습니다. 97M 파라미터의 컴팩트 모델은 MTEB 다국어 검색(60.3)에서 100M 미만의 모든 오픈 멀티링구얼 임베더를 능가하고, 311M 풀 사이즈 모델은 동일 벤치마크에서 65.2점을 기록해 500M 파라미터 이하 오픈 모델 중 2위를 차지했으며 Matryoshka를 지원합니다. 두 모델 모두 200개 이상의 언어를 커버하고, 52개 언어와 프로그래밍 코드를 대상으로 튜닝되었으며, 32K 토큰 컨텍스트(전 모델 대비 64배)를 처리합니다.

Enterprise‑Ready by Design

두 모델은 IBM이 직접 선별·정제한 데이터셋, 공개 데이터, 내부에서 생성·합성한 데이터를 혼합해 학습되었습니다. 학습에 사용된 공개 웹 데이터는 IBM이 개발한 품질·중복제거·거버넌스 프로세스를 통해 위험을 최소화하도록 선택·필터링되었습니다. 모델은 MS‑MARCO 학습 데이터와 비상업적 라이선스 제한이 명시된 데이터셋을 사용하지 않았습니다. 학습은 공개 웹 콘텐츠에서 파생된 IBM‑curated 데이터셋인 GneissWeb을 활용했으며, IBM의 데이터 준비·거버넌스 도구와 추가 IBM‑curated 및 기타 공개 소스를 함께 사용했습니다. 데이터셋은 라이선스, 소유권 신호, 개인 데이터 위험 등을 평가하기 위해 IBM 거버넌스 검토를 거쳐 책임 있는 사용 및 엔터프라이즈 배포에 기여합니다.

A Strong Sub‑100M Multilingual Model

주목할 모델은 granite-embedding-97m-multilingual-r2입니다. 9700만 파라미터로 18개 언어에 걸친 Multilingual MTEB Retrieval에서 60.3점을 기록했으며, 이는 100M 이하 파라미터를 가진 모든 오픈 다국어 임베딩 모델 중 최고 점수입니다. 동일 규모에서 두 번째로 좋은 모델인 multilingual-e5-small은 50.9점으로 9.4점 차이입니다. 직접적인 전 모델과 비교했을 때, 97M R2 모델은 새로운 아키텍처·향상된 학습 데이터·새로운 프루닝 방법론 덕분에 MTEB Multilingual Retrieval에서 +12.2점을 얻었습니다. 풀 사이즈 granite-embedding-311m-multilingual-r2는 동일 벤치마크에서 65.2점을 받아 전 모델 대비 +13.0점을 기록했습니다.

What Changed from R1

Granite Embedding Multilingual R1 모델은 XLM‑RoBERTa 인코더와 512‑토큰 컨텍스트 윈도우를 사용했습니다. R2는 ModernBERT 기반으로 처음부터 재구축되었습니다. ModernBERT는 최근 5년간의 트랜스포머 연구 결과를 반영해 교대형 어텐션 길이, 32K 컨텍스트 윈도우를 가능하게 하는 로터리 포지션 임베딩, 그리고 최신 GPU에서 인코딩 속도를 높이는 Flash Attention 2.0을 지원합니다. 새로운 다국어 토크나이저는 XLM‑RoBERTa의 250K 토큰 vocab과 다릅니다: 311M 모델은 Gemma 3 토크나이저(262K 토큰)를 사용하고, 97M 모델은 GPT‑OSS 토크나이저를 기반으로 180K 토큰의 컴팩트 vocab으로 프루닝해 다국어 커버리지를 유지하면서 임베딩 테이블 파라미터를 크게 줄였습니다.

Training the Full‑Size 311M Model

311M 모델은 22‑layer ModernBERT 인코더와 262K 토큰 다국어 vocab을 갖고, 다단계 파이프라인으로 학습되었습니다:

  1. 지식 증류Granite 3.3 InstructMistral v0.2 Instruct 디코더 모델(텍스트 임베딩용으로 추가 파인튜닝) 등 여러 교사 모델로부터 검색 전용 지식을 인코더에 전달합니다.
  2. 대조 파인튜닝 – 52개 언어와 코드에 걸친 다국어 검색 쌍(관련·하드‑네거티브 패시지)으로 모델이 관련성과 비관련성을 구분하도록 학습합니다.
  3. 모델 병합 – 서로 다른 학습 단계·구성에서 저장된 체크포인트를 병합해 별도 추가 학습 없이 다양한 목표에 최적화된 강점을 결합합니다.
  4. Matryoshka Representation Learning – 768‑차원 임베딩을 512, 384, 256, 128 차원으로 잘라도 품질 손실이 최소화되도록 합니다. 이 결과 모델은 MTEB Multilingual Retrieval에서 65.2점, 전체 평균에서 56.3점을 기록해 R1 대비 평균 +14.5점을 달성했습니다.

Building the Compact 97M Multilingual Model

97M 모델은 vocab 선택과 지식 증류를 결합해 학습되었습니다:

  1. Vocabulary selection – 262K 토큰 vocab을 180K 토큰 vocab으로 축소해 다국어 커버리지를 유지하면서 임베딩 테이블 크기를 크게 줄였습니다.
  2. Knowledge distillation – 여러 교사 모델(Granite 4.1 8B, Mistral Instruct 디코더 등)과 대조 학습을 통해 프루닝된 모델을 파인튜닝해 검색 품질을 향상시켰습니다. 이 접근법은 강력한 교사 모델의 검색 지식을 전달하면서 파라미터를 감소시켜 언어 커버리지를 희생하지 않는 효율적인 컴팩트 모델을 만들었습니다. 결과적으로 97M 모델은 풀 사이즈 모델(65.2점) 대비 약 3배 작은 크기로 60.3점을 기록했습니다.

Benchmark Results

Multilingual Retrieval

모델 크기별 주요 벤치마크 성능 (점수가 높을수록 좋음):

모델 파라미터 활성 파라미터 임베드 차원 MTEB 다국어 검색 (18) 코드 (12) 영어 검색 (10) LongEmbed (6) RaR‑b (17)
F2LLM‑v2‑80M 80M 32M 320 50.1 68.0 47.5 31.7 17.9
multilingual‑e5‑small 118M 22M 384 50.9 53.5 46.5 38.8 20.3
granite‑embedding‑107m‑multilingual (R1) 107M 11M 384 48.1 40.7 47.9 34.3 17.1
paraphrase‑multilingual‑MiniLM‑L12‑v2 118M 22M 384 36.6 23.5 35.9 20.9 10.9
jina‑embeddings‑v5‑text‑nano 212M 113M 768 63.3 71.2 58.8 63.6 25.2
harrier‑oss‑v1‑270m 268M 100M 640 66.4 62.4 52.1 64.9 32.9
multilingual‑e5‑base 278M 86M 768 52.7 52.6 49.0 40.5 23.4
granite‑embedding‑278m‑multilingual (R1) 278M 86M 768 52.2 48.5 51.5 37.7 18.9
embeddinggemma‑300m 308M 106M 768 62.5 68.7 54.6 55.4 26.1
gte‑multilingual‑base 305M 113M 768 57.2 57.5 50.8 62.1 19.0
snowflake‑arctic‑embed‑m‑v2.0 305M 113M 768 54.8 55.2 58.4 55.4 23.3
multilingual‑e5‑large 560M 304M 1024 53.7 55.8 51.5 40.4 25.4
text‑embedding‑3‑small (OpenAI, API only) 1536 50.7 53.8 53.6 23.2
granite‑embedding‑97m‑multilingual‑r2 97M 28M 384 60.3 60.4 50.1 65.6 24.9
granite‑embedding‑311m‑multilingual‑r2 311M 110M 768 65.2 (#2) 63.8 (#3) 52.6 (#5) 71.7 (#1) 28.0 (#2)

주요 관찰점

  • 97M R2 모델은 300M 파라미터 규모의 multilingual‑e5‑basegte‑multilingual‑base를 평균 및 대부분 개별 벤치마크에서 앞섭니다(크기 약 3배 작음).
  • paraphrase‑multilingual‑MiniLM‑L12‑v2는 36.6점으로 97M R2 모델보다 23.7점 낮으며, 파라미터도 비슷하지만 차원도 동일(384)입니다.
  • LongEmbed에서 가장 큰 R1‑to‑R2 향상이 나타났습니다: 97M 모델 +31.3점, 311M 모델 +34.0점, 이는 32K 컨텍스트 윈도우의 효과를 보여줍니다.
  • 코드 검색도 크게 개선되었습니다: 97M 모델 +19.7점, 311M 모델 +15.3점.
  • 전체 경쟁 환경에서는 harrier‑oss‑v1‑270m이 MTEB 다국어 검색(66.4)과 RaR‑b(32.9)에서 최고이며, jina‑embeddings‑v5‑text‑nano가 코드(71.2)와 영어 검색(58.8)에서 최고입니다. 311M Granite 모델은 평균(56.3)에서 경쟁력 있고 LongEmbed(71.7)에서는 1위를 차지하며, 인코딩 처리량도 jina‑embeddings‑v5‑text‑nano보다 훨씬 높습니다.

Speed and Throughput

인코딩 속도는 NVIDIA H100 GPU 하나에서 512‑토큰 청크 기준으로 측정했습니다. 97M 모델은 초당 2,500문서 이상을 인코딩해 multilingual‑e5‑small과 비슷한 처리량을 보이며 품질은 크게 앞섭니다. 311M 모델은 초당 약 1,800문서를 처리하면서 jina‑embeddings‑v5‑text‑nano보다 높은 검색 품질(65.2 vs 63.3)과 5.5배 빠른 인코딩 속도를 제공합니다(속도 수치는 최신 트랜스포머 코드 기준이며, 이전 4.57 버전 대비 회귀가 있음을 참고). harrier‑oss‑v1‑270m은 경쟁 모델 중 속도와 점수의 최적 조합을 보여줍니다.

Matryoshka Embeddings (311M)

311M 모델은 Matryoshka Representation Learning을 지원해 768 차원 전체 임베딩을 512, 384, 256, 128 차원으로 손쉽게 잘라도 품질 손실이 최소화됩니다. 저장 용량·메모리·유사도 계산 비용이 중요한 경우에 유용합니다—예를 들어 256 차원 임베딩은 768 차원 대비 1/3 저장 공간을 차지하고, 코사인 유사도 계산 비용도 비례해 감소합니다.

차원 축소에 따른 품질 손실은 매우 작습니다. 768→256 차원(스토리지·연산 3배 감소)에서는 MTEB 다국어 검색이 0.5점(65.2→64.7) 떨어지고 코드 검색도 0.5점(63.9→63.4) 감소합니다. 128 차원(6배 감소)에서도 여전히 MTEB 다국어 검색 63.7점, 코드 62.3점을 기록해 전체 성능의 97% 이상을 유지합니다. 실제로 이는 인덱스 크기와 검색 지연 시간을 크게 줄이면서 결과 품질에 미치는 영향을 최소화한다는 의미입니다(위 그림의 결과는 영어·다국어 검색은 컨텍스트 길이 1024, 코드는 8192로 평가되었습니다).

비교를 위해 311M 모델을 384 차원으로 잘라도(97M 모델과 동일 차원) 모든 세 벤치마크에서 97M 모델을 앞섭니다. 384 차원 임베딩이 필요하고 311M 모델의 인코딩 비용을 감당할 수 있다면 Matryoshka 축소가 더 강력한 선택입니다.

예시 사용법 (sentence‑transformers):

from sentence_transformers import SentenceTransformer

model = SentenceTransformer("ibm-granite/granite-embedding-311m-multilingual-r2")

# 전체 768‑차원 임베딩
full = model.encode(["example text"])
print(full.shape)  # (1, 768)

# 384 차원으로 축소
small = model.encode(["example text"], truncate_dim=384)
print(small.shape)  # (1, 384)

97M 모델은 Matryoshka를 지원하지 않으며, 384 차원이 이미 가장 컴팩트한 형태입니다.

Deployment Options

두 모델 모두 프로덕션 사용을 위한 다양한 배포 경로를 제공합니다. 핵심 라이브러리는 다음과 같이 설치합니다:

pip install sentence-transformers

Sentence Transformers (대부분 사용자에게 권장):

from sentence_transformers import SentenceTransformer, util

model = SentenceTransformer("ibm-granite/granite-embedding-97m-multilingual-r2")
docs = ["富士山は日本最高峰の独立峰です。", "Mount Fuji is Japan's highest peak."]
query = embeddings.embed_query("What is Japan's tallest mountain?")
# LangChain이 Embeddings 객체를 받는 모든 곳에 Drop‑in 교체 가능

LangChain (pip install langchain‑huggingface):

from langchain_huggingface import HuggingFaceEmbeddings

embeddings = HuggingFaceEmbeddings(
    model_name="ibm-granite/granite-embedding-97m-multilingual-r2"
)

docs = embeddings.embed_documents([
    "富士山は日本最高峰の独立峰です。",
    "Mount Fuji is Japan's highest peak."
])  # LangChain이 Embeddings 객체를 받는 모든 곳에 Drop‑in 교체 가능

LlamaIndex (pip install llama-index-embeddings-huggingface):

from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core import Settings

embed_model = HuggingFaceEmbedding(
    model_name="ibm-granite/granite-embedding-97m-multilingual-r2"
)
Settings.embed_model = embed_model  # 모든 인덱스·파이프라인에 전역 적용

Haystack (pip install sentence-transformers haystack-ai):

from haystack.components.embedders import (
    SentenceTransformersDocumentEmbedder,
    SentenceTransformersTextEmbedder,
)
from haystack.components.retrievers.in_memory import InMemoryEmbeddingRetriever
from haystack.dataclasses import Document
from haystack.document_stores.in_memory import InMemoryDocumentStore

doc_embedder = SentenceTransformersDocumentEmbedder(
    model="ibm-granite/granite-embedding-97m-multilingual-r2"
)
query_embedder = SentenceTransformersTextEmbedder(
    model="ibm-granite/granite-embedding-97m-multilingual-r2"
)
doc_embedder.warm_up()
query_embedder.warm_up()

# 문서 임베딩 및 인덱싱
document_store = InMemoryDocumentStore()
result_docs = doc_embedder.run(documents=[
    Document(content="富士山は日本最高峰の独立峰です。"),
    Document(content="Mount Fuji is Japan's highest peak."),
    Document(content="Achy Breaky Heart is a country song written by Don Von Tress."),
    Document(content="Berlin ist die Hauptstadt und ein Land der Bundesrepublik Deutschland.")
])
document_store.write_documents(result_docs["documents"])

# 쿼리 임베딩 및 검색
result_query = query_embedder.run(text="What is Japan's tallest mountain?")
retriever = InMemoryEmbeddingRetriever(document_store=document_store)
results = retriever.run(query_embedding=result_query["embedding"], top_k=2)
for doc in results["documents"]:
    print(f"{doc.score:.3f}  {doc.content}")

Milvus (pip install pymilvus sentence-transformers):

from pymilvus import MilvusClient
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("ibm-granite/granite-embedding-97m-multilingual-r2")

# 로컬 영속성을 위해 "./milvus.db" 사용하거나 프로덕션에서는 서버 URI 지정
client = MilvusClient(":memory:")
client.create_collection(collection_name="multilingual_docs", dimension=384)

docs = [
    "富士山は日本最高峰の独立峰です。",
    "Mount Fuji is Japan's highest peak.",
    "Achy Breaky Heart is a country song written by Don Von Tress.",
    "Berlin ist die Hauptstadt und ein Land der Bundesrepublik Deutschland."
]
embeddings = model.encode(docs).tolist()
client.insert(
    collection_name="multilingual_docs",
    data=[{"id": i, "vector": emb, "text": doc} for i, (emb, doc) in enumerate(zip(embeddings, docs))],
)

query_emb = model.encode(["What is Japan's tallest mountain?"]).tolist()
results = client.search(
    collection_name="multilingual_docs",
    data=query_emb,
    limit=2,
    output_fields=["text"],
)
for hit in results[0]:
    print(f"{hit['distance']:.3f}  {hit['entity']['text']}")

두 모델 모두 최적화된 CPU/가속기 추론을 위한 사전 변환된 ONNX 및 OpenVINO 가중치를 제공하며, vLLM(vllm serve ... --task embed)을 통한 임베딩 엔드포인트로도 동작하고, llama.cpp를 이용해 GGUF 형식으로 변환해 Ollama에서 사용할 수 있습니다. 자세한 배포 예시는 모델 카드에서 확인하세요.

For Framework Integrators

임베딩 프레임워크·벡터 스토어·RAG 파이프라인 라이브러리를 유지보수하고 기본 모델로 이들을 평가하고 있다면 다음을 참고하세요:

  • 라이선스: Apache 2.0, MS‑MARCO 사용 없음.
  • Drop‑in 동작: 별도 프롬프트 접두사 필요 없이 all-MiniLM-L6-v2와 동일하게 API 수준에서 동작합니다. 기존 .encode() 호출은 그대로 사용 가능합니다.
  • 차원: 97M 모델은 384‑차원, 311M 모델은 768‑차원 출력으로 가장 일반적인 기본값과 일치합니다. 인덱스 마이그레이션이 필요 없습니다.
  • 모델 크기: 97M 모델 가중치는 195 MB(safetensors)로 paraphrase-multilingual-MiniLM-L12-v2(471 MB)의 절반 이하이며, 양자화된 ONNX 가중치는 98 MB로 all-MiniLM-L6-v2(91 MB)와 비슷하면서 200개 이상 언어를 지원합니다.
  • CPU 친화적: 최적화된 CPU 추론을 위한 ONNX·OpenVINO 가중치를 제공하므로 GPU 없이도 튜토리얼을 시작할 수 있습니다.
  • 다국어 기본 지원: 현재 기본이 영어 전용이라면, 한 줄 교체만으로 200개 이상 언어를 지원하도록 할 수 있어 코드 수정 없이 커뮤니티 전체에 혜택을 제공합니다.
  • 안정적인 식별자: Hugging Face에서 ibm-granite/granite-embedding-97m-multilingual-r2 로 제공되며 IBM이 Granite 모델 패밀리로 관리합니다.

이 모델들을 프로젝트 기본값으로 채택하고 싶다면 ibm-granite/granite-embedding-models에서 이슈를 열어 주세요.

Which Model Should You Use?

두 다국어 모델은 Granite Embedding R2 패밀리의 일부이며, 추가로 두 개의 고성능 영어 전용 모델(granite-embedding-english-r2 149M 파라미터, granite-embedding-small-english-r2 47M 파라미터)도 포함합니다. 데이터가 주로 영어라면 영어 모델이 더 작은 footprint에 높은 검색 품질을 제공합니다.

필요에 따라 선택 모델
최고 다국어 검색 품질 granite‑embedding‑311m‑multilingual‑r2
유연한 임베딩 차원(스토리지·속도 절충) granite‑embedding‑311m‑multilingual‑r2 (Matryoshka)
최대 처리량·엣지 배포·저지연 granite‑embedding‑97m‑multilingual‑r2
다수 언어쌍에 대한 최고의 교차 언어 전이 granite‑embedding‑311m‑multilingual‑r2
주로 영어 데이터 granite‑embedding‑english‑r2 또는 granite‑embedding‑small‑english‑r2

Try The Models

두 모델 모두 IBM Granite Embedding 컬렉션 아래 Hugging Face에서 바로 사용할 수 있습니다:

  • granite-embedding-311m-multilingual-r2
  • granite-embedding-97m-multilingual-r2

CPU 환경에서 작은 모델을 인터랙티브하게 체험하려면 Granite Embedding 데모 를 방문하거나, Google Colab에서 전체 예제 노트북을 실행해 보세요:

Image 9: Open In Colab

전체 학습 방법론·언어별 평가·프루닝 실험을 담은 상세 기술 보고서는 여기서 확인할 수 있습니다: Granite Multilingual Embedding R2 report. 질문·피드백·이슈는 ibm-granite/granite-embedding-models 에서 받아주세요.

프레임워크 유지보수자: 프로젝트 기본값으로 채택하고 싶다면 ibm-granite/granite-embedding-models 에 이슈를 열어 주세요—통합·테스트·라이선스·배포 관련 지원을 제공해 드립니다.

한 번 사용해 보고, 임베딩이 마음에 든다면 Hugging Face에서 ❤️ 버튼을 눌러 주세요. 우리 모델도 감정을 가지고 있으며, +1은 밤새 따뜻하게 해줍니다.

Sources