IBM 开源新一代多语言嵌入模型,支持 32K 上下文和多语言检索。对构建检索增强生成(RAG)系统的开发者有实用价值。
多语言嵌入模型面临一个长期存在的张力:广泛的语言覆盖通常需要以更大的模型规模为代价,而小型模型往往无法覆盖足够多的语言。如果你在多种语言上工作——对多语言语料库执行检索增强生成、进行跨语言搜索、在国际团队中进行代码检索——你很可能需要在速度足够快的模型和检索质量足够好的模型之间做出选择。
Granite Embedding Multilingual R2 的发布大幅缩小了这个差距。我们发布了两个新的多语言嵌入模型:
granite-embedding-311m-multilingual-r2 — 一个拥有 311M 参数的完整版本模型,具有 768 维嵌入、Matryoshka 维度支持和一流的多语言检索质量。
granite-embedding-97m-multilingual-r2 — 一个拥有 97M 参数的紧凑型模型,具有 384 维嵌入,在其规模范围内提供出色的检索质量。
两个模型都支持 200+ 种语言,对 52 种语言和编程代码提供增强的检索质量,可处理长达 32,768 个 token 的上下文长度(相比 R1 前身提升 64 倍),并在 Apache 2.0 许可证下发布。它们可以开箱即用地与 sentence-transformers 和 transformers 配合工作,不需要特定任务的说明,并且可以作为 LangChain、LlamaIndex、Haystack 和 Milvus 中的替代品——仅需修改一行模型名称。对于目前仅支持英文默认值的框架,这一行改动可以为你的整个社区用户提供 200+ 种语言的支持——无需更改 API、无需添加新依赖、用户端无需任何代码改动。两个模型都提供 ONNX 和 OpenVINO 权重,用于 CPU 优化推理。
底层编码器在 200+ 种语言的文本上进行了预训练,为其中任何一种语言生成通用嵌入。以下 52 种语言获得了明确的检索对和跨语言训练,以获得更高质量的检索:
阿尔巴尼亚语(sq)、阿拉伯语(ar)、阿塞拜疆语(az)、孟加拉语(bn)、保加利亚语(bg)、加泰罗尼亚语(ca)、中文(zh)、克罗地亚语(hr)、捷克语(cs)、丹麦语(da)、荷兰语(nl)、英语(en)、爱沙尼亚语(et)、芬兰语(fi)、法语(fr)、格鲁吉亚语(ka)、德语(de)、希腊语(el)、希伯来语(he)、印地语(hi)、匈牙利语(hu)、冰岛语(is)、印尼语(id)、意大利语(it)、日语(ja)、哈萨克语(kk)、高棉语(km)、韩语(ko)、拉脱维亚语(lv)、立陶宛语(lt)、马来语(ms)、马拉地语(mr)、挪威语(no)、波斯语(fa)、波兰语(pl)、葡萄牙语(pt)、罗马尼亚语(ro)、俄语(ru)、塞尔维亚语(sr)、斯洛伐克语(sk)、斯洛文尼亚语(sl)、西班牙语(es)、斯瓦希里语(sw)、瑞典语(sv)、他加禄语(tl)、泰卢固语(te)、泰语(th)、土耳其语(tr)、乌克兰语(uk)、乌尔都语(ur)、乌兹别克语(uz)、越南语(vi)。
此外,这些模型在编程代码(Python、Go、Java、JavaScript、PHP、Ruby、SQL、C、C++)上进行了训练,并支持跨语言代码检索。
两个嵌入模型都是在 IBM 策划的数据集、公开可用的数据以及内部生成或合成数据的混合上训练的。训练中使用的来自公共网络的数据经过 IBM 开发的质量、去重和治理流程的选择和过滤,旨在降低下游商业用途中的风险。我们有意避免使用 MS-MARCO 训练数据集和具有明确非商业许可限制的数据集。这些模型使用 GneissWeb 进行预训练,GneissWeb 是从公开可用的网络内容衍生的 IBM 策划数据集,并使用 IBM 的数据准备和治理工具进行处理——还包括其他 IBM 策划和公开可用的数据源。数据集接受 IBM 治理审查,以评估许可考虑、所有权信号和个人数据风险。这些流程旨在促进负责任的使用和企业部署。
本次发布的亮点是 granite-embedding-97m-multilingual-r2。在拥有 97 百万参数的情况下,它在 18 种语言的多语言 MTEB 检索基准上获得 60.3 分——这是我们在开源 100M 参数以下的多语言嵌入模型中找到的最高检索得分。同一规模类别中的次优模型 multilingual-e5-small 在相同基准上得分为 50.9——在这个成熟的基准上相差 +9.4 分。
尽管规模仅为完整版本 311M 模型的约三分之一,它在多语言、代码和长文档基准上保留了大部分检索质量——相比其直接前身,MTEB 多语言检索上获得 +12.2 分的提升,这得益于新的架构、更好的训练数据和新颖的剪枝方法(下面有更多介绍)。完整版本 granite-embedding-311m-multilingual-r2 在相同基准上得分 65.2,相比 R1 前身获得 +13.0 分的提升。
Granite Embedding Multilingual R1 模型是在 XLM-RoBERTa 编码器上构建的,具有 512 token 的上下文窗口。R2 一代采用了全新设计:
ModernBERT 是一个最近推出的编码器架构,它用过去五年 transformer 研究中的技术重新审视最初的 BERT 设计。这个转变带来了几个实际的好处:交替的注意力长度减少了对长序列的计算(显著提高了长序列的吞吐量)、旋转位置嵌入允许 32K 上下文窗口而无需旧架构存在的位置插值 hack、Flash Attention 2.0 支持加快了现代 GPU 上的编码速度。
新的多语言分词器值得特别指出。我们没有继续使用 XLM-RoBERTa 的 250K token 词汇表,而是采用了具有强大多语言和代码覆盖的现有分词器。311M 模型使用 Gemma 3 分词器(262K token);97M 模型从 GPT-OSS 分词器开始,并将其剪枝到紧凑的 180K token 词汇表,保持了广泛的多语言覆盖,同时大幅减少了嵌入表的参数占用。分词器的效率比人们通常认为的要重要得多——32K token 的窗口听起来令人印象深刻,直到你的分词器耗尽了其中一半来编码一段泰语文本。
311M 模型是一个 22 层的 ModernBERT 编码器,具有 262K token 多语言词汇表,通过多阶段流水线进行训练:
知识蒸馏:模型同时从多个教师模型学习。这些教师是 Granite 3.3 Instruct 和 Mistral v0.2 Instruct 解码器模型,进一步针对文本嵌入进行了微调,将检索特定知识转移到 311M 编码器架构中。
对比微调:在多语言检索对上进行标准的对比训练——将跨 52 种语言和代码的查询与相关和困难否定段落匹配——增强了模型区分相关和不相关结果的能力。
模型合并:训练后,我们合并来自不同训练阶段和配置的检查点。这将针对不同目标优化的模型的优点(例如多语言广度与英文深度)组合成单一权重集,无需额外的训练计算。
Matryoshka 表示学习:使用 Matryoshka 目标训练模型,使其 768 维嵌入可以被截断到 512、384、256 或 128 维,质量损失最小(详见下方 Matryoshka 嵌入部分)。
结果是一个在 MTEB 多语言检索上得分 65.2、整体平均得分 56.3 的模型——相比 R1 前身平均提升 +14.5 分。
97M 模型通过词汇表选择和知识蒸馏的结合进行训练:
词汇表选择:262K token 词汇表被缩减到专门设计的 180K token 词汇表,保持了广泛的多语言覆盖,同时大幅减少了嵌入表的参数占用。
知识蒸馏:随后使用来自多个教师模型(包括基于 Granite 4.1 8B 和 Mistral Instruct 解码器的教师)的知识蒸馏和对比训练对剪枝后的模型进行微调,以改进检索质量。
这种方法从多个强大的教师那里转移检索特定的知识,同时在不牺牲语言覆盖的前提下减少模型参数。结果是一个高效的紧凑型模型——在 MTEB 多语言检索上得分 60.3,相比完整版本模型的 65.2,同时模型规模约为其三分之一。
跨主基准套件的性能(按模型规模排序)。分数为每个基准内各任务的平均值(分数越高越好):
有几点值得注意:
97M R2 模型在平均指标和大多数单个基准上都击败了 multilingual-e5-base 和 gte-multilingual-base(约 300M 参数模型),尽管规模约小三倍。
paraphrase-multilingual-MiniLM-L12-v2——一个被广泛使用的框架默认模型——得分为 36.6,比 97M R2 模型整整低了 23.7 分;后者的规模还略小一些(参数量为 97M,而前者为 110M),输出维度同为 384。
LongEmbed 是从 R1 到 R2 提升最大的基准:97M 模型提升了 31.3 分,311M 模型提升了 34.0 分。这正是 32K 上下文窗口带来的直接收益——R1 的 512 token 限制意味着,你的法律合同只能根据第一页来评判。许多实际的多语言工作负载都涉及长文档(法律合同、技术手册、研究论文、多页报告),而 R1 根本无法完整读取这些内容。
代码检索也得到显著改善:相比 R1,97M 模型提升了 19.7 分,311M 模型提升了 15.3 分,这得益于新的代码训练集、更大的上下文窗口以及更好的训练方法。
在更广泛的竞争格局中,harrier-oss-v1-270m 在 MTEB Multilingual Retrieval(66.4)和 RaR-b(32.9)上领先,而 jina-embeddings-v5-text-nano 则在 Code(71.2)和 English Retrieval(58.8)上领先。311M Granite 模型的平均得分具有竞争力(56.3),并在 LongEmbed(71.7)上领先,同时编码吞吐量显著高于 jina-embeddings-v5-text-nano(参见下方速度表)。
编码速度对于生产工作负载至关重要,尤其是在需要为数百万份文档建立索引,或需要低延迟查询编码时。我们使用 512 token 的文本块,在单张 NVIDIA H100 GPU 上测量了延迟和吞吐量:
97M 模型每秒可编码超过 2,500 份文档——吞吐量与 multilingual-e5-small 相当——同时提供显著更高的检索质量。311M 模型的速度约为每秒 1,800 份文档,其检索质量优于 jina-embeddings-v5-text-nano(65.2 对 63.3),编码速度则是后者的 5.5 倍以上(注意:速度数据使用最新的 transformer 代码计算;与之前的 4.57 版本相比,该代码出现了速度回退——Jina 和 Granite 模型均受影响——详情请参阅我们的技术报告)。在这里列出的竞品中,harrier-oss-v1-270m 提供了速度与检索得分的最佳组合。
311M 模型支持 Matryoshka Representation Learning,可以将嵌入从完整的 768 维截断为 512、384、256 或 128 维,同时使质量平缓下降。当存储、内存或相似度计算成本成为关注重点时,这项能力非常有用——256 维嵌入的存储空间仅为 768 维嵌入的三分之一,余弦相似度的计算成本也会成比例降低。
以下是不同嵌入维度下检索质量的保持情况:
维度缩减造成的质量损失非常小。从 768 维降至 256 维——存储和相似度计算成本降低至三分之一——MTEB Multilingual Retrieval 得分仅下降 0.5 分(65.2 → 64.7),Code Retrieval 得分也仅下降 0.5 分(63.9 → 63.4)。即使降至 128 维(缩减至六分之一),该模型在 MTEB Multilingual Retrieval 上仍能取得 63.7 分,在 Code 上仍能取得 62.3 分——保留了完整维度下超过 97% 的性能。在实践中,这意味着你可以显著减小索引大小并降低搜索延迟,同时只对结果质量产生极小影响。(注意,上图中的 English Retrieval 和 Multilingual Retrieval 结果使用 1024 的上下文长度进行评估,Code 则使用 8192 的上下文长度。)
作为对比,将 311M 模型截断至 384 维(与 97M 模型的原生输出维度相同)后,它在全部三个基准测试中仍然优于 97M 模型。如果你需要 384 维嵌入,并且能够承担 311M 模型的编码成本,那么 Matryoshka 截断是更强的选择。
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("ibm-granite/granite-embedding-311m-multilingual-r2")
# Full 768-dimensional embeddings
full = model.encode(["example text"])
print(full.shape) # (1, 768)
# Truncated to 384 dimensions
small = model.encode(["example text"], truncate_dim=384)
print(small.shape) # (1, 384)
97M 模型不支持 Matryoshka——384 维本身已经足够紧凑。
这是 MTEB Retrieval 中跨语言任务的平均表现。Belebele 衡量涵盖 122 种语言的跨语言段落匹配能力;MLQA 衡量涵盖 7 种语言的抽取式跨语言问答检索能力。
311M R2 模型相比其 R1 前代,在 Belebele 上提升了 4.3 分,在 MLQA 上提升了 4.1 分,表明更大规模的模型在这两个基准测试上都具备更好的跨语言迁移能力。
97M R2 模型在 Belebele 上的得分较低(52.9 对 55.1,下降 2.2 分),而在 MLQA 上则与其 R1 前代持平(60.5)。Belebele 上的差距是剪枝和词表缩减过程固有的权衡——R2 模型的训练优先考虑了范围更广、涵盖 18 种语言的 MTEB Multilingual Retrieval 数据集(相比 R1 提升 12.2 分)和长文档检索(提升 31.3 分),而更小的词表(180K 对 250K token)和更少的层数(12 层对 22 层)会影响范围较窄的跨语言迁移任务。如果你的主要用例是在大量语言对之间进行跨语言迁移,那么完整规模的 311M 模型是更好的选择。
两个模型都提供了多种面向生产环境的部署方式。安装核心库:
pip install sentence-transformers
Sentence Transformers(推荐大多数用户使用):
from sentence_transformers import SentenceTransformer, util
model = SentenceTransformer("ibm-granite/granite-embedding-97m-multilingual-r2")
queries = [
"What is the tallest mountain in Japan?", # English
"Wer hat das Lied Achy Breaky Heart geschrieben?", # German
"ドイツの首都はどこですか?", # Japanese
]
passages = [
"富士山は、静岡県と山梨県にまたがる活火山で、標高3776.12 mで日本最高峰の独立峰である。", # Japanese
"Achy Breaky Heart is a country song written by Don Von Tress.", # English
"Berlin ist die Hauptstadt und ein Land der Bundesrepublik Deutschland.", # German
]
q_emb = model.encode(queries)
p_emb = model.encode(passages)
print(util.cos_sim(q_emb, p_emb))
# Each query scores highest against its matching passage — across languages
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.",
])
query = embeddings.embed_query("What is Japan's tallest mountain?")
# Drop-in replacement anywhere LangChain accepts an Embeddings object
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 # applies globally to any index or pipeline
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()
# Embed and index documents
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"])
# Embed query and retrieve
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}")
# 0.961 Mount Fuji is Japan's highest peak.
# 0.913 富士山は日本最高峰の独立峰です。
from pymilvus import MilvusClient
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("ibm-granite/granite-embedding-97m-multilingual-r2")
# Use "./milvus.db" for local persistence or a server URI for production
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']}")
这两个模型还提供了预转换的 ONNX 和 OpenVINO 权重,可用于优化 CPU/加速器上的推理;也可以通过 vLLM 作为嵌入端点运行(`vllm serve ... --task embed`),还可使用 llama.cpp 转换为供 Ollama 使用的 GGUF 格式。完整的部署示例请参阅模型卡片。
## 面向框架集成者
如果你维护着嵌入框架、向量存储或 RAG 流水线库,并正在评估是否将这些模型作为默认模型,以下是你需要了解的信息:
**许可证:** Apache 2.0,训练时未使用 MS-MARCO
**即插即用行为:** 无需特定于任务的指令前缀——在 API 层面的行为与 all-MiniLM-L6-v2 相同。现有调用 `.encode()` 的代码无需修改即可使用。
**维度:** 输出维度分别为 384(97M)和 768(311M),与最常见的现有默认设置一致。无需迁移索引。
**模型大小:** 97M 模型的权重大小为 195 MB(safetensors),不到最常用多语言默认模型 paraphrase-multilingual-MiniLM-L12-v2(471 MB)的一半。量化后的 ONNX 权重仅为 98 MB,与 all-MiniLM-L6-v2(91 MB)相当,同时支持 200 多种语言。
**CPU 友好:** 提供 ONNX 和 OpenVINO 权重,针对 CPU 推理进行了优化。入门教程无需依赖 GPU。
**默认支持多语言:** 如果你当前的默认模型仅支持英语,只需替换一行代码,就能让社区中的每位用户获得对 200 多种语言的支持——无需修改他们的代码。
**稳定标识符:** Hugging Face 上的 `ibm-granite/granite-embedding-97m-multilingual-r2`,由 IBM 在 Granite 模型家族下维护。
如需讨论在你的项目中采用这些模型作为默认模型,请在 `ibm-granite/granite-embedding-models` 中提交 issue。
## 应该使用哪个模型?
这两个多语言模型属于更广泛的 Granite Embedding R2 系列,该系列还包含两个性能出色、专注于英语的模型:granite-embedding-english-r2(149M 参数)和 granite-embedding-small-english-r2(47M 参数)。如果你的数据主要是英语,英语模型占用空间更小,并且在英语基准测试上能提供更高的检索质量,因为它们无需将模型容量分配给 200 多种语言。
这两个模型现已在 Hugging Face 的 IBM Granite Embedding 合集中提供:
granite-embedding-311m-multilingual-r2
granite-embedding-97m-multilingual-r2
你可以通过 Hugging Face Spaces 上的 Granite Embedding 演示,以交互方式在 CPU 上试用这些小模型,也可以在 Google Colab 中运行完整的示例 notebook:
你可以阅读我们详尽的技术报告 Granite Multilingual Embedding R2 report,其中介绍了完整的训练方法、逐语言评估以及剪枝消融实验。如有问题、反馈或发现 issue,请访问 GitHub 上的 `ibm-granite/granite-embedding-models`。
框架维护者:如果你希望在项目中采用这些模型作为默认模型,请在 `ibm-granite/granite-embedding-models` 中提交 issue——我们很乐意协助集成、测试,并解答有关许可证或部署的任何问题。
欢迎试用;如果这些嵌入让你感到愉悦,请在 Hugging Face 上猛戳那个 ❤️ 按钮。我们的模型也有感情,每一个 +1 都能让它们在夜里保持温暖。
本文提及的模型 5
本文提及的数据集 2
本文提及的 Spaces 1
该作者的更多文章
Granite 4.1 LLM:它们是如何构建的
Granite 4.0 3B Vision:面向企业文档的紧凑型多模态智能
· 注册或登录后发表评论
本文提及的模型 5
本文提及的数据集 2
本文提及的 Spaces 1