FlagEmbedding 推理 Embedder API 全解析:BaseEmbedder、M3Embedder、BaseLLMEmbedder 与 ICLLLMEmbedder 的架构、参数与实战
2026/9/15 9:57:16 网站建设 项目流程

FlagEmbedding 推理 Embedder API 全解析:BaseEmbedder、M3Embedder、BaseLLMEmbedder 与 ICLLLMEmbedder 的架构、参数与实战

【免费下载链接】FlagEmbeddingRetrieval and Retrieval-augmented LLMs项目地址: https://gitcode.com/GitHub_Trending/fl/FlagEmbedding

本篇技术指南聚焦 FlagEmbedding 的推理侧(inference)Embedder API,系统讲解仓库 API 文档(docs/source/API/inference/embedder/embedder.rst)所覆盖的四类嵌入模型封装类:面向编码器架构的BaseEmbedder、面向 BGE-M3 多模态检索的M3Embedder、面向解码器 LLM 的BaseLLMEmbedder,以及支持上下文学习(In-Context Learning)的ICLLLMEmbedder。读完本文,你将掌握每个类的构造参数含义与默认值、encode_queries/encode_corpus/encode等核心方法的调用约定、底层 pooling 与多设备推理的实现原理,并能直接照搬到自己的检索与 RAG 项目中。

一、文档结构与四类 Embedder 的总览

embedder.rst本身是一个 Sphinx toctree 索引页,它挂载了四个子 API 页面,分别对应四个推理类:

子文档对应类适用模型架构代表模型
encoder_only/BaseEmbedder.rstFlagEmbedding.inference.embedder.encoder_only.base.BaseEmbedder编码器(Encoder-only,BERT 类)BGE v1/v1.5 系列、e5、gte 等
encoder_only/M3Embedder.rstFlagEmbedding.inference.embedder.encoder_only.m3.M3Embedder编码器(多向量/稀疏/稠密混合)BGE-M3
decoder_only/BaseLLMEmbedder.rstFlagEmbedding.inference.embedder.decoder_only.base.BaseLLMEmbedder解码器(Decoder-only,LLM)bge-reasoner、Qwen3-Embedding、SFR-Embedding 等
decoder_only/ICLLLMEmbedder.rstFlagEmbedding.inference.embedder.decoder_only.icl.ICLLLMEmbedder解码器(上下文学习)BGE-EN-ICL

在代码层面,这四个类分别定义在 FlagEmbedding/inference/embedder/encoder_only/base.py、m3.py、decoder_only/base.py 与 decoder_only/icl.py,并统一从FlagEmbedding/inference/embedder/__init__.py导出为FlagModelBGEM3FlagModelFlagLLMModelFlagICLModel等用户友好的别名。四者都继承自抽象基类AbsEmbedder(见 FlagEmbedding/abc/inference/AbsEmbedder.py),因此共享一套"查询/语料/通用编码"接口约定,差异集中在 pooling 方式与多模态输出上。

二、共同架构:抽象基类 AbsEmbedder 与统一编码流程

所有 Embedder 的骨架由AbsEmbedder定义(FlagEmbedding/abc/inference/AbsEmbedder.py),其 docstring 明确说明:扩展该类并实现encode_queriesencode_corpusencode三个方法即可自定义 Embedder

2.1 统一的三入口设计

  • encode_queries(queries, ...):编码查询。内部以self.query_max_length为默认长度上限,并自动拼接检索指令query_instruction_for_retrieval(见 AbsEmbedder.py 的encode_queries实现)。
  • encode_corpus(corpus, ...):编码语料/文档。以self.passage_max_length为默认长度上限,并支持通过 kwargs 传入passage_instruction_for_retrieval/passage_instruction_format为语料附加独立的指令(默认"{}{}")。
  • encode(sentences, ...):通用编码入口,最终依据设备数量决定走单设备路径encode_single_device还是多进程池路径encode_multi_process

三者均支持输入单个字符串(str)或字符串列表(List[str]),返回值可以是numpy.ndarraytorch.Tensor,由convert_to_numpy控制(默认True,返回 numpy 数组)。

