LlamaIndex - 03 Embedding Model

LlamaIndex Embedding Model 完全指南

在 LlamaIndex 中,Embedding 模型是将文本转换为向量表示的核心组件,直接影响检索质量。本文将系统地介绍如何使用、配置和评估 Embedding 模型,并特别加入针对中文场景的详细推荐。


目录

  1. 概念与核心作用
  2. 安装与基础配置
  3. 各主要来源 Embedding 模型详解
  4. 中文 Embedding 模型详解与推荐
  5. 高级配置参数
  6. 模型选择与性能评测
  7. 完整代码示例
  8. 常见问题与最佳实践

一、概念与核心作用

Embedding 模型将文本作为输入,输出一个浮点数列表(向量),用于捕捉文本的语义信息。这些向量使得语义相似的文本在向量空间中彼此靠近,从而支持搜索、RAG 等应用。

在 LlamaIndex 中,Embedding 模型有两个关键使用场景:

  1. 索引阶段:将文档切分后的 Node 转换为向量,存入向量数据库
  2. 查询阶段:将用户查询转换为向量,用于与索引中的向量进行相似度计算

默认情况下,LlamaIndex 使用 OpenAI 的 text-embedding-ada-002 模型,相似度计算采用余弦相似度。


二、安装与基础配置

2.1 安装对应包

不同 Embedding 提供商需要安装不同的包:

# OpenAI
pip install llama-index-embeddings-openai

# Hugging Face 本地模型
pip install llama-index-embeddings-huggingface

# Ollama 本地模型
pip install llama-index-embeddings-ollama

# LangChain 集成
pip install llama-index-embeddings-langchain

# ONNX 加速
pip install llama-index-embeddings-huggingface-optimum transformers optimum[exporters]

# Jina AI
pip install llama-index-embeddings-jinaai

# BCEmbedding(中文推荐)
pip install BCEmbedding

2.2 全局配置方式

最常用的配置方式是通过 Settings 对象全局设置 Embedding 模型:

from llama_index.core import Settings
from llama_index.embeddings.openai import OpenAIEmbedding

# 全局设置
Settings.embed_model = OpenAIEmbedding()

# 之后构建的 index 和 query engine 会自动使用该模型

也可以在创建 Index 时单独指定:

index = VectorStoreIndex.from_documents(
    documents, 
    embed_model=embed_model
)

三、各主要来源 Embedding 模型详解

3.1 OpenAI Embedding

OpenAI 的 Embedding 模型在多项评测中表现优异,特别是与 reranker 配合使用时。

from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core import Settings

# 基础配置
Settings.embed_model = OpenAIEmbedding()

# 自定义配置
embed_model = OpenAIEmbedding(
    model="text-embedding-3-small",  # 或 "text-embedding-3-large", "text-embedding-ada-002"
    embed_batch_size=10,             # 批处理大小,默认 10
    api_key="your-api-key",          # 可选,也可通过环境变量设置
)

根据 LlamaIndex 官方评测,OpenAI Embedding 与 CohereRerank 搭配时,Hit Rate 可达 0.926966,MRR 达 0.86573

3.2 Hugging Face 本地模型

使用本地模型可以避免 API 调用成本,适合需要离线运行或数据隐私敏感的场景。

基础用法:

from llama_index.embeddings.huggingface import HuggingFaceEmbedding

# 使用轻量级模型(速度快)
embed_model = HuggingFaceEmbedding(
    model_name="BAAI/bge-small-en-v1.5"
)

# 使用高性能模型
embed_model = HuggingFaceEmbedding(
    model_name="BAAI/bge-large-en-v1.5"
)

带缓存的配置:

embed_model = HuggingFaceEmbedding(
    cache_folder="./models",          # 模型缓存目录
    model_name="BAAI/bge-large-en-v1.5"
)
Settings.embed_model = embed_model

常用 Hugging Face Embedding 模型:

模型特点维度
BAAI/bge-small-en-v1.5轻量快速,适合开发测试384
BAAI/bge-base-en-v1.5平衡性能与速度768
BAAI/bge-large-en-v1.5高性能,适合生产环境1024
sentence-transformers/all-mpnet-base-v2通用性较好768