2.2 指令拼接机制

get_detailed_instruct(instruction_format, instruction, sentence)(AbsEmbedder.py 第 157-170 行)按模板把指令与句子组合:

def get_detailed_instruct(instruction_format: str, instruction: str, sentence: str): if "\\n" in instruction_format: instruction_format = instruction_format.replace("\\n", "\n") return instruction_format.format(instruction, sentence)

例如query_instruction_format="Instruct: {}\nQuery: {}"会把"检索指令 + 查询文本"拼成Instruct: <指令>\nQuery: <查询>。注意源码会对字面量\n做一次显式替换,因此既支持在 Python 字符串中写真实换行,也支持写\n转义序列。

2.3 设备自动探测与多进程并行

get_target_devices(devices)(AbsEmbedder.py 第 110-154 行)是一套完整的设备解析逻辑:

  • devices=None时按优先级自动探测:CUDA(全部可用卡cuda:0...N)→ NPU(npu:0...N)→ MUSA(musa:0...N)→ MPS(Apple Silicon)→ 兜底cpu
  • 传入str"cuda:0"int0、字符串列表或整数列表均可;
  • 当检测到多张卡且输入为批量列表时,encode会通过start_multi_process_pool启动每卡一个进程的 worker 池,配合encode_multi_process分块分发、_concatenate_results_from_multi_process合并结果;对象析构时由__del__调用stop_self_pool清理进程与显存。

2.4 通用后处理钩子

  • _convert_to_numpy:在 bf16 推理且非 CPU 设备上,先将bfloat16张量升为float32再转 numpy(NumPy 不支持 bfloat16);
  • _truncate_embeddings:配合 Matryoshka 表示学习模型,当truncate_dim不为None时截取前truncate_dim维,例如把 4096 维向量截到 1024 维使用。

三、BaseEmbedder:编码器模型的通用推理封装

3.1 构造参数速查

BaseEmbedder(encoder_only/base.py)用于加载任意 HuggingFace 编码器模型(AutoModel),核心参数与默认值如下:

参数默认值说明
model_name_or_path必填本地模型路径,或 HuggingFace Hub 上的模型名
normalize_embeddingsTrue是否对输出向量做 L2 归一化
use_fp16True半精度推理加速(轻微精度损失)
use_bf16False使用 bfloat16;优先于 fp16
query_instruction_for_retrievalNone检索任务查询指令文本
query_instruction_format"{}{}"指令拼接模板
devicesNone推理设备,见上文设备探测逻辑
pooling_method"cls"池化方式:clsmean
trust_remote_codeFalse是否信任远端模型自定义代码
cache_dirNone模型缓存目录
batch_size256推理批大小
query_max_length512查询最大 token 长度
passage_max_length512语料最大 token 长度
convert_to_numpyTrue输出 numpy 数组而非张量
truncate_dimNoneMatryoshka 截断维度

构造时使用AutoTokenizer.from_pretrainedAutoModel.from_pretrained加载模型,并按get_model_torch_dtype(bf16 > fp16 > fp32)设置精度。

3.2 池化方法实现

pooling(last_hidden_state, attention_mask)(第 284-308 行)支持两种方法:

  • cls:直接取last_hidden_state[:, 0],即[CLS]token 的隐状态;
  • mean:按 attention mask 对非 padding 位置的隐状态做加权平均:s / d,其中s是掩码加权和、d是有效 token 数;
  • 其他值抛出NotImplementedError

3.3 单设备编码流水线(encode_single_device)

encode_single_device(第 174-282 行)是理解整个库推理性能设计的关键,流程如下:

  1. 单条字符串输入会先包成列表并在返回时还原(input_was_string标记);
  2. 预分词:先不带 padding 分词,记录每条输入的真实长度;
  3. 按长度降序排序np.argsort),将长度相近的样本分到同一 batch,最大限度减少 padding 浪费;
  4. batch size 自适应:用"试跑一个 batch"的方式探测显存,捕获RuntimeErrortorch.cuda.OutOfMemoryError时把batch_size乘以3/4缩小重试;
  5. 正式推理:forward 取last_hidden_statepooling_truncate_embeddings→ 按需 L2 归一化 → 按需转 numpy;
  6. length_sorted_idx的逆序还原样本顺序后返回。