3.3 Ollama 本地部署

Ollama 允许在本地运行 LLM 和 Embedding 模型,提供隐私保护和离线能力。

前置步骤:

# 1. 安装 Ollama(访问 ollama.ai)
# 2. 启动 Ollama 服务(默认 localhost:11434)
# 3. 拉取 embedding 模型
ollama pull nomic-embed-text
# 或
ollama pull embeddinggemma

代码使用:

from llama_index.embeddings.ollama import OllamaEmbedding
from llama_index.core import Settings

embed_model = OllamaEmbedding(
    model_name="nomic-embed-text",           # 必需:Ollama 模型名称
    base_url="http://localhost:11434",       # Ollama 服务地址
    embed_batch_size=10,                     # 批处理大小
    keep_alive="5m",                         # 模型在内存中的保持时间
    query_instruction=None,                  # 查询前置指令
    text_instruction=None,                   # 文本前置指令
)

Settings.embed_model = embed_model

带指令的配置(可提升检索质量):

embed_model = OllamaEmbedding(
    model_name="nomic-embed-text",
    query_instruction="Represent the question for retrieving supporting documents:",
    text_instruction="Represent the document for retrieval:",
)

异步使用:

import asyncio

async def generate_embeddings():
    embedding = await embed_model.aget_text_embedding("Hello, world!")
    embeddings = await embed_model.aget_text_embeddings(["text1", "text2"])
    
asyncio.run(generate_embeddings())

Ollama 可用的 Embedding 模型:

  • nomic-embed-text:通用型
  • embeddinggemma:Google Gemma 系列
  • mxbai-embed-large:大型模型,质量更高

3.4 LangChain 集成

如需使用 LangChain 中的 Embedding 模型:

from langchain.embeddings.huggingface import HuggingFaceBgeEmbeddings
from llama_index.core import Settings
from llama_index.embeddings.langchain import LangchainEmbedding

embed_model = LangchainEmbedding(
    HuggingFaceBgeEmbeddings(model_name="BAAI/bge-base-en")
)
Settings.embed_model = embed_model

3.5 ONNX 加速模型

使用 ONNX 可显著提升推理速度:

from llama_index.embeddings.huggingface_optimum import OptimumEmbedding

# 首次运行:创建并保存 ONNX 模型
OptimumEmbedding.create_and_save_optimum_model(
    "BAAI/bge-small-en-v1.5", "./bge_onnx"
)

# 后续使用
Settings.embed_model = OptimumEmbedding(folder_name="./bge_onnx")

3.6 自定义 Embedding 模型

可以通过继承 BaseEmbedding 类实现自定义模型:

from typing import List
from llama_index.core.embeddings import BaseEmbedding

class CustomEmbedding(BaseEmbedding):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        # 初始化你的模型
        
    def _get_query_embedding(self, query: str) -> List[float]:
        # 生成查询向量
        pass
        
    def _get_text_embedding(self, text: str) -> List[float]:
        # 生成文本向量
        pass
        
    def _get_text_embeddings(self, texts: List[str]) -> List[List[float]]:
        # 批量生成(可选,用于优化性能)
        pass

四、中文 Embedding 模型详解与推荐

4.1 中文模型选型总览

根据不同的使用场景,下表汇总了当前主流的中文 Embedding 模型:

模型名称开发者核心特点向量维度适用场景
BGE-M3智源研究院支持100+语言,输入8192 tokens,密集/稀疏/多向量混合检索1024跨语言长文档检索、多语言知识库
bce-embedding-base_v1网易有道中英双语优化,RAG场景SOTA表现,无需指令前缀768双语RAG、语义搜索
Qwen3-VL-2B阿里巴巴多模态支持,跨语言检索能力强,开源2048图文混合检索、跨语言场景
SEA-LION-E5-Embedding-600MAISG东南亚+中英文优化,CMTEB得分60.79未明确东南亚语言+中文场景
xiaobu-embedding-v2国内团队专为中文语义深度优化未明确通用中文检索、电商搜索
stella-mrl-large-zh-v3.5国内团队大规模中文数据处理能力强1792中文复杂语义、新闻舆情分析
M3E-Turbo国内团队中文轻量模型,支持本地私有化部署未明确本地知识库、专业领域检索
jina-embeddings-v2-base-zhJina AI中英双语,8192上下文768中文长文档检索