这套"预排序 + 自适应 batch"的设计在长尾长度的真实语料上能显著提升吞吐,是仓库在大量推理场景中推荐的默认实现。

四、M3Embedder:BGE-M3 的稠密 + 稀疏 + 多向量混合检索

M3Embedder(encoder_only/m3.py)专为 BGE-M3 设计,在BaseEmbedder基础上新增了**稀疏词权重(lexical weights)ColBERT 多向量(colbert vecs)**两种输出,覆盖稠密检索、稀疏检索、多向量重排三类能力。

4.1 独有构造参数

BaseEmbedder的通用参数外,还包含:

参数默认值说明
colbert_dim-1ColBERT 线性投影维度,-1表示使用模型 hidden_size
return_denseTrue是否返回稠密向量
return_sparseFalse是否返回稀疏词权重字典
return_colbert_vecsFalse是否返回 ColBERT 多向量

模型加载走专门的EncoderOnlyEmbedderM3ModelForInference包装类(来自FlagEmbedding.finetune.embedder.encoder_only.m3),内部负责把 tokenizer、池化与归一化装配在一起。

4.2 encode_* 方法的字典返回值

encode_queries/encode_corpus/encode的返回类型统一为字典:

Dict[Literal["dense_vecs", "lexical_weights", "colbert_vecs"], Union[np.ndarray, List[Dict[str, float]], List[np.ndarray]]]
  • dense_vecs:归一化后的稠密向量(np.ndarray);
  • lexical_weights:每个样本一个{token_id: weight}字典(token_id 为字符串形式),已剔除 cls/eos/pad/unk 等特殊 token,且同 token 取最大权重(见_process_token_weights);
  • colbert_vecs:去掉 padding 与[CLS]后的逐 token 向量列表。

三个方法的默认长度/开关回退规则各不相同:encode_queriesquery_max_lengthencode_corpusencodepassage_max_length;若调用时未显式传return_dense/sparse/colbert_vecs,则回退到构造时的对应开关。

4.3 词级与向量级辅助方法

  • convert_id_to_token(lexical_weights):把{token_id: weight}字典转换为{token: weight},方便直接阅读或对接 BM25 类检索器;
  • compute_lexical_matching_score(lw1, lw2):按共享 token 的权重乘积求和计算稀疏匹配分数,支持"单对单返回 float、批量对返回np.ndarray"两种形态;
  • colbert_score(q_reps, p_reps):用torch.einsum('in,jn->ij')计算查询-文档 token 相似度矩阵,取每行最大值(MaxSim)后求均值,得到 ColBERT 风格的交互分数。

4.4 混合打分:compute_score 系列

compute_score(sentence_pairs, batch_size, max_query_length, max_passage_length, weights_for_different_modes)(第 488-538 行)直接对(query, passage)对打分,返回五档分数:

Dict[Literal["colbert", "sparse", "dense", "sparse+dense", "colbert+sparse+dense"], List[float]]
  • 单卡时直接走compute_score_single_device
  • 多卡时启动M3Embedder._compute_score_multi_process_worker进程池,用compute_score_multi_process分块并汇总;
  • weights_for_different_modes是稠密、稀疏、ColBERT 三者的权重列表(长度必须为 3),默认[1.0, 1.0, 1.0],即等权融合;sparse+densecolbert+sparse+dense分别按权重做加权平均。这在 hybrid 检索评测(如仓库research/C_MTEBevaluation下的多个 benchmark)中是直接可复用的打分 API。

五、BaseLLMEmbedder:解码器 LLM 的嵌入封装

5.1 与编码器版本的关键差异