4.2 重点推荐模型详解

🔥 网易有道 BCEmbedding (bce-embedding-base_v1)

网易有道推出的双语 Embedding 模型,在生产环境(QAnything)中得到验证。

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

# 配置 BCEmbedding
embed_model = HuggingFaceEmbedding(
    model_name="maidalun1020/bce-embedding-base_v1",
    max_length=512,
    embed_batch_size=32,
    device="cuda"  # 或 "cpu"
)

Settings.embed_model = embed_model

核心优势

  • 无需指令:不像很多模型需要添加 "Represent this sentence: " 等前缀,开箱即用
  • RAG 优化:专门针对检索增强生成场景调优
  • 双语 SOTA:在 LlamaIndex 官方 RAG 评测中,bce-embedding-base_v1 + bce-reranker-base_v1 组合达到 SOTA
  • 生产验证:已被网易有道多个产品(速读、翻译)采用

配合 Reranker 使用(强烈推荐):

from BCEmbedding.tools.llama_index import BCERerank

# 配置 Reranker
reranker = BCERerank(
    model="maidalun1020/bce-reranker-base_v1",
    top_n=5,
    device="cuda"
)

# 在 Query Engine 中使用
query_engine = index.as_query_engine(node_postprocessors=[reranker])

🔥 BGE-M3(智源研究院)

智源发布的 M3(Multi-Function, Multi-Lingual, Multi-Granularity)Embedding 模型,是处理多语言和长文档的首选。

from llama_index.embeddings.huggingface import HuggingFaceEmbedding

embed_model = HuggingFaceEmbedding(
    model_name="BAAI/bge-m3",
    trust_remote_code=True,  # BGE-M3 需要
)

核心优势

  • 超长上下文:8192 tokens,可处理整篇文章或长文档
  • 100+ 语言支持:中文、英文及众多小语种
  • 混合检索:支持密集向量、稀疏向量(类似 BM25)、多向量三种检索方式
  • CMTEB 高分:在中文 MTEB 评测中表现优异

适用场景:跨语言知识库、多语言 RAG 系统、处理超长文档的企业应用。


🔥 Qwen3-VL-2B(阿里巴巴)

阿里云 Qwen 团队最新推出的多模态 Embedding 模型,在跨语言检索评测中表现优异。

# 需要从 Qwen 官方仓库加载
from transformers import AutoModel
from llama_index.core.embeddings import BaseEmbedding

# 注意:该模型可能需要自定义封装
# 详见 Qwen 官方文档

核心优势

  • 跨语言能力:中英跨语言检索得分 0.988,仅次于 Gemini
  • 多模态支持:同时支持文本和图像输入
  • 开源免费:2B 参数,可本地部署

Jina AI v2/v3 系列

Jina AI 提供了专门的中文版本 jina-embeddings-v2-base-zh,支持 8192 上下文。

from llama_index.embeddings.jinaai import JinaEmbedding

# 使用中文专用版本
embed_model = JinaEmbedding(
    model="jina-embeddings-v2-base-zh",  # 中文专用
    api_key="your-jina-api-key",
)

# 或使用最新的 v3 多语言模型(推荐)
embed_model = JinaEmbedding(
    model="jina-embeddings-v3",
    task="retrieval.passage",  # 可指定任务类型
)

Jina v3 任务适配器

  • retrieval.query:查询编码
  • retrieval.passage:文档编码(索引时使用)
  • classification:文本分类
  • text-matching:相似度匹配

中文轻量模型:M3E-Turbo 与 xiaobu-embedding-v2

对于资源受限或纯中文场景,可考虑以下国产轻量模型:

# M3E-Turbo(本地部署优先)
embed_model = HuggingFaceEmbedding(
    model_name="moka-ai/m3e-turbo",
    # 或 "m3e-base", "m3e-small"
)

# xiaobu-embedding-v2(通用中文场景)
embed_model = HuggingFaceEmbedding(
    model_name="xiaobu/xiaobu-embedding-v2",
)
模型适用场景特点
M3E-Turbo本地私有部署、法律/医疗专业检索轻量、易部署
xiaobu-embedding-v2电商搜索、客服知识库中文语义理解精度高

4.3 跨语言检索性能对比

根据 2026 年最新的 CCKM 评测基准,各模型在中英跨语言检索任务中的表现如下:

模型跨语言得分 (R@1)中文成语理解 (Hard Tier)
Gemini Embedding 20.9971.000
Qwen3-VL-2B0.9880.969
Jina Embeddings v40.9850.969
Voyage Multimodal 3.50.9820.938
OpenAI text-embedding-3-large0.9670.906
BGE-M30.9400.844
nomic-embed-text0.1540.031

关键结论:在需要处理中文成语、俗语等复杂语义的场景下,BGE-M3、Qwen3-VL-2B 等专门优化的模型明显优于通用英文模型。

4.4 CMTEB 中文评测基准表现

SEA-LION 项目发布的最新评测数据(CMTEB 中文基准):

模型参数量CMTEB 得分
Qwen-8B-Embedding8B75.00
Qwen-0.6B-Embedding0.6B67.45
SEA-LION-E5-Embedding-600M0.6B60.79
BGE-M30.6B60.47
text-embedding-3-small (OpenAI)处理失败

4.5 中文场景决策树

根据业务需求,按以下步骤选择最合适的模型:

第一步:确定语言需求
├── 纯中文 + 资源受限/本地部署 → M3E-Turbo
├── 纯中文 + 云端部署/高精度 → xiaobu-embedding-v2 或 stella-mrl-large-zh
├── 中英双语 + RAG 场景 → bce-embedding-base_v1(首选)
├── 多语言(>10种)/长文档 → BGE-M3
├── 多语言 + 高精度(愿意付费) → Gemini Embedding 2
└── 需要图像+文本混合检索 → Qwen3-VL-2B

第二步:是否配合 Reranker?
├── 是 → bce-reranker-base_v1(与 BCEmbedding 最佳搭配)
│         或 BGE-reranker-large
└── 否 → 考虑提升 top_k 值补偿召回

4.6 中文场景特别注意事项

  1. 文本分块优化:中文建议使用 SpacyTextSplitter + zh_core_web_sm 模型,比默认的 SentenceSplitter 更适合中文:
from langchain.text_splitter import SpacyTextSplitter
from llama_index.core.node_parser import LangchainNodeParser

parser = LangchainNodeParser(
    SpacyTextSplitter(
        pipeline="zh_core_web_sm",
        chunk_size=512,
        chunk_overlap=50,
    )
)
  1. 中文标题增强:可参考 QAnything 的实现,对文档标题进行标记,提升检索完整性
  2. 模型大小选择

    • 轻量级(< 0.5B):BGE-small-zh、M3E-Turbo
    • 中量级(0.5B-1B):bce-embedding-base_v1、BGE-M3、jina-embedding-v2-zh
    • 重量级(> 2B):Qwen3-VL-2B、stella-large-zh
  3. 获取最新评测数据:建议关注 MTEB 中文榜单 和 LlamaIndex 官方博客的持续更新。

五、高级配置参数

5.1 批处理大小(Batch Size)

默认批处理大小为 10,可根据需求调整:

# 增大批处理可以提高吞吐量,但可能触发速率限制
embed_model = OpenAIEmbedding(embed_batch_size=42)

5.2 分块策略配合

Embedding 的质量与文本分块策略密切相关:

from llama_index.core.node_parser import SentenceSplitter

text_splitter = SentenceSplitter(
    chunk_size=500,      # 每块大小
    chunk_overlap=50,    # 块之间重叠
)