BaseLLMEmbedder(decoder_only/base.py)面向 LLM 类嵌入模型,与BaseEmbedder的差异集中在三点:

  1. 默认指令模板不同query_instruction_format默认值从"{}{}"变为"Instruct: {}\nQuery: {}",适配 E5、SFR、bge-reasoner 等指令式 LLM 嵌入模型;
  2. 池化方式强制为 last_token:构造时校验kwargs.get("pooling_method", "last_token"),一旦传入非last_token立即抛ValueError("Pooling method must be 'last_token' for LLM-based models.")
  3. 池化函数不同:使用模块级函数last_token_pool(第 12-29 行)——先判断是否为左 padding(attention_mask[:, -1].sum() == batch 行数),是则取最后一个位置last_hidden_states[:, -1],否则按每行有效 token 数定位最后一个真实 token 并取对应隐状态,从而兼容padding=True的 batch 推理。

5.2 编码流水线

encode_single_deviceBaseEmbedder的结构一致(预分词 → 长度排序 → 自适应 batch → last_token 池化 → 归一化 → 输出),并在参数注释中提示:对于 bge-multilingual-gemma2 等模型可在 kwargs 中传pad_to_multiple_of=8。由于 LLM 序列较长,实际使用中建议配合batch_sizemax_length的调优来控制显存占用。

六、ICLLLMEmbedder:带示例注入的上下文学习嵌入

ICLLLMEmbedder(decoder_only/icl.py)面向 BGE-EN-ICL 这类通过 few-shot 示例增强检索的模型:把"指令 + 示例 + 查询"组装成模型特有的模板再编码,使模型针对当前任务自适应。

6.1 独有参数

参数默认值说明
query_instruction_format"<instruct>{}\n<query>{}"查询指令模板(构造时自动把\n字面量转为真实换行)
suffix'\n<response>'查询后追加的后缀 token 序列
examples_for_taskNonefew-shot 示例列表,元素为含instruct/query/response键的字典
examples_instruction_format"<instruct>{}\n<query>{}\n<response>{}"单个示例的组装模板

6.2 示例管理与前缀组装

  • set_examples(examples_for_task=None)(第 133-165 行):把示例按examples_instruction_format展开后以'\n\n'连接,末尾再补'\n\n'作为self.prefix;未提供任何示例时prefix为空串;
  • get_detailed_example(instruction_format, instruction, query, response)(第 167-182 行):静态方法,负责单条示例的模板拼接;
  • 构造完成后立即调用self.set_examples(),把构造参数中的examples_for_task固化为前缀。

6.3 带前缀的查询编码

encode_queries_single_device(第 322-457 行)是 ICL 模式的核心,处理链条为:

  1. query_instruction_format拼接检索指令与查询文本;
  2. self.prefixself.suffix分词后,重新计算有效最大长度:new_max_length = (len(prefix_ids) + len(suffix_ids) + max_length + 8) // 8 * 8 + 8(8 对齐,兼顾部分模型对序列长度的对齐要求);
  3. 预分词阶段把每条文本重写为prefix + 截断后的查询 + suffix
  4. 之后的长度排序、自适应 batch、last_token 池化、归一化与BaseLLMEmbedder一致。

此外,ICL 类为查询单独维护了一个query_pool(与语料编码的pool分离),并在encode_corpus前调用stop_self_query_pool释放查询侧的多进程资源,避免两套进程池互相干扰。

七、从 API 到自动装配:模型映射与统一入口

尽管embedder.rst只列出四个类,但仓库在 FlagEmbedding/inference/embedder/model_mapping.py 中为它们建立了完整的模型名 → 类 + 池化方式 + 指令模板映射表:

  • EmbedderModelClass枚举了encoder-only-baseencoder-only-m3decoder-only-basedecoder-only-icldecoder-only-pseudo_moe五种类型;
  • BGE_MAPPINGbge-m3BGEM3FlagModel(cls)bge-en-iclFlagICLModel(last_token, "<instruct>{}\n<query>{}")bge-large-en-v1.5等 →FlagModel(cls)bge-reasoner-embed-qwen3-8b-0923FlagLLMModel("Instruct: {}\nQuery: {}")
  • 此外还有QWEN3_EMBEDDING_MAPPINGE5_MAPPINGGTE_MAPPINGSFR_MAPPINGLINQ_MAPPINGBCE_MAPPING,最终合并为AUTO_EMBEDDER_MAPPING,由support_model_list()列出全部支持模型名。

这意味着在实际项目中,多数情况下无需手动实例化上述四个类,直接使用统一入口FlagAutoModel(FlagEmbedding/inference/auto_embedder.py)即可按模型名自动匹配正确的类、池化方式与指令模板;需要精细控制时再回到这四个类手工配置。

八、典型使用示例与工程建议

以下示例演示如何直接使用四类 API(均为仓库真实支持的调用形态,仓库另附多份可运行的完整示例脚本,见 examples/inference/embedder/encoder_only 与 examples/inference/embedder/decoder_only):

from FlagEmbedding import FlagModel, BGEM3FlagModel, FlagLLMModel, FlagICLModel # 1) 编码器模型(BGE v1.5 系列等),cls 池化 model = FlagModel("bge-large-en-v1.5", query_instruction_for_retrieval="Represent this sentence for searching relevant passages:", use_fp16=True) q_emb = model.encode_queries(["how to use FlagEmbedding?"]) c_emb = model.encode_corpus(["FlagEmbedding is a library for retrieval.", "..."]) # 2) BGE-M3 混合输出:稠密 + 稀疏 + 多向量 m3 = BGEM3FlagModel("bge-m3", use_fp16=True, return_dense=True, return_sparse=True, return_colbert_vecs=True) out = m3.encode_queries(["query text"]) dense, lexical, colbert = out["dense_vecs"], out["lexical_weights"], out["colbert_vecs"] # 词 id 转回 token、并直接算稀疏匹配分 lexical_tokens = m3.convert_id_to_token(lexical) scores = m3.compute_lexical_matching_score(lexical, lexical) # 或直接对 (query, passage) 混合打分 hybrid = m3.compute_score([("q1", "p1")], weights_for_different_modes=[1., 1., 1.]) # 3) LLM 嵌入模型(last_token 池化,指令模板自动拼接) llm = FlagLLMModel("bge-reasoner-embed-qwen3-8b-0923", query_max_length=8192, batch_size=16) q_emb = llm.encode_queries(["query text"]) # 4) ICL 上下文学习:注入 few-shot 示例 icl = FlagICLModel("bge-en-icl", examples_for_task=[ {"instruct": "Given a web search query, retrieve relevant passages...", "query": "example query", "response": "example passage"} ]) q_emb = icl.encode_queries(["real query"])

工程使用建议:

  • 显存优先:LLM 类(BaseLLMEmbedder/ICLLLMEmbedder)建议调小batch_size并配合use_bf16=True;超大语料可先encode_corpus批量建索引,再encode_queries在线检索;
  • 多卡扩展:传入devices=["cuda:0", "cuda:1"]即可自动走多进程池并行,注意每卡一个进程是推荐配置;
  • 检索评估M3Embedder.compute_score可直接用于 hybrid 检索的分数融合验证,仓库的 evaluation 与 research/C_MTEB 目录提供了 MSMARCO、BEIR、MIRACL、MLDR 等基准的完整评测配套;
  • 回归验证:仓库测试目录中的 tests/test_infer_embedder_basic.py 覆盖了 Embedder 的基础推理路径,可作为自定义封装后的自检参考。

九、小结

FlagEmbedding 的推理 Embedder API 用"一个抽象基类 + 四个具体类"覆盖了当前主流的两代嵌入模型范式:BaseEmbedderM3Embedder服务于编码器架构(单向量检索与稠密+稀疏+多向量混合检索),BaseLLMEmbedderICLLLMEmbedder服务于解码器 LLM 架构(指令式嵌入与上下文学习嵌入)。理解它们的参数默认值、三入口编码约定、池化差异与多设备调度机制,是高效使用 BGE 系列模型构建 RAG 与检索系统的基础,也是阅读仓库评测与微调代码(FlagEmbedding.abc.inferenceFlagEmbedding.finetune.embedder)的切入点。

【免费下载链接】FlagEmbeddingRetrieval and Retrieval-augmented LLMs项目地址: https://gitcode.com/GitHub_Trending/fl/FlagEmbedding

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询