index = VectorStoreIndex.from_documents(
    documents, 
    transformations=[text_splitter]
)

5.3 混合使用不同模型

可以在索引和查询阶段使用不同的 Embedding 模型,或使用不同模型进行检索和 LLM 生成:

from llama_index.core import ServiceContext
from llama_index.llms.openai import OpenAI

# 索引阶段使用本地 embedding
embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-large-en-v1.5")

# 查询阶段使用 OpenAI LLM
llm = OpenAI(model="gpt-3.5-turbo")

service_context = ServiceContext.from_defaults(
    embed_model=embed_model,
    llm=llm
)

index = VectorStoreIndex.from_documents(documents, service_context=service_context)

六、模型选择与性能评测

6.1 评测指标

LlamaIndex 使用两个主要指标评估检索性能:

  • Hit Rate(命中率):正确答案出现在 top-k 检索结果中的查询比例
  • MRR(Mean Reciprocal Rank,平均倒数排名):第一个相关文档排名倒数的平均值

6.2 各模型性能对比

根据 LlamaIndex 官方评测(特定数据集):

Embedding 模型搭配 RerankerHit RateMRR
JinaAI-Basebge-reranker-large0.9382020.868539
JinaAI-BaseCohereRerank0.9325840.873689
OpenAICohereRerank0.9269660.865730
OpenAIbge-reranker-large0.9101120.855805
VoyageCohereRerank0.9157300.851217
Google-PaLMCohereRerank0.9101120.855712
Cohere v3.0CohereRerank0.8876400.836049
bge-largeCohereRerank0.8764040.822753

6.3 关键结论

  1. Reranker 的重要性:几乎所有 Embedding 模型在搭配 Reranker 后都有显著提升,CohereRerankbge-reranker-large 表现最为突出
  2. 最佳组合

    • OpenAI/JinaAI-Base + CohereRerank/bge-reranker-large 是目前表现最好的组合
  3. 本地模型的选择

    • 追求质量:BAAI/bge-large-en-v1.5
    • 平衡速度和效果:BAAI/bge-base-en-v1.5
    • 轻量快速:BAAI/bge-small-en-v1.5
  4. 基础模型是关键:即使是最好的 Reranker,也无法弥补基础 Embedding 模型质量不足的问题

七、完整代码示例

7.1 基础 RAG Pipeline

from llama_index.core import (
    SimpleDirectoryReader,
    VectorStoreIndex,
    Settings,
)
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core.node_parser import SentenceSplitter

# 1. 配置 Embedding 模型
Settings.embed_model = HuggingFaceEmbedding(
    model_name="BAAI/bge-large-en-v1.5",
    cache_folder="./models"
)

# 2. 配置文本分块
Settings.text_splitter = SentenceSplitter(
    chunk_size=512,
    chunk_overlap=50,
)

# 3. 加载文档并建立索引
documents = SimpleDirectoryReader("./data").load_data()
index = VectorStoreIndex.from_documents(
    documents,
    show_progress=True,
)

# 4. 持久化
index.storage_context.persist(persist_dir="./storage")

# 5. 查询
query_engine = index.as_query_engine()
response = query_engine.query("你的问题")
print(response)

7.2 带 Reranker 的完整 Pipeline

from llama_index.core import VectorStoreIndex, Settings
from llama_index.core.retrievers import VectorIndexRetriever
from llama_index.core.query_engine import RetrieverQueryEngine
from llama_index.core.postprocessor import SentenceTransformerRerank

# 配置 Embedding
Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-large-en-v1.5")

# 构建索引
index = VectorStoreIndex.from_documents(documents)

# 配置 Retriever(获取更多候选)
retriever = VectorIndexRetriever(
    index=index,
    similarity_top_k=10,  # 获取 top-10
)

# 配置 Reranker(重排序取 top-5)
reranker = SentenceTransformerRerank(
    model="BAAI/bge-reranker-large",
    top_n=5,
)

# 构建 Query Engine
query_engine = RetrieverQueryEngine.from_args(
    retriever=retriever,
    node_postprocessors=[reranker],
)

response = query_engine.query("你的问题")

7.3 使用 Ollama 本地模型

from llama_index.embeddings.ollama import OllamaEmbedding
from llama_index.llms.ollama import Ollama
from llama_index.core import Settings

# 设置 Embedding 模型
Settings.embed_model = OllamaEmbedding(
    model_name="nomic-embed-text",
    base_url="http://localhost:11434",
)

# 设置 LLM(也可用 Ollama)
Settings.llm = Ollama(
    model="llama3.1",
    base_url="http://localhost:11434",
)

# 正常使用
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()

7.4 中文 RAG 完整示例

from llama_index.core import (
    SimpleDirectoryReader,
    VectorStoreIndex,
    Settings,
)
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.core.node_parser import SentenceSplitter
from BCEmbedding.tools.llama_index import BCERerank

# 1. 配置中文优化的 Embedding 模型
Settings.embed_model = HuggingFaceEmbedding(
    model_name="maidalun1020/bce-embedding-base_v1",
    device="cuda",
    embed_batch_size=32,
)

# 2. 配置文本分块(中文建议 512-1024)
Settings.text_splitter = SentenceSplitter(
    chunk_size=512,
    chunk_overlap=50,
)

# 3. 加载中文文档
documents = SimpleDirectoryReader("./chinese_docs").load_data()

# 4. 建立索引
index = VectorStoreIndex.from_documents(
    documents,
    show_progress=True,
)

# 5. 配置 Reranker(可选,但强烈推荐)
reranker = BCERerank(
    model="maidalun1020/bce-reranker-base_v1",
    top_n=3,
    device="cuda",
)

# 6. 构建 Query Engine
query_engine = index.as_query_engine(
    similarity_top_k=10,  # 先召回更多,让 reranker 精排
    node_postprocessors=[reranker] if reranker else [],
)

# 7. 中文查询测试
response = query_engine.query("《长安的荔枝》的主角是谁?")
print(response)

八、常见问题与最佳实践

8.1 如何选择合适的模型?

  1. 考虑约束条件

    • 有预算、需要最佳效果 → OpenAI + CohereRerank
    • 数据隐私要求高 → 本地模型(BGE 系列)+ 本地 Reranker
    • 需要离线运行 → Ollama + nomic-embed-text
    • 中文场景 → bce-embedding-base_v1 + bce-reranker-base_v1
  2. 小规模测试:使用 LlamaIndex 的 RetrieverEvaluator 在你自己的数据上测试

8.2 Embedding 维度不匹配?

确保查询和索引使用同一个 Embedding 模型。不同模型的向量维度不同,无法直接比较。

8.3 如何提升检索质量?

  1. 调整分块策略:根据文档类型调整 chunk_sizechunk_overlap
  2. 添加 Reranker:可显著提升 MRR,尤其对于长尾查询
  3. 使用指令型模型:如 Instructor、Nomic-embed-text 支持前置指令

8.4 性能优化建议

  • 使用批处理:get_text_embeddings() 比循环调用 get_text_embedding() 高效
  • 开启异步:使用 aget_text_embedding() 提升并发能力
  • ONNX 加速:对 Hugging Face 模型使用 Optimum 导出

8.5 中文场景特别建议

  1. 首选组合:对于中英双语 RAG 场景,强烈推荐 bce-embedding-base_v1 + bce-reranker-base_v1
  2. 长文档处理:使用 BGE-M3(8192 上下文)
  3. 预算有限:使用轻量模型 M3E-Turbo 或 xiaobu-embedding-v2
  4. 持续关注:定期查看 MTEB 中文榜单获取最新评测数据

参考资料

  1. LlamaIndex Ollama Embeddings Integration
  2. LlamaIndex Embeddings 官方文档
  3. LlamaIndex RAG 评测:选择最佳 Embedding 和 Reranker
  4. BCEmbedding 评测工具文档
  5. Stack Overflow 社区实践经验
  6. MTEB 中文榜单 (Hugging Face)
  7. 网易有道 QAnything 项目文档
  8. 智源研究院 BGE 系列模型文